Beispiel #1
0
/**
  * 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));
}
/**
  * Trigger:    The dispatcher receives a Publication from a broadcast with multiple output parameters.
  * Expected:   The SubscriptionManager retrieves the correct SubscriptionCallback and the
  *             Interpreter executes it correctly
  */
TEST_F(BroadcastSubscriptionTest, receive_publication_multipleOutputParameters ) {

    qRegisterMetaType<SubscriptionPublication>("SubscriptionPublication");

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

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

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

    QSharedPointer<SubscriptionCallback<types::QtGpsLocation, double>> subscriptionCallback(
            new SubscriptionCallback<types::QtGpsLocation, double>(mockSubscriptionListenerTwo));

    // subscriptionRequest is an out param
    subscriptionManager->registerSubscription(
                subscribeToName,
                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.tryAcquire(1, 1000));
    ASSERT_FALSE(semaphore.tryAcquire(1, 250));
}
Beispiel #3
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)));
}
Beispiel #4
0
void Dispatcher::handlePublicationReceived(const JoynrMessage& message)
{
    std::string jsonSubscriptionPublication = message.getPayload();

    try {
        SubscriptionPublication subscriptionPublication =
                JsonSerializer::deserialize<SubscriptionPublication>(jsonSubscriptionPublication);

        std::string subscriptionId = subscriptionPublication.getSubscriptionId();

        assert(subscriptionManager != nullptr);

        std::shared_ptr<ISubscriptionCallback> callback =
                subscriptionManager->getSubscriptionCallback(subscriptionId);
        if (!callback) {
            JOYNR_LOG_ERROR(logger,
                            "Dropping reply for non/no more existing subscription with id = {}",
                            subscriptionId);
            return;
        }

        subscriptionManager->touchSubscriptionState(subscriptionId);

        int typeId = callback->getTypeId();

        // Get the publication interpreter - this has to be a reference to support
        // PublicationInterpreter polymorphism
        IPublicationInterpreter& interpreter =
                MetaTypeRegistrar::instance().getPublicationInterpreter(typeId);
        interpreter.execute(callback, subscriptionPublication);
    } catch (const std::invalid_argument& e) {
        JOYNR_LOG_ERROR(
                logger,
                "Unable to deserialize subscription publication object from: {} - error: {}",
                jsonSubscriptionPublication,
                e.what());
    }
}
Beispiel #5
0
void Dispatcher::handlePublicationReceived(const JoynrMessage& message)
{
    QByteArray jsonSubscriptionPublication = message.getPayload();

    SubscriptionPublication* subscriptionPublication =
            JsonSerializer::deserialize<SubscriptionPublication>(jsonSubscriptionPublication);
    if (subscriptionPublication == Q_NULLPTR) {
        LOG_ERROR(logger,
                  QString("Unable to deserialize subscription publication object from: %1")
                          .arg(QString::fromUtf8(jsonSubscriptionPublication)));
        return;
    }
    QString subscriptionId = subscriptionPublication->getSubscriptionId();

    assert(subscriptionManager != NULL);

    QSharedPointer<ISubscriptionCallback> callback =
            subscriptionManager->getSubscriptionCallback(subscriptionId);
    if (callback.isNull()) {
        LOG_ERROR(logger,
                  "Dropping reply for non/no more existing subscription with id=" + subscriptionId);
        delete subscriptionPublication;
        return;
    }

    subscriptionManager->touchSubscriptionState(subscriptionId);

    int typeId = callback->getTypeId();

    // Get the publication interpreter - this has to be a reference to support
    // PublicationInterpreter polymorphism
    IPublicationInterpreter& interpreter =
            MetaTypeRegistrar::instance().getPublicationInterpreter(typeId);
    interpreter.execute(callback, *subscriptionPublication);

    delete subscriptionPublication;
}
void InProcessPublicationSender::sendSubscriptionPublication(
        const std::string& senderParticipantId,
        const std::string& receiverParticipantId,
        const MessagingQos& qos,
        const SubscriptionPublication& subscriptionPublication)
{
    Q_UNUSED(senderParticipantId); // interface has sourcePartId, because JoynrMessages have a
                                   // source and dest. partId. Those are not necessary for in
                                   // process
    Q_UNUSED(receiverParticipantId);
    Q_UNUSED(qos);

    /**
      * just call the InProcessDispatcher!
      */

    QString subscriptionId = subscriptionPublication.getSubscriptionId();
    LOG_TRACE(logger, "Sending publication. id=" + subscriptionId);
    assert(subscriptionManager != NULL);
    subscriptionManager->touchSubscriptionState(subscriptionId);
    QSharedPointer<ISubscriptionCallback> callback =
            subscriptionManager->getSubscriptionCallback(subscriptionId);
    if (callback.isNull()) {
        LOG_ERROR(logger,
                  "Dropping reply for non/no more existing subscription with id=" + subscriptionId);
        return;
    }

    int typeId = callback->getTypeId();

    // Get the publication interpreter - this has to be a reference to support
    // PublicationInterpreter polymorphism
    IPublicationInterpreter& interpreter =
            MetaTypeRegistrar::instance().getPublicationInterpreter(typeId);
    LOG_TRACE(logger, "Interpreting publication. id=" + subscriptionId);
    interpreter.execute(callback, subscriptionPublication);
}