void testOneShotAttributeSubscription(const T& expectedValue,
                                          SubscribeTo subscribeTo,
                                          ChangeAttribute setAttribute,
                                          const std::string& attributeName) {
        MockSubscriptionListenerOneType<T>* mockListener =
                new MockSubscriptionListenerOneType<T>();

        // Use a semaphore to count and wait on calls to the mock listener
        ON_CALL(*mockListener, onReceive(Eq(expectedValue)))
                .WillByDefault(ReleaseSemaphore(&semaphore));

        std::shared_ptr<ISubscriptionListener<T>> subscriptionListener(
                        mockListener);

        std::shared_ptr<tests::DefaulttestProvider> testProvider(new tests::DefaulttestProvider());
        runtime1->registerProvider<tests::testProvider>(domainName, testProvider);

        //This wait is necessary, because registerProvider is async, and a lookup could occur
        // before the register has finished.
        std::this_thread::sleep_for(std::chrono::milliseconds(registerProviderWait));

        (*testProvider.*setAttribute)(expectedValue, [](){}, [](const joynr::exceptions::ProviderRuntimeException&) {});
        ProxyBuilder<tests::testProxy>* testProxyBuilder
                = runtime2->createProxyBuilder<tests::testProxy>(domainName);
        DiscoveryQos discoveryQos;
        discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::HIGHEST_PRIORITY);
        discoveryQos.setDiscoveryTimeout(1000);
        discoveryQos.setRetryInterval(250);

        std::int64_t qosRoundTripTTL = 500;

        // Send a message and expect to get a result
        tests::testProxy* testProxy = testProxyBuilder
                ->setMessagingQos(MessagingQos(qosRoundTripTTL))
                ->setCached(false)
                ->setDiscoveryQos(discoveryQos)
                ->build();

        std::int64_t minInterval_ms = 50;
        OnChangeSubscriptionQos subscriptionQos(
                    500000,   // validity_ms
                    minInterval_ms);  // minInterval_ms

        subscribeTo(testProxy, subscriptionListener, subscriptionQos);
        waitForAttributeSubscriptionArrivedAtProvider(testProvider, attributeName);

        // Wait for a subscription message to arrive
        ASSERT_TRUE(semaphore.waitFor(std::chrono::seconds(3)));

        delete testProxyBuilder;
        delete testProxy;
    }
Example #2
0
void LibJoynrRuntime::init(
        std::unique_ptr<IMiddlewareMessagingStubFactory> middlewareMessagingStubFactory,
        std::shared_ptr<const joynr::system::RoutingTypes::Address> libjoynrMessagingAddress,
        std::shared_ptr<const joynr::system::RoutingTypes::Address> ccMessagingAddress)
{
    // create messaging stub factory
    auto messagingStubFactory = std::make_unique<MessagingStubFactory>();
    messagingStubFactory->registerStubFactory(std::move(middlewareMessagingStubFactory));
    messagingStubFactory->registerStubFactory(std::make_unique<InProcessMessagingStubFactory>());

    // create message router
    messageRouter = std::make_shared<MessageRouter>(
            std::move(messagingStubFactory), libjoynrMessagingAddress);

    startLibJoynrMessagingSkeleton(*messageRouter);

    joynrMessageSender = new JoynrMessageSender(messageRouter);
    joynrDispatcher = new Dispatcher(joynrMessageSender);
    joynrMessageSender->registerDispatcher(joynrDispatcher);

    // create the inprocess skeleton for the dispatcher
    dispatcherMessagingSkeleton =
            std::make_shared<InProcessLibJoynrMessagingSkeleton>(joynrDispatcher);
    dispatcherAddress = std::make_shared<InProcessMessagingAddress>(dispatcherMessagingSkeleton);

    publicationManager = new PublicationManager();
    subscriptionManager = new SubscriptionManager();
    inProcessDispatcher = new InProcessDispatcher();

    inProcessPublicationSender = new InProcessPublicationSender(subscriptionManager);
    inProcessConnectorFactory = new InProcessConnectorFactory(
            subscriptionManager,
            publicationManager,
            inProcessPublicationSender,
            dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher));
    joynrMessagingConnectorFactory =
            new JoynrMessagingConnectorFactory(joynrMessageSender, subscriptionManager);

    auto connectorFactory = std::make_unique<ConnectorFactory>(
            inProcessConnectorFactory, joynrMessagingConnectorFactory);
    proxyFactory = new ProxyFactory(libjoynrMessagingAddress, std::move(connectorFactory), nullptr);

    // Set up the persistence file for storing provider participant ids
    std::string persistenceFilename = libjoynrSettings->getParticipantIdsPersistenceFilename();
    participantIdStorage = std::make_shared<ParticipantIdStorage>(persistenceFilename);

    // initialize the dispatchers
    std::vector<IDispatcher*> dispatcherList;
    dispatcherList.push_back(inProcessDispatcher);
    dispatcherList.push_back(joynrDispatcher);

    joynrDispatcher->registerPublicationManager(publicationManager);
    joynrDispatcher->registerSubscriptionManager(subscriptionManager);

    discoveryProxy = std::make_unique<LocalDiscoveryAggregator>(systemServicesSettings);
    requestCallerDirectory = dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher);

    std::string systemServicesDomain = systemServicesSettings.getDomain();
    std::string routingProviderParticipantId =
            systemServicesSettings.getCcRoutingProviderParticipantId();

    DiscoveryQos routingProviderDiscoveryQos;
    routingProviderDiscoveryQos.setCacheMaxAgeMs(1000);
    routingProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    routingProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", routingProviderParticipantId);
    routingProviderDiscoveryQos.setDiscoveryTimeoutMs(50);

    auto routingProxyBuilder =
            createProxyBuilder<joynr::system::RoutingProxy>(systemServicesDomain);
    auto routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(10000))
                                ->setCached(false)
                                ->setDiscoveryQos(routingProviderDiscoveryQos)
                                ->build();
    messageRouter->setParentRouter(std::unique_ptr<system::RoutingProxy>(routingProxy),
                                   ccMessagingAddress,
                                   routingProviderParticipantId);
    delete routingProxyBuilder;

    // setup discovery
    std::string discoveryProviderParticipantId =
            systemServicesSettings.getCcDiscoveryProviderParticipantId();
    DiscoveryQos discoveryProviderDiscoveryQos;
    discoveryProviderDiscoveryQos.setCacheMaxAgeMs(1000);
    discoveryProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    discoveryProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", discoveryProviderParticipantId);
    discoveryProviderDiscoveryQos.setDiscoveryTimeoutMs(1000);

    ProxyBuilder<joynr::system::DiscoveryProxy>* discoveryProxyBuilder =
            createProxyBuilder<joynr::system::DiscoveryProxy>(systemServicesDomain);
    joynr::system::IDiscoverySync* proxy =
            discoveryProxyBuilder->setMessagingQos(MessagingQos(10000))
                    ->setCached(false)
                    ->setDiscoveryQos(discoveryProviderDiscoveryQos)
                    ->build();
    discoveryProxy->setDiscoveryProxy(std::unique_ptr<joynr::system::IDiscoverySync>(proxy));
    capabilitiesRegistrar = std::make_unique<CapabilitiesRegistrar>(
            dispatcherList,
            *discoveryProxy,
            participantIdStorage,
            dispatcherAddress,
            messageRouter,
            messagingSettings.getDiscoveryEntryExpiryIntervalMs());
}
Example #3
0
void Dispatcher::handleRequestReceived(const JoynrMessage& message)
{
    std::string senderId = message.getHeaderFrom();
    std::string receiverId = message.getHeaderTo();

    // json request
    // lookup necessary data
    std::string jsonRequest = message.getPayload();
    std::shared_ptr<RequestCaller> caller = requestCallerDirectory.lookup(receiverId);
    if (caller == nullptr) {
        JOYNR_LOG_ERROR(
                logger,
                "caller not found in the RequestCallerDirectory for receiverId {}, ignoring",
                receiverId);
        return;
    }
    std::string interfaceName = caller->getInterfaceName();

    // Get the request interpreter that has been registered with this interface name
    std::shared_ptr<IRequestInterpreter> requestInterpreter =
            InterfaceRegistrar::instance().getRequestInterpreter(interfaceName);

    // deserialize json
    try {
        Request request = JsonSerializer::deserialize<Request>(jsonRequest);

        std::string requestReplyId = request.getRequestReplyId();
        JoynrTimePoint requestExpiryDate = message.getHeaderExpiryDate();

        std::function<void(std::vector<Variant>)> onSuccess =
                [requestReplyId, requestExpiryDate, this, senderId, receiverId](
                        std::vector<Variant> returnValueVar) {
            Reply reply;
            reply.setRequestReplyId(requestReplyId);
            reply.setResponse(std::move(returnValueVar));
            // send reply back to the original sender (ie. sender and receiver ids are reversed
            // on
            // purpose)
            JOYNR_LOG_DEBUG(logger,
                            "Got reply from RequestInterpreter for requestReplyId {}",
                            requestReplyId);
            JoynrTimePoint now = std::chrono::time_point_cast<std::chrono::milliseconds>(
                    std::chrono::system_clock::now());
            std::int64_t ttl = std::chrono::duration_cast<std::chrono::milliseconds>(
                                       requestExpiryDate - now).count();
            messageSender->sendReply(receiverId, // receiver of the request is sender of reply
                                     senderId,   // sender of request is receiver of reply
                                     MessagingQos(ttl),
                                     reply);
        };

        std::function<void(const exceptions::JoynrException&)> onError =
                [requestReplyId, requestExpiryDate, this, senderId, receiverId](
                        const exceptions::JoynrException& exception) {
            Reply reply;
            reply.setRequestReplyId(requestReplyId);
            reply.setError(joynr::exceptions::JoynrExceptionUtil::createVariant(exception));
            JOYNR_LOG_DEBUG(logger,
                            "Got error reply from RequestInterpreter for requestReplyId {}",
                            requestReplyId);
            JoynrTimePoint now = std::chrono::time_point_cast<std::chrono::milliseconds>(
                    std::chrono::system_clock::now());
            std::int64_t ttl = std::chrono::duration_cast<std::chrono::milliseconds>(
                                       requestExpiryDate - now).count();
            messageSender->sendReply(receiverId, // receiver of the request is sender of reply
                                     senderId,   // sender of request is receiver of reply
                                     MessagingQos(ttl),
                                     reply);
        };
        // execute request
        requestInterpreter->execute(caller,
                                    request.getMethodName(),
                                    request.getParams(),
                                    request.getParamDatatypes(),
                                    onSuccess,
                                    onError);
    } catch (const std::invalid_argument& e) {
        JOYNR_LOG_ERROR(logger,
                        "Unable to deserialize request object from: {} - error: {}",
                        jsonRequest,
                        e.what());
        return;
    }
}
void JoynrClusterControllerRuntime::initializeAllDependencies()
{
    /**
      * libjoynr side skeleton & dispatcher
      * This needs some preparation of libjoynr and clustercontroller parts.
      */
    messagingSettings = new MessagingSettings(*settings);
    messagingSettings->printSettings();
    libjoynrSettings = new LibjoynrSettings(*settings);
    libjoynrSettings->printSettings();
    wsSettings.printSettings();

    // Initialise security manager
    securityManager = new DummyPlatformSecurityManager();

    // CAREFUL: the factory creates an old style dispatcher, not the new one!

    inProcessDispatcher = new InProcessDispatcher();
    /* CC */
    // create the messaging stub factory
    MessagingStubFactory* messagingStubFactory = new MessagingStubFactory();
#ifdef USE_DBUS_COMMONAPI_COMMUNICATION
    messagingStubFactory->registerStubFactory(new DbusMessagingStubFactory());
#endif // USE_DBUS_COMMONAPI_COMMUNICATION
    messagingStubFactory->registerStubFactory(new InProcessMessagingStubFactory());
    // init message router
    messageRouter = std::shared_ptr<MessageRouter>(
            new MessageRouter(messagingStubFactory, securityManager));
    // provision global capabilities directory
    std::shared_ptr<joynr::system::RoutingTypes::Address> globalCapabilitiesDirectoryAddress(
            new system::RoutingTypes::ChannelAddress(
                    messagingSettings->getCapabilitiesDirectoryChannelId()));
    messageRouter->addProvisionedNextHop(messagingSettings->getCapabilitiesDirectoryParticipantId(),
                                         globalCapabilitiesDirectoryAddress);
    // provision channel url directory
    std::shared_ptr<joynr::system::RoutingTypes::Address> globalChannelUrlDirectoryAddress(
            new system::RoutingTypes::ChannelAddress(
                    messagingSettings->getChannelUrlDirectoryChannelId()));
    messageRouter->addProvisionedNextHop(messagingSettings->getChannelUrlDirectoryParticipantId(),
                                         globalChannelUrlDirectoryAddress);

    // setup CC WebSocket interface
    WebSocketMessagingStubFactory* wsMessagingStubFactory = new WebSocketMessagingStubFactory();
    messagingStubFactory->registerStubFactory(wsMessagingStubFactory);
    system::RoutingTypes::WebSocketAddress wsAddress =
            wsSettings.createClusterControllerMessagingAddress();

    wsCcMessagingSkeleton =
            new WebSocketCcMessagingSkeleton(*messageRouter, *wsMessagingStubFactory, wsAddress);

    /* LibJoynr */
    assert(messageRouter);
    joynrMessageSender = new JoynrMessageSender(messageRouter);
    joynrDispatcher = new Dispatcher(joynrMessageSender);
    joynrMessageSender->registerDispatcher(joynrDispatcher);

    /* CC */
    // TODO: libjoynrmessagingskeleton now uses the Dispatcher, should it use the
    // InprocessDispatcher?
    libJoynrMessagingSkeleton = std::shared_ptr<InProcessMessagingSkeleton>(
            new InProcessLibJoynrMessagingSkeleton(joynrDispatcher));
    // EndpointAddress to messagingStub is transmitted when a provider is registered
    // messagingStubFactory->registerInProcessMessagingSkeleton(libJoynrMessagingSkeleton);

    /**
      * ClusterController side
      *
      */
    if (!messageReceiver) {
        JOYNR_LOG_INFO(
                logger,
                "The message receiver supplied is NULL, creating the default MessageReceiver");
        messageReceiver = std::shared_ptr<IMessageReceiver>(
                new HttpReceiver(*messagingSettings, messageRouter));
    }

    std::string channelId = messageReceiver->getReceiveChannelId();

    // create message sender
    if (!messageSender) {
        JOYNR_LOG_INFO(
                logger, "The message sender supplied is NULL, creating the default MessageSender");
        messageSender = std::shared_ptr<IMessageSender>(new HttpSender(
                messagingSettings->getBounceProxyUrl(),
                std::chrono::milliseconds(messagingSettings->getSendMsgMaxTtl()),
                std::chrono::milliseconds(messagingSettings->getSendMsgRetryInterval())));
    }
    messagingStubFactory->registerStubFactory(
            new JoynrMessagingStubFactory(messageSender, messageReceiver->getReceiveChannelId()));

    // joynrMessagingSendSkeleton = new DummyClusterControllerMessagingSkeleton(messageRouter);
    // ccDispatcher = DispatcherFactory::createDispatcherInSameThread(messagingSettings);

    // we currently have to use the fake client, because JAVA side is not yet working for
    // CapabilitiesServer.
    bool usingRealCapabilitiesClient =
            /*when switching this to true, turn on the UUID in systemintegrationtests again*/ true;
    capabilitiesClient = new CapabilitiesClient(channelId); // ownership of this is not transferred
    // try using the real capabilitiesClient again:
    // capabilitiesClient = new CapabilitiesClient(channelId);// ownership of this is not
    // transferred

    localCapabilitiesDirectory = std::make_shared<LocalCapabilitiesDirectory>(
            *messagingSettings, capabilitiesClient, *messageRouter);
#ifdef USE_DBUS_COMMONAPI_COMMUNICATION
    dbusSettings = new DbusSettings(*settings);
    dbusSettings->printSettings();
    // register dbus skeletons for capabilities and messaging interfaces
    std::string ccMessagingAddress(dbusSettings->createClusterControllerMessagingAddressString());
    ccDbusMessageRouterAdapter = new DBusMessageRouterAdapter(*messageRouter, ccMessagingAddress);
#endif // USE_DBUS_COMMONAPI_COMMUNICATION

    /**
      * libJoynr side
      *
      */
    publicationManager = new PublicationManager();
    subscriptionManager = new SubscriptionManager();
    inProcessPublicationSender = new InProcessPublicationSender(subscriptionManager);
    std::shared_ptr<joynr::system::RoutingTypes::Address> libjoynrMessagingAddress(
            new InProcessMessagingAddress(libJoynrMessagingSkeleton));
    // subscriptionManager = new SubscriptionManager(...)
    inProcessConnectorFactory = new InProcessConnectorFactory(
            subscriptionManager,
            publicationManager,
            inProcessPublicationSender,
            dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher));
    joynrMessagingConnectorFactory =
            new JoynrMessagingConnectorFactory(joynrMessageSender, subscriptionManager);

    connectorFactory =
            createConnectorFactory(inProcessConnectorFactory, joynrMessagingConnectorFactory);

    proxyFactory = new ProxyFactory(libjoynrMessagingAddress, connectorFactory, &cache);

    dispatcherList.push_back(joynrDispatcher);
    dispatcherList.push_back(inProcessDispatcher);

    // Set up the persistence file for storing provider participant ids
    std::string persistenceFilename = libjoynrSettings->getParticipantIdsPersistenceFilename();
    participantIdStorage =
            std::shared_ptr<ParticipantIdStorage>(new ParticipantIdStorage(persistenceFilename));

    dispatcherAddress = libjoynrMessagingAddress;
    discoveryProxy = new LocalDiscoveryAggregator(
            *dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher), systemServicesSettings);

    std::string discoveryProviderParticipantId(
            systemServicesSettings.getCcDiscoveryProviderParticipantId());
    std::shared_ptr<RequestCaller> discoveryRequestCaller(
            new joynr::system::DiscoveryRequestCaller(localCapabilitiesDirectory));
    std::shared_ptr<InProcessAddress> discoveryProviderAddress(
            new InProcessAddress(discoveryRequestCaller));
    joynr::system::DiscoveryInProcessConnector* discoveryInProcessConnector =
            InProcessConnectorFactoryHelper<joynr::system::IDiscoveryConnector>().create(
                    subscriptionManager,
                    publicationManager,
                    inProcessPublicationSender,
                    std::string(), // can be ignored
                    discoveryProviderParticipantId,
                    discoveryProviderAddress);

    discoveryProxy->setDiscoveryProxy(discoveryInProcessConnector);

    capabilitiesRegistrar = new CapabilitiesRegistrar(dispatcherList,
                                                      *discoveryProxy,
                                                      libjoynrMessagingAddress,
                                                      participantIdStorage,
                                                      dispatcherAddress,
                                                      messageRouter);

    joynrDispatcher->registerPublicationManager(publicationManager);
    joynrDispatcher->registerSubscriptionManager(subscriptionManager);

    /**
     * Finish initialising Capabilitiesclient by building a Proxy and passing it
     */
    std::int64_t discoveryMessagesTtl = messagingSettings->getDiscoveryMessagesTtl();

    if (usingRealCapabilitiesClient) {
        ProxyBuilder<infrastructure::GlobalCapabilitiesDirectoryProxy>* capabilitiesProxyBuilder =
                createProxyBuilder<infrastructure::GlobalCapabilitiesDirectoryProxy>(
                        messagingSettings->getDiscoveryDirectoriesDomain());
        DiscoveryQos discoveryQos(10000);
        discoveryQos.setArbitrationStrategy(
                DiscoveryQos::ArbitrationStrategy::HIGHEST_PRIORITY); // actually only one provider
                                                                      // should be available
        std::shared_ptr<infrastructure::GlobalCapabilitiesDirectoryProxy> capabilitiesProxy(
                capabilitiesProxyBuilder->setMessagingQos(MessagingQos(discoveryMessagesTtl))
                        ->setCached(true)
                        ->setDiscoveryQos(discoveryQos)
                        ->build());
        ((CapabilitiesClient*)capabilitiesClient)->init(capabilitiesProxy);
    }

    ProxyBuilder<infrastructure::ChannelUrlDirectoryProxy>* channelUrlDirectoryProxyBuilder =
            createProxyBuilder<infrastructure::ChannelUrlDirectoryProxy>(
                    messagingSettings->getDiscoveryDirectoriesDomain());

    DiscoveryQos discoveryQos(10000);
    discoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::HIGHEST_PRIORITY); // actually only one provider
                                                                  // should be available
    channelUrlDirectoryProxy = std::shared_ptr<infrastructure::ChannelUrlDirectoryProxy>(
            channelUrlDirectoryProxyBuilder->setMessagingQos(MessagingQos(discoveryMessagesTtl))
                    ->setCached(true)
                    ->setDiscoveryQos(discoveryQos)
                    ->build());

    channelUrlDirectory = std::shared_ptr<ILocalChannelUrlDirectory>(
            new LocalChannelUrlDirectory(*messagingSettings, channelUrlDirectoryProxy));
    messageReceiver->init(channelUrlDirectory);
    messageSender->init(channelUrlDirectory, *messagingSettings);
}