コード例 #1
0
void LongPollingMessageReceiver::processReceivedJsonObjects(const std::string& jsonObject)
{
    JoynrMessage* msg = JsonSerializer::deserialize<JoynrMessage>(jsonObject);
    if (msg == nullptr) {
        JOYNR_LOG_ERROR(logger, "Unable to deserialize message. Raw message: {}", jsonObject);
        return;
    }
    if (msg->getType().empty()) {
        JOYNR_LOG_ERROR(logger, "received empty message - dropping Messages");
        return;
    }
    if (!msg->containsHeaderExpiryDate()) {
        JOYNR_LOG_ERROR(logger,
                        "received message [msgId=[{}] without decay time - dropping message",
                        msg->getHeaderMessageId());
    }

    if (msg->getType() == JoynrMessage::VALUE_MESSAGE_TYPE_REQUEST ||
        msg->getType() == JoynrMessage::VALUE_MESSAGE_TYPE_SUBSCRIPTION_REQUEST ||
        msg->getType() == JoynrMessage::VALUE_MESSAGE_TYPE_BROADCAST_SUBSCRIPTION_REQUEST) {
        // TODO ca: check if replyTo header info is available?
        std::string replyChannelId = msg->getHeaderReplyChannelId();
        std::shared_ptr<system::RoutingTypes::ChannelAddress> address(
                new system::RoutingTypes::ChannelAddress(replyChannelId));
        messageRouter->addNextHop(msg->getHeaderFrom(), address);
    }

    // messageRouter.route passes the message reference to the MessageRunnable, which copies it.
    // TODO would be nicer if the pointer would be passed to messageRouter, on to MessageRunnable,
    // and runnable should delete it.
    messageRouter->route(*msg);
    delete msg;
}
コード例 #2
0
bool LocalDomainAccessStore::insertDomainRoleEntry(const std::string& userId,
                                                   Role::Enum role,
                                                   const std::vector<std::string>& domains)
{

    // Loop through the domains
    auto it = domains.begin();
    while (it != domains.end()) {

        // Insert a record for each domain
        QSqlQuery query;
        std::string domain = *it;

        query.prepare(QtTypeUtil::toQt(UPDATE_DRE));
        query.bindValue(BIND_UID, QtTypeUtil::toQt(userId));
        query.bindValue(BIND_ROLE, role);
        query.bindValue(BIND_DOMAIN, QtTypeUtil::toQt(domain));

        if (!query.exec()) {
            JOYNR_LOG_ERROR(logger, "Could not add domain entry {} {} {}", userId, role, domain);
            return false;
        }
        ++it;
    }

    // Assume success
    return true;
}
コード例 #3
0
void LongPollingMessageReceiver::checkServerTime()
{
    std::string timeCheckUrl = bounceProxyUrl.getTimeCheckUrl().toString();

    std::shared_ptr<IHttpGetBuilder> timeCheckRequestBuilder(
            HttpNetworking::getInstance()->createHttpGetBuilder(timeCheckUrl));
    std::shared_ptr<HttpRequest> timeCheckRequest(
            timeCheckRequestBuilder->addHeader("Accept", "text/plain")
                    ->withTimeout(settings.bounceProxyTimeout)
                    ->build());
    JOYNR_LOG_DEBUG(logger, "CheckServerTime: sending request to Bounce Proxy ({})", timeCheckUrl);
    std::chrono::system_clock::time_point localTimeBeforeRequest = std::chrono::system_clock::now();
    HttpResult timeCheckResult = timeCheckRequest->execute();
    std::chrono::system_clock::time_point localTimeAfterRequest = std::chrono::system_clock::now();
    std::uint64_t localTime = (TypeUtil::toMilliseconds(localTimeBeforeRequest) +
                               TypeUtil::toMilliseconds(localTimeAfterRequest)) /
                              2;
    if (timeCheckResult.getStatusCode() != 200) {
        JOYNR_LOG_ERROR(logger,
                        "CheckServerTime: Bounce Proxy not reached [statusCode={}] [body={}]",
                        timeCheckResult.getStatusCode(),
                        QString(timeCheckResult.getBody()).toStdString());
    } else {
        JOYNR_LOG_TRACE(logger,
                        "CheckServerTime: reply received [statusCode={}] [body={}]",
                        timeCheckResult.getStatusCode(),
                        QString(timeCheckResult.getBody()).toStdString());
        std::uint64_t serverTime =
                TypeUtil::toStdUInt64(QString(timeCheckResult.getBody()).toLongLong());

        auto minMaxTime = std::minmax(serverTime, localTime);
        std::uint64_t diff = minMaxTime.second - minMaxTime.first;

        JOYNR_LOG_INFO(
                logger,
                "CheckServerTime [server time={}] [local time={}] [diff={} ms]",
                TypeUtil::toDateString(JoynrTimePoint(std::chrono::milliseconds(serverTime))),
                TypeUtil::toDateString(JoynrTimePoint(std::chrono::milliseconds(localTime))),
                diff);

        if (diff > 500) {
            JOYNR_LOG_ERROR(logger, "CheckServerTime: time difference to server is {} ms", diff);
        }
    }
}
コード例 #4
0
ファイル: Dispatcher.cpp プロジェクト: zabela/joynr
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());
    }
}
コード例 #5
0
void WebSocketLibJoynrMessagingSkeleton::onTextMessageReceived(const std::string& message)
{
    // deserialize message and transmit
    JoynrMessage* joynrMsg = JsonSerializer::deserialize<JoynrMessage>(message);
    if (joynrMsg == nullptr || joynrMsg->getType().empty()) {
        JOYNR_LOG_ERROR(logger, "Unable to deserialize joynr message object from: {}", message);
        return;
    }
    JOYNR_LOG_TRACE(logger, "<<< INCOMING <<< {}", message);
    // message router copies joynr message when scheduling thread that handles
    // message delivery
    transmit(*joynrMsg);
    delete joynrMsg;
}
コード例 #6
0
void ParticipantIdStorage::writeStoreToFile()
{
    std::lock_guard<std::mutex> lockAccessToFile(fileMutex);
    WriteLocker lockAccessToStorage(storageMutex);

    auto& writeIndex = storage.get<participantIdStorageTags::write>();
    const size_t entries = writeIndex.size();

    // The storage in memory is supposed to contain at least one entry at this point.
    if (entries == 0) {
        assert(entriesWrittenToDisk == 0);
        return;
    }

    if (entries > entriesWrittenToDisk) {
        JOYNR_LOG_TRACE(
                logger(), "Writing {} new entries to file.", entries - entriesWrittenToDisk);

        // write not present entries to File
        size_t writtenToDisk = 0;
        for (size_t i = entriesWrittenToDisk; i < entries; ++i, ++writtenToDisk) {
            auto entry = writeIndex[i];
            try {
                joynr::util::appendStringToFile(fileName, entry.toIniForm());
            } catch (const std::runtime_error& ex) {
                JOYNR_LOG_ERROR(logger(),
                                "Cannot save ParticipantId to file. Next application lifecycle "
                                "might not function correctly. Exception: ",
                                ex.what());
                entriesWrittenToDisk += writtenToDisk;
                return;
            }
        }
        assert(entries == entriesWrittenToDisk + writtenToDisk);
        entriesWrittenToDisk = entries;
        JOYNR_LOG_TRACE(logger(), "Storage on file contains now {} entries.", entriesWrittenToDisk);
    } else if (entries < entriesWrittenToDisk) {
        // This actually means that someone modified the file and inserted other entries.
        // Do nothing.
    } else {
        // In this case the number of entries written to disk matches those in the store.
        // Do nothing.
    }
}
コード例 #7
0
ファイル: Dispatcher.cpp プロジェクト: zabela/joynr
void Dispatcher::handleReplyReceived(const JoynrMessage& message)
{
    // json request
    // lookup necessary data
    std::string jsonReply = message.getPayload();

    // deserialize the jsonReply
    try {
        Reply reply = JsonSerializer::deserialize<Reply>(jsonReply);
        std::string requestReplyId = reply.getRequestReplyId();

        std::shared_ptr<IReplyCaller> caller = replyCallerDirectory.lookup(requestReplyId);
        if (caller == nullptr) {
            // This used to be a fatal error, but it is possible that the replyCallerDirectory
            // removed
            // the caller
            // because its lifetime exceeded TTL
            JOYNR_LOG_INFO(
                    logger,
                    "caller not found in the ReplyCallerDirectory for requestid {}, ignoring",
                    requestReplyId);
            return;
        }

        // Get the reply interpreter - this has to be a reference to support ReplyInterpreter
        // polymorphism
        int typeId = caller->getTypeId();
        IReplyInterpreter& interpreter = MetaTypeRegistrar::instance().getReplyInterpreter(typeId);

        // pass reply
        interpreter.execute(caller, reply);

        // Clean up
        removeReplyCaller(requestReplyId);
    } catch (const std::invalid_argument& e) {
        JOYNR_LOG_ERROR(logger,
                        "Unable to deserialize reply object from: {} - error {}",
                        jsonReply,
                        e.what());
    }
}
コード例 #8
0
ファイル: Dispatcher.cpp プロジェクト: zabela/joynr
void Dispatcher::handleSubscriptionStopReceived(const JoynrMessage& message)
{
    JOYNR_LOG_DEBUG(logger, "handleSubscriptionStopReceived");
    std::string jsonSubscriptionStop = message.getPayload();

    std::string subscriptionId;
    try {
        SubscriptionStop subscriptionStop =
                JsonSerializer::deserialize<SubscriptionStop>(jsonSubscriptionStop);

        subscriptionId = subscriptionStop.getSubscriptionId();
    } catch (const std::invalid_argument& e) {
        JOYNR_LOG_ERROR(logger,
                        "Unable to deserialize subscription stop object from: {} - error: {}",
                        jsonSubscriptionStop,
                        e.what());
        return;
    }
    assert(publicationManager != nullptr);
    publicationManager->stopPublication(subscriptionId);
}
コード例 #9
0
ファイル: Dispatcher.cpp プロジェクト: zabela/joynr
void Dispatcher::handleBroadcastSubscriptionRequestReceived(const JoynrMessage& message)
{
    JOYNR_LOG_TRACE(logger, "Starting handleBroadcastSubscriptionRequestReceived");
    // Make sure that noone is registering a Caller at the moment, because a racing condition could
    // occour.
    std::lock_guard<std::mutex> lock(subscriptionHandlingMutex);
    assert(publicationManager != nullptr);

    std::string receiverId = message.getHeaderTo();
    std::shared_ptr<RequestCaller> caller = requestCallerDirectory.lookup(receiverId);

    std::string jsonSubscriptionRequest = message.getPayload();

    // PublicationManager is responsible for deleting SubscriptionRequests
    try {
        BroadcastSubscriptionRequest subscriptionRequest =
                JsonSerializer::deserialize<BroadcastSubscriptionRequest>(jsonSubscriptionRequest);

        if (!caller) {
            // Provider not registered yet
            // Dispatcher will call publicationManger->restore when a new provider is added to
            // activate
            // subscriptions for that provider
            publicationManager->add(
                    message.getHeaderFrom(), message.getHeaderTo(), subscriptionRequest);
        } else {
            publicationManager->add(message.getHeaderFrom(),
                                    message.getHeaderTo(),
                                    caller,
                                    subscriptionRequest,
                                    messageSender);
        }
    } catch (const std::invalid_argument& e) {
        JOYNR_LOG_ERROR(
                logger,
                "Unable to deserialize broadcast subscription request object from: {} - error: {}",
                jsonSubscriptionRequest,
                e.what());
    }
}
コード例 #10
0
ファイル: Dispatcher.cpp プロジェクト: zabela/joynr
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;
    }
}
コード例 #11
0
void LongPollingMessageReceiver::run()
{
    checkServerTime();
    std::string createChannelUrl = bounceProxyUrl.getCreateChannelUrl(channelId).toString();
    JOYNR_LOG_INFO(logger, "Running lpmr with channelId {}", channelId);
    std::shared_ptr<IHttpPostBuilder> createChannelRequestBuilder(
            HttpNetworking::getInstance()->createHttpPostBuilder(createChannelUrl));
    std::shared_ptr<HttpRequest> createChannelRequest(
            createChannelRequestBuilder->addHeader("X-Atmosphere-tracking-id", receiverId)
                    ->withContentType("application/json")
                    ->withTimeout(settings.bounceProxyTimeout)
                    ->build());

    std::string channelUrl;
    while (channelUrl.empty() && !isInterrupted()) {
        JOYNR_LOG_DEBUG(logger, "sending create channel request");
        HttpResult createChannelResult = createChannelRequest->execute();
        if (createChannelResult.getStatusCode() == 201) {
            channelUrl = *createChannelResult.getHeaders().find("Location");
            JOYNR_LOG_INFO(logger, "channel creation successfull; channel url: {}", channelUrl);
            channelCreatedSemaphore->notify();
        } else {
            JOYNR_LOG_INFO(logger,
                           "channel creation failed); status code: {}",
                           createChannelResult.getStatusCode());
            std::unique_lock<std::mutex> lock(interruptedMutex);
            interruptedWait.wait_for(lock, settings.createChannelRetryInterval);
        }
    }
    /**
      * register the channelUrl with the ChannelUrlDirectory (asynchronously)
      */
    assert(channelUrlDirectory != nullptr);
    types::ChannelUrlInformation urlInformation;
    std::vector<std::string> urls = {channelUrl};
    urlInformation.setUrls(urls);
    JOYNR_LOG_INFO(
            logger,
            "Adding channelId and Url of cluster controller to remote ChannelUrlDirectory {}",
            channelUrl);
    channelUrlDirectory->registerChannelUrlsAsync(channelId, urlInformation);

    while (!isInterrupted()) {

        std::shared_ptr<IHttpGetBuilder> longPollRequestBuilder(
                HttpNetworking::getInstance()->createHttpGetBuilder(channelUrl));

        std::shared_ptr<HttpRequest> longPollRequest(
                longPollRequestBuilder->acceptGzip()
                        ->addHeader("Accept", "application/json")
                        ->addHeader("X-Atmosphere-tracking-id", receiverId)
                        ->withTimeout(settings.longPollTimeout)
                        ->build());

        JOYNR_LOG_DEBUG(logger, "sending long polling request; url: {}", channelUrl);
        HttpResult longPollingResult = longPollRequest->execute();
        if (!isInterrupted()) {
            // TODO: remove HttpErrorCodes and use constants.
            // there is a bug in atmosphere, which currently gives back 503 instead of 200 as a
            // result to longpolling.
            // Accepting 503 is a temporary workaround for this bug. As soon as atmosphere is fixed,
            // this should be removed
            // 200 does nott refect the state of the message body! It could be empty.
            if (longPollingResult.getStatusCode() == 200 ||
                longPollingResult.getStatusCode() == 503) {
                Util::logSerializedMessage(logger,
                                           "long polling successful; contents: ",
                                           longPollingResult.getBody().data());
                processReceivedInput(longPollingResult.getBody());
                // Atmosphere currently cannot return 204 when a long poll times out, so this code
                // is currently never executed (2.2.2012)
            } else if (longPollingResult.getStatusCode() == 204) {
                JOYNR_LOG_DEBUG(logger, "long polling successfull);full; no data");
            } else {
                std::string body("NULL");
                if (!longPollingResult.getBody().isNull()) {
                    body = QString(longPollingResult.getBody().data()).toStdString();
                }
                JOYNR_LOG_ERROR(logger,
                                "long polling failed; error message: {}; contents: {}",
                                longPollingResult.getErrorMessage(),
                                body);
                std::unique_lock<std::mutex> lock(interruptedMutex);
                interruptedWait.wait_for(lock, settings.createChannelRetryInterval);
            }
        }
    }
}