void *
AgentConsolidatorTest::create (void *args)
{
    TestArgs *test_args = (TestArgs *) args;
    AgentConsolidator *cons = test_args->cons;
    AgentConsolidatorHandle *handle;
    SubscriptionRequest request;
    SubscriptionRequest system_accepted_request;
    telemetry::Path *path;

    // Build a request
    path = request.add_path_list();
    path->set_path("firewall");
    path = request.add_path_list();
    path->set_path("port");

    // Add it to the consolidator
    id_idx_t subscription_id = test_args->id;
    handle = cons->addRequest(subscription_id, &request,
                              &system_accepted_request);

    // Sleep randomly between 0 to 4 seconds
    sleep(rand()%5);

    // Now remove it
    cons->removeRequest(handle);

    return NULL;
}
TEST_F(AgentConsolidatorTest, add) {
    AgentConsolidatorHandle *handle;
    SubscriptionRequest request;
    SubscriptionRequest system_accepted_request;
    telemetry::Path *path;

    // Build a request of valid paths
    path = request.add_path_list();
    path->set_path("firewall");
    path = request.add_path_list();
    path->set_path("port");

    // Add it to the consolidator
    handle = cons->addRequest(61, &request, &system_accepted_request);
    EXPECT_TRUE(handle != NULL);
    EXPECT_EQ(2, cons->getSystemRequestCount());
    EXPECT_EQ(1, cons->getAddCount());
    EXPECT_EQ(0, cons->getErrors());
    for (int i = 0; i < request.path_list_size(); i++) {
        EXPECT_STREQ(request.path_list(i).path().c_str(),
                     system_accepted_request.path_list(i).path().c_str());
    }

    // Simple check get call is good
    SubscriptionRequest *test_ptr;
    test_ptr = cons->getRequest(handle, false);
    EXPECT_TRUE(test_ptr != NULL);

    // Remove it now
    cons->removeRequest(handle);
    EXPECT_EQ(0, cons->getSystemRequestCount());
    EXPECT_EQ(1, cons->getRemCount());
    EXPECT_EQ(0, cons->getErrors());
}
/**
  * Trigger:    The dispatcher receives a SubscriptionRequest.
  * Expected:   The PublicationManager creates a PublisherRunnable and polls
  *             the MockCaller for the attribute.
  */
TEST_F(SubscriptionTest, receive_subscriptionRequestAndPollAttribute) {
    qRegisterMetaType<OnChangeWithKeepAliveSubscriptionQos>("OnChangeWithKeepAliveSubscriptionQos");
    qRegisterMetaType<SubscriptionRequest>("SubscriptionRequest");

    // Use a semaphore to count and wait on calls to the mockRequestCaller
    QSemaphore semaphore(0);
    EXPECT_CALL(*mockRequestCaller, getLocation(_, _))
            .WillRepeatedly(ReleaseSemaphore(&semaphore));

    QString attributeName = "Location";
    auto subscriptionQos = QSharedPointer<SubscriptionQos>(new OnChangeWithKeepAliveSubscriptionQos(
                80, // validity_ms
                100, // minInterval_ms
                200, // maxInterval_ms
                80 // alertInterval_ms
    ));
    QString subscriptionId = "SubscriptionID";
    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setAttributeName(attributeName);
    subscriptionRequest.setQos(subscriptionQos);

    JoynrMessage msg = messageFactory.createSubscriptionRequest(
                proxyParticipantId,
                providerParticipantId,
                qos,
                subscriptionRequest);

    dispatcher.addRequestCaller(providerParticipantId, mockRequestCaller);
    dispatcher.receive(msg, qos);

    // Wait for a call to be made to the mockRequestCaller
    ASSERT_TRUE(semaphore.tryAcquire(1,1000));
}
Exemple #4
0
/**
  * Trigger:    The dispatcher receives a SubscriptionRequest.
  * Expected:   The PublicationManager creates a PublisherRunnable and polls
  *             the MockCaller for the attribute.
  */
TEST_F(SubscriptionTest, receive_subscriptionRequestAndPollAttribute) {

    // Use a semaphore to count and wait on calls to the mockRequestCaller
    Semaphore semaphore(0);
    EXPECT_CALL(*mockRequestCaller, getLocation(_,_))
            .WillRepeatedly(
                DoAll(
                    Invoke(mockRequestCaller.get(), &MockTestRequestCaller::invokeLocationOnSuccessFct),
                    ReleaseSemaphore(&semaphore)));

    std::string attributeName = "Location";
    Variant subscriptionQos = Variant::make<OnChangeWithKeepAliveSubscriptionQos>(OnChangeWithKeepAliveSubscriptionQos(
                500, // validity_ms
                1000, // minInterval_ms
                2000, // maxInterval_ms
                1000 // alertInterval_ms
    ));
    std::string subscriptionId = "SubscriptionID";
    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setSubscribeToName(attributeName);
    subscriptionRequest.setQos(subscriptionQos);

    JoynrMessage msg = messageFactory.createSubscriptionRequest(
                proxyParticipantId,
                providerParticipantId,
                qos,
                subscriptionRequest);

    dispatcher.addRequestCaller(providerParticipantId, mockRequestCaller);
    dispatcher.receive(msg);

    // Wait for a call to be made to the mockRequestCaller
    ASSERT_TRUE(semaphore.waitFor(std::chrono::seconds(1)));
}
bool ControlPoint::subscribe(Service *service, long timeout) {
  if (service->isSubscribed() == true) {
    const char *sid = service->getSID();
    return subscribe(service, sid, timeout);
  }
  
  Device *rootDev = service->getRootDevice();
  if (rootDev == NULL)
    return false;
  
  lock();
  
  const char *ifAddress = rootDev->getInterfaceAddress();     
  SubscriptionRequest subReq;
  string callbackURLBuf;
  subReq.setSubscribeRequest(service, getEventSubCallbackURL(ifAddress, callbackURLBuf), timeout);
  if (Debug::isOn() == true)
    subReq.print();  
  SubscriptionResponse *subRes = subReq.post();
  if (Debug::isOn() == true)
    subRes->print();  
  bool ret = false;
  if (subRes->isSuccessful() == true) {
    string sidBuf;
    service->setSID(subRes->getSID(sidBuf));
    service->setTimeout(subRes->getTimeout());
    ret = true;
  }
  else
    service->clearSID();
  
  unlock();
  
  return ret;
}
/**
  * Trigger:    The dispatcher receives a Publication.
  * Expected:   The SubscriptionManager retrieves the correct SubscriptionCallback and the
  *             Interpreter executes it correctly
  */
TEST_F(SubscriptionTest, receive_publication ) {

    qRegisterMetaType<SubscriptionPublication>("SubscriptionPublication");

    // getType is used by the ReplyInterpreterFactory to create an interpreter for the reply
    // so this has to match with the type being passed to the dispatcher in the reply
    ON_CALL(*mockReplyCaller, getType()).WillByDefault(Return(QString("QtGpsLocation")));

    // Use a semaphore to count and wait on calls to the mockSubscriptionListener
    QSemaphore semaphore(0);
    EXPECT_CALL(*mockSubscriptionListener, onReceive(A<const types::QtGpsLocation&>()))
            .WillRepeatedly(ReleaseSemaphore(&semaphore));

    //register the subscription on the consumer side
    QString attributeName = "Location";
    auto subscriptionQos = QSharedPointer<QtSubscriptionQos>(new QtOnChangeWithKeepAliveSubscriptionQos(
                80, // validity_ms
                100, // minInterval_ms
                200, // maxInterval_ms
                80 // alertInterval_ms
    ));

    SubscriptionRequest subscriptionRequest;
    //construct a reply containing a QtGpsLocation
    SubscriptionPublication subscriptionPublication;
    subscriptionPublication.setSubscriptionId(subscriptionRequest.getSubscriptionId());
    QList<QVariant> response;
    response.append(QVariant::fromValue(types::QtGpsLocation::createQt(gpsLocation1)));
    subscriptionPublication.setResponse(response);

    QSharedPointer<SubscriptionCallback<types::QtGpsLocation>> subscriptionCallback(
            new SubscriptionCallback<types::QtGpsLocation>(mockSubscriptionListener));


    // subscriptionRequest is an out param
    subscriptionManager->registerSubscription(
                attributeName,
                subscriptionCallback,
                subscriptionQos,
                subscriptionRequest);
    // incoming publication from the provider
    JoynrMessage msg = messageFactory.createSubscriptionPublication(
                QString::fromStdString(providerParticipantId),
                QString::fromStdString(proxyParticipantId),
                qos,
                subscriptionPublication);

    dispatcher.receive(msg);

    // Assert that only one subscription message is received by the subscription listener
    ASSERT_TRUE(semaphore.tryAcquire(1, 1000));
    ASSERT_FALSE(semaphore.tryAcquire(1, 250));
}
/**
  * Precondition: A provider is registered and there is at least one subscription for it.
  * Trigger:    A subscription stop message is received
  * Expected:   The PublicationManager stops the publications for this provider
  */
TEST_F(SubscriptionTest, stopMessage_stopsPublications) {

    qRegisterMetaType<QtOnChangeWithKeepAliveSubscriptionQos>("QtOnChangeWithKeepAliveSubscriptionQos");
    qRegisterMetaType<SubscriptionRequest>("SubscriptionRequest");

    // Use a semaphore to count and wait on calls to the mockRequestCaller
    QSemaphore semaphore(0);
    EXPECT_CALL(*mockRequestCaller, getLocation(_))
            .WillRepeatedly(
                DoAll(
                    Invoke(mockRequestCaller.data(), &MockTestRequestCaller::invokeOnSuccessFct),
                    ReleaseSemaphore(&semaphore)));

    dispatcher.addRequestCaller(providerParticipantId, mockRequestCaller);
    QString attributeName = "Location";
    auto subscriptionQos = QSharedPointer<QtSubscriptionQos>(new QtOnChangeWithKeepAliveSubscriptionQos(
                1200, // validity_ms
                10, // minInterval_ms
                100, // maxInterval_ms
                1100 // alertInterval_ms
    ));
    QString subscriptionId = "SubscriptionID";
    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setSubscribeToName(attributeName);
    subscriptionRequest.setQos(subscriptionQos);

    JoynrMessage msg = messageFactory.createSubscriptionRequest(
                QString::fromStdString(proxyParticipantId),
                QString::fromStdString(providerParticipantId),
                qos,
                subscriptionRequest);
    // first received message with subscription request
    dispatcher.receive(msg);

    // wait for two requests from the subscription
    ASSERT_TRUE(semaphore.tryAcquire(2, 1000));

    SubscriptionStop subscriptionStop;
    subscriptionStop.setSubscriptionId(subscriptionRequest.getSubscriptionId());
    // receive a subscription stop message
    msg = messageFactory.createSubscriptionStop(
                QString::fromStdString(proxyParticipantId),
                QString::fromStdString(providerParticipantId),
                qos,
                subscriptionStop);
    dispatcher.receive(msg);

    // assert that less than 2 requests happen in the next 300 milliseconds
    ASSERT_FALSE(semaphore.tryAcquire(2, 300));
}
bool ControlPoint::unsubscribe(Service *service) {
  SubscriptionRequest subReq;
  subReq.setUnsubscribeRequest(service);
  if (Debug::isOn() == true)
    subReq.print();  
  SubscriptionResponse *subRes = subReq.post();
  if (Debug::isOn() == true)
    subRes->print();  
  if (subRes->isSuccessful() == true) {
    service->clearSID();
    return true;
  }
  return false;
}
Exemple #9
0
void *
Service::proc (void *p_args)
{
    ServiceContext       *contextp = (ServiceContext *) p_args;
    ServiceInterestList  *interests = contextp->_interests;
    Service *service = contextp->_service;
    
    // Create a reader
    SubscriptionRequest request;
    Path *path;
    path = request.add_path_list();
    path->set_path(service->getName());
    path->set_sample_frequency(5000);
    
    ClientContext context;
    std::multimap<grpc::string_ref, grpc::string_ref> server_metadata;
    std::multimap<grpc::string_ref, grpc::string_ref>::iterator metadata_itr;
    std::unique_ptr<ClientReader<OpenConfigData>> reader(service->stub_->telemetrySubscribe(&context, request));
    
    // Get the subscription ID from the response
    // Wait for the initial meta data to come back
    reader->WaitForInitialMetadata();
    server_metadata = context.GetServerInitialMetadata();
    metadata_itr = server_metadata.find("init-response");
    std::string tmp = metadata_itr->second.data();
    
    // Use Textformat Printer APIs to convert to right format
    google::protobuf::TextFormat::Parser parser;
    SubscriptionReply reply;
    SubscriptionResponse *response;
    parser.ParseFromString(tmp, &reply);
    response = reply.mutable_response();
    service->setSubscriptionId(response->subscription_id());
    
    // Create the read channel
    OpenConfigData kv;
    while (reader->Read(&kv)) {
        for (int i = 0; i < kv.kv_size(); i++) {
            const KeyValue &kv_data = kv.kv(i);
            ServiceCallbackKeyValue key_value(kv_data.key(), kv_data.str_value());
            for (ServiceInterestListIterator itr = interests->begin(); itr != interests->end(); itr++) {
                Element *element = (*itr)->_element;
                (*itr)->_cb(element, &key_value);
            }
        }
    }

    // We are done.
    return NULL;
}
Exemple #10
0
/**
  * Trigger:    The dispatcher receives an enum Publication.
  * Expected:   The SubscriptionManager retrieves the correct SubscriptionCallback and the
  *             Interpreter executes it correctly
  */
TEST_F(SubscriptionTest, receive_enumPublication ) {

    // getType is used by the ReplyInterpreterFactory to create an interpreter for the reply
    // so this has to match with the type being passed to the dispatcher in the reply
    ON_CALL(*mockReplyCaller, getType()).WillByDefault(Return(std::string("TestEnum")));

    // Use a semaphore to count and wait on calls to the mockTestEnumSubscriptionListener
    Semaphore semaphore(0);
    EXPECT_CALL(*mockTestEnumSubscriptionListener, onReceive(A<const joynr::tests::testTypes::TestEnum::Enum&>()))
            .WillRepeatedly(ReleaseSemaphore(&semaphore));

    //register the subscription on the consumer side
    std::string attributeName = "testEnum";
    Variant subscriptionQos = Variant::make<OnChangeWithKeepAliveSubscriptionQos>(OnChangeWithKeepAliveSubscriptionQos(
                500, // validity_ms
                1000, // minInterval_ms
                2000, // maxInterval_ms
                1000 // alertInterval_ms
    ));

    SubscriptionRequest subscriptionRequest;
    //construct a reply containing a GpsLocation
    SubscriptionPublication subscriptionPublication;
    subscriptionPublication.setSubscriptionId(subscriptionRequest.getSubscriptionId());
    std::vector<Variant> response;
    response.push_back(Variant::make<joynr::tests::testTypes::TestEnum::Enum>(tests::testTypes::TestEnum::ZERO));
    subscriptionPublication.setResponse(response);

    auto subscriptionCallback = std::make_shared<SubscriptionCallback<joynr::tests::testTypes::TestEnum::Enum>>(mockTestEnumSubscriptionListener);

    // subscriptionRequest is an out param
    subscriptionManager->registerSubscription(
                attributeName,
                subscriptionCallback,
                subscriptionQos,
                subscriptionRequest);
    // incoming publication from the provider
    JoynrMessage msg = messageFactory.createSubscriptionPublication(
                providerParticipantId,
                proxyParticipantId,
                qos,
                subscriptionPublication);

    dispatcher.receive(msg);

    // Assert that only one subscription message is received by the subscription listener
    ASSERT_TRUE(semaphore.waitFor(std::chrono::seconds(1)));
    ASSERT_FALSE(semaphore.waitFor(std::chrono::seconds(1)));
}
TEST_F(JoynrMessageFactoryTest, createSubscriptionRequest){
    auto subscriptionQos = QSharedPointer<SubscriptionQos>(new OnChangeSubscriptionQos());
    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(QString("subscriptionId"));
    subscriptionRequest.setAttributeName(QString("attributeName"));
    subscriptionRequest.setQos(subscriptionQos);
    JoynrMessage joynrMessage = messageFactory.createSubscriptionRequest(
                senderID,
                receiverID,
                qos,
                subscriptionRequest
    );
    checkParticipantIDs(joynrMessage);
    EXPECT_QSTREQ(JoynrMessage::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REQUEST, joynrMessage.getType());
}
bool ControlPoint::subscribe(Service *service, const std::string &uuid, long timeout) {
  SubscriptionRequest subReq;
  subReq.setRenewRequest(service, uuid, timeout);
  if (Debug::isOn() == true)
    subReq.print();  
  SubscriptionResponse *subRes = subReq.post();
  if (Debug::isOn() == true)
    subRes->print();  
  if (subRes->isSuccessful() == true) {
    string sidBuf;
    service->setSID(subRes->getSID(sidBuf));
    service->setTimeout(subRes->getTimeout());
    return true;
  }
  service->clearSID();
  return false;
}
void ClassDeserializerImpl<SubscriptionRequest>::deserialize(
        SubscriptionRequest& subscriptionRequest,
        IObject& o)
{
    while (o.hasNextField()) {
        IField& field = o.nextField();
        if (field.name() == "subscriptionId") {
            subscriptionRequest.setSubscriptionId(field.value());
        }
        if (field.name() == "subscribedToName") {
            subscriptionRequest.setSubscribeToName(field.value());
        }
        if (field.name() == "qos") {
            Variant qos = convertVariant(field.value());
            subscriptionRequest.setQos(qos);
        }
    }
}
Exemple #14
0
/**
  * Precondition: Dispatcher receives a SubscriptionRequest for a not(yet) existing Provider.
  * Trigger:    The provider is registered.
  * Expected:   The PublicationManager registers the provider and notifies the PublicationManager
  *             to restore waiting Subscriptions
  */
TEST_F(SubscriptionTest, receive_RestoresSubscription) {

    qRegisterMetaType<QtOnChangeWithKeepAliveSubscriptionQos>("QtOnChangeWithKeepAliveSubscriptionQos");
    qRegisterMetaType<SubscriptionRequest>("SubscriptionRequest");

    // Use a semaphore to count and wait on calls to the mockRequestCaller
    QSemaphore semaphore(0);
    EXPECT_CALL(
            *mockRequestCaller,
            getLocation(A<std::function<void(const types::Localisation::GpsLocation&)>>())
    )
            .WillOnce(DoAll(
                    Invoke(mockRequestCaller.data(), &MockTestRequestCaller::invokeOnSuccessFct),
                    ReleaseSemaphore(&semaphore)
            ));
    QString attributeName = "Location";
    auto subscriptionQos = QSharedPointer<QtSubscriptionQos>(new QtOnChangeWithKeepAliveSubscriptionQos(
                80, // validity_ms
                100, // minInterval_ms
                200, // maxInterval_ms
                80 // alertInterval_ms
    ));
    QString subscriptionId = "SubscriptionID";

    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setSubscribeToName(attributeName);
    subscriptionRequest.setQos(subscriptionQos);

    JoynrMessage msg = messageFactory.createSubscriptionRequest(
                QString::fromStdString(proxyParticipantId),
                QString::fromStdString(providerParticipantId),
                qos,
                subscriptionRequest);
    // first received message with subscription request

    dispatcher.receive(msg);
    dispatcher.addRequestCaller(providerParticipantId, mockRequestCaller);
    ASSERT_TRUE(semaphore.tryAcquire(1,15000));
    //Try to acquire a semaphore for up to 5 seconds. Acquireing the semaphore will only work, if the mockRequestCaller has been called
    //and will be much faster than waiting for 500ms to make sure it has been called
}
Exemple #15
0
/**
  * Precondition: Dispatcher receives a SubscriptionRequest for a not(yet) existing Provider.
  * Trigger:    The provider is registered.
  * Expected:   The PublicationManager registers the provider and notifies the PublicationManager
  *             to restore waiting Subscriptions
  */
TEST_F(SubscriptionTest, receive_RestoresSubscription) {

    // Use a semaphore to count and wait on calls to the mockRequestCaller
    Semaphore semaphore(0);
    EXPECT_CALL(
            *mockRequestCaller,
            getLocation(A<std::function<void(const types::Localisation::GpsLocation&)>>(),
                        A<std::function<void(const joynr::exceptions::ProviderRuntimeException&)>>())
    )
            .WillOnce(DoAll(
                    Invoke(mockRequestCaller.get(), &MockTestRequestCaller::invokeLocationOnSuccessFct),
                    ReleaseSemaphore(&semaphore)
            ));
    std::string attributeName = "Location";
    Variant subscriptionQos = Variant::make<OnChangeWithKeepAliveSubscriptionQos>(OnChangeWithKeepAliveSubscriptionQos(
                500, // validity_ms
                1000, // minInterval_ms
                2000, // maxInterval_ms
                1000 // alertInterval_ms
    ));
    std::string subscriptionId = "SubscriptionID";

    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setSubscribeToName(attributeName);
    subscriptionRequest.setQos(subscriptionQos);

    JoynrMessage msg = messageFactory.createSubscriptionRequest(
                proxyParticipantId,
                providerParticipantId,
                qos,
                subscriptionRequest);
    // first received message with subscription request

    dispatcher.receive(msg);
    dispatcher.addRequestCaller(providerParticipantId, mockRequestCaller);
    ASSERT_TRUE(semaphore.waitFor(std::chrono::seconds(15)));
    //Try to acquire a semaphore for up to 15 seconds. Acquireing the semaphore will only work, if the mockRequestCaller has been called
    //and will be much faster than waiting for 1s to make sure it has been called
}
Exemple #16
0
/**
  * Precondition: A provider is registered and there is at least one subscription for it.
  * Trigger:    The request caller is removed from the dispatcher
  * Expected:   The PublicationManager stops all subscriptions for this provider
  */
TEST_F(SubscriptionTest, removeRequestCaller_stopsPublications) {

    // Use a semaphore to count and wait on calls to the mockRequestCaller
    Semaphore semaphore(0);
    EXPECT_CALL(*mockRequestCaller, getLocation(_,_))
            .WillRepeatedly(
                DoAll(
                    Invoke(mockRequestCaller.get(), &MockTestRequestCaller::invokeLocationOnSuccessFct),
                    ReleaseSemaphore(&semaphore)));

    dispatcher.addRequestCaller(providerParticipantId, mockRequestCaller);
    Variant subscriptionQos = Variant::make<OnChangeWithKeepAliveSubscriptionQos>(OnChangeWithKeepAliveSubscriptionQos(
                1200, // validity_ms
                10, // minInterval_ms
                100, // maxInterval_ms
                1100 // alertInterval_ms
    ));
    std::string subscriptionId = "SubscriptionID";
    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(subscriptionId);
    std::string attributeName = "Location";
    subscriptionRequest.setSubscribeToName(attributeName);
    subscriptionRequest.setQos(subscriptionQos);

    JoynrMessage msg = messageFactory.createSubscriptionRequest(
                proxyParticipantId,
                providerParticipantId,
                qos,
                subscriptionRequest);
    // first received message with subscription request
    dispatcher.receive(msg);
    // wait for two requests from the subscription
    ASSERT_TRUE(semaphore.waitFor(std::chrono::seconds(1)));
    ASSERT_TRUE(semaphore.waitFor(std::chrono::seconds(1)));
    // remove the request caller
    dispatcher.removeRequestCaller(providerParticipantId);
    // assert that less than 2 requests happen in the next 300 milliseconds
    semaphore.waitFor(std::chrono::milliseconds(300));
    ASSERT_FALSE(semaphore.waitFor(std::chrono::milliseconds(300)));
}
TEST_F(AgentConsolidatorTest, add_multiple) {
    AgentConsolidatorHandle *handle1, *handle2;
    SubscriptionRequest request;
    SubscriptionRequest system_accepted_request;
    telemetry::Path *path;

    // Build a request
    path = request.add_path_list();
    path->set_path("firewall");
    path = request.add_path_list();
    path->set_path("port");

    // Add it to the consolidator
    handle1 = cons->addRequest(61, &request, &system_accepted_request);
    EXPECT_TRUE(handle1 != NULL);
    for (int i = 0; i < request.path_list_size(); i++) {
        EXPECT_STREQ(request.path_list(i).path().c_str(),
                     system_accepted_request.path_list(i).path().c_str());
    }

    // Add it to the consolidator
    handle2 = cons->addRequest(62, &request, &system_accepted_request);
    EXPECT_TRUE(handle2 != NULL);

    // Only two system requests should have been created
    EXPECT_EQ(2, cons->getSystemRequestCount());
    EXPECT_EQ(2, cons->getAddCount());
    EXPECT_EQ(0, cons->getErrors());

    // Remove it now
    cons->removeRequest(handle1);
    EXPECT_EQ(2, cons->getSystemRequestCount());
    EXPECT_EQ(1, cons->getRemCount());
    EXPECT_EQ(0, cons->getErrors());

    cons->removeRequest(handle2);
    EXPECT_EQ(0, cons->getSystemRequestCount());
    EXPECT_EQ(2, cons->getRemCount());
    EXPECT_EQ(0, cons->getErrors());
}
/**
  * Precondition: Dispatcher receives a SubscriptionRequest for a not(yet) existing Provider.
  * Trigger:    The provider is registered.
  * Expected:   The PublicationManager registers the provider and notifies the PublicationManager
  *             to restore waiting Subscriptions
  */
TEST_F(SubscriptionTest, receive_RestoresSubscription) {

    qRegisterMetaType<OnChangeWithKeepAliveSubscriptionQos>("OnChangeWithKeepAliveSubscriptionQos");
    qRegisterMetaType<SubscriptionRequest>("SubscriptionRequest");

    // Use a semaphore to count and wait on calls to the mockRequestCaller
    QSemaphore semaphore(0);
    EXPECT_CALL(*mockRequestCaller, getLocation(A<RequestStatus&>(), A<types::GpsLocation&>()))
            .WillOnce(DoAll( SetArgReferee<1>(gpsLocation1),
                             ReleaseSemaphore(&semaphore))
                          );

    QString attributeName = "Location";
    auto subscriptionQos = QSharedPointer<SubscriptionQos>(new OnChangeWithKeepAliveSubscriptionQos(
                80, // validity_ms
                100, // minInterval_ms
                200, // maxInterval_ms
                80 // alertInterval_ms
    ));
    QString subscriptionId = "SubscriptionID";

    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setAttributeName(attributeName);
    subscriptionRequest.setQos(subscriptionQos);

    JoynrMessage msg = messageFactory.createSubscriptionRequest(
                proxyParticipantId,
                providerParticipantId,
                qos,
                subscriptionRequest);
    // first received message with subscription request

    dispatcher.receive(msg, qos);
    dispatcher.addRequestCaller(providerParticipantId, mockRequestCaller);
    ASSERT_TRUE(semaphore.tryAcquire(1,15000));
    //Try to acquire a semaphore for up to 5 seconds. Acquireing the semaphore will only work, if the mockRequestCaller has been called
    //and will be much faster than waiting for 500ms to make sure it has been called
}
/**
  * Precondition: A provider is registered and there is at least one subscription for it.
  * Trigger:    The request caller is removed from the dispatcher
  * Expected:   The PublicationManager stops all subscriptions for this provider
  */
TEST_F(SubscriptionTest, removeRequestCaller_stopsPublications) {
    qRegisterMetaType<OnChangeWithKeepAliveSubscriptionQos>("OnChangeWithKeepAliveSubscriptionQos");
    qRegisterMetaType<SubscriptionRequest>("SubscriptionRequest");
    qRegisterMetaType<SubscriptionStop>("SubscriptionStop");

    // Use a semaphore to count and wait on calls to the mockRequestCaller
    QSemaphore semaphore(0);
    EXPECT_CALL(*mockRequestCaller, getLocation(_, _))
            .WillRepeatedly(ReleaseSemaphore(&semaphore));

    dispatcher.addRequestCaller(providerParticipantId, mockRequestCaller);
    QString attributeName = "Location";
    auto subscriptionQos = QSharedPointer<SubscriptionQos>(new OnChangeWithKeepAliveSubscriptionQos(
                1200, // validity_ms
                10, // minInterval_ms
                100, // maxInterval_ms
                1100 // alertInterval_ms
    ));
    QString subscriptionId = "SubscriptionID";
    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setAttributeName(attributeName);
    subscriptionRequest.setQos(subscriptionQos);

    JoynrMessage msg = messageFactory.createSubscriptionRequest(
                proxyParticipantId,
                providerParticipantId,
                qos,
                subscriptionRequest);
    // first received message with subscription request
    dispatcher.receive(msg, qos);
    // wait for two requests from the subscription
    ASSERT_TRUE(semaphore.tryAcquire(2, 1000));
    // remove the request caller
    dispatcher.removeRequestCaller(providerParticipantId);
    // assert that less than 2 requests happen in the next 300 milliseconds
    ASSERT_FALSE(semaphore.tryAcquire(2, 300));
}
Exemple #20
0
TEST_F(SubscriptionTest, sendPublication_attributeWithSingleArrayParam) {

    std::string subscriptionId = "SubscriptionID";
    Variant subscriptionQos =
            Variant::make<OnChangeSubscriptionQos>(OnChangeSubscriptionQos(
                800, // validity_ms
                0 // minInterval_ms
    ));

    // Use a semaphore to count and wait on calls to the mockRequestCaller
    Semaphore semaphore(0);

    SubscriptionRequest subscriptionRequest;
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setSubscribeToName("listOfStrings");
    subscriptionRequest.setQos(subscriptionQos);

    EXPECT_CALL(
            *provider,
            getListOfStrings(A<std::function<void(const std::vector<std::string> &)>>(),
                    A<std::function<void(const joynr::exceptions::ProviderRuntimeException&)>>())
    )
            .WillOnce(DoAll(
                    Invoke(provider.get(), &MockTestProvider::invokeListOfStringsOnSuccess),
                    ReleaseSemaphore(&semaphore)
            ));

    auto mockMessageRouter = std::make_shared<MockMessageRouter>();
    JoynrMessageSender* joynrMessageSender = new JoynrMessageSender(mockMessageRouter);

    /* ensure the serialization succeeds and the first publication is send to the proxy */
    EXPECT_CALL(*mockMessageRouter, route(
                     AllOf(
                         A<JoynrMessage>(),
                         Property(&JoynrMessage::getHeaderFrom, Eq(providerParticipantId)),
                         Property(&JoynrMessage::getHeaderTo, Eq(proxyParticipantId))),
                     _
                     ));

    publicationManager->add(
                proxyParticipantId,
                providerParticipantId,
                requestCaller,
                subscriptionRequest,
                joynrMessageSender);

    ASSERT_TRUE(semaphore.waitFor(std::chrono::seconds(15)));

    std::vector<std::string> listOfStrings;
    listOfStrings.push_back("1");
    listOfStrings.push_back("2");

    /* ensure the value change leads to another publication */
    Mock::VerifyAndClear(mockMessageRouter.get());
    EXPECT_CALL(*mockMessageRouter, route(
                     AllOf(
                         A<JoynrMessage>(),
                         Property(&JoynrMessage::getHeaderFrom, Eq(providerParticipantId)),
                         Property(&JoynrMessage::getHeaderTo, Eq(proxyParticipantId))),
                     _
                     ));


    provider->listOfStringsChanged(listOfStrings);

    delete joynrMessageSender;
}
Exemple #21
0
void SubscriptionManager::registerSubscription(
        const std::string& subscribeToName,
        std::shared_ptr<ISubscriptionCallback> subscriptionCaller,
        const Variant& qosVariant,
        SubscriptionRequest& subscriptionRequest)
{
    // Register the subscription
    std::string subscriptionId = subscriptionRequest.getSubscriptionId();
    JOYNR_LOG_DEBUG(logger, "Subscription registered. ID={}", subscriptionId);

    if (subscriptions.contains(subscriptionId)) {
        // pre-existing subscription: remove it first from the internal data structure
        unregisterSubscription(subscriptionId);
    }

    std::int64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
                               std::chrono::system_clock::now().time_since_epoch()).count();
    subscriptionRequest.setQos(qosVariant);
    const SubscriptionQos* qos = subscriptionRequest.getSubscriptionQosPtr();
    if (qos->getExpiryDateMs() != SubscriptionQos::NO_EXPIRY_DATE() &&
        qos->getExpiryDateMs() < now) {
        throw std::invalid_argument("Subscription ExpiryDate " +
                                    std::to_string(qos->getExpiryDateMs()) + " in the past. Now: " +
                                    std::to_string(now));
    }

    auto subscription = std::make_shared<Subscription>(subscriptionCaller);

    subscriptions.insert(subscriptionId, subscription);

    {
        std::lock_guard<std::recursive_mutex> subscriptionLocker(subscription->mutex);
        if (SubscriptionUtil::getAlertInterval(qosVariant) > 0 &&
            SubscriptionUtil::getPeriodicPublicationInterval(qosVariant) > 0) {
            JOYNR_LOG_DEBUG(logger, "Will notify if updates are missed.");
            std::int64_t alertAfterInterval = SubscriptionUtil::getAlertInterval(qosVariant);
            JoynrTimePoint expiryDate(std::chrono::milliseconds(qos->getExpiryDateMs()));
            if (qos->getExpiryDateMs() == SubscriptionQos::NO_EXPIRY_DATE()) {
                expiryDate = JoynrTimePoint(
                        std::chrono::milliseconds(std::numeric_limits<std::int64_t>::max()));
            }
            std::int64_t periodicPublicationInterval =
                    SubscriptionUtil::getPeriodicPublicationInterval(qosVariant);

            subscription->missedPublicationRunnableHandle = missedPublicationScheduler->schedule(
                    new MissedPublicationRunnable(expiryDate,
                                                  periodicPublicationInterval,
                                                  subscriptionId,
                                                  subscription,
                                                  *this,
                                                  alertAfterInterval),
                    std::chrono::milliseconds(alertAfterInterval));
        } else if (qos->getExpiryDateMs() != SubscriptionQos::NO_EXPIRY_DATE()) {
            std::int64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
                                       std::chrono::system_clock::now().time_since_epoch()).count();
            subscription->subscriptionEndRunnableHandle = missedPublicationScheduler->schedule(
                    new SubscriptionEndRunnable(subscriptionId, *this),
                    std::chrono::milliseconds(qos->getExpiryDateMs() - now));
        }
    }
    subscriptionRequest.setSubscriptionId(subscriptionId);
    subscriptionRequest.setSubscribeToName(subscribeToName);
}