Beispiel #1
0
void KaaChannelManager::onTransportConnectionInfoUpdated(ITransportConnectionInfoPtr connectionInfo) {
    if (isShutdown_) {
        KAA_LOG_WARN("Can't update server. Channel manager is down");
        return;
    }
    if (!connectionInfo) {
        KAA_LOG_WARN("Failed to update connection info: bad input data")
        throw KaaException("empty connection info pointer");
    }

    connectionInfo->resetFailedState();

    TransportProtocolId protocolId = connectionInfo->getTransportId();
    if (connectionInfo->getServerType() == ServerType::OPERATIONS) {
        KAA_MUTEX_LOCKING("lastOpsServersGuard_");
        KAA_MUTEX_UNIQUE_DECLARE(lastOpsServers_Lock, lastOpsServersGuard_);
        KAA_MUTEX_LOCKED("lastOpsServersGuard_");

        lastOpsServers_[protocolId] = connectionInfo;
    }

    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    for (auto& channel : channels_) {
        if (channel->getServerType() == connectionInfo->getServerType() && channel->getTransportProtocolId() == protocolId) {
            KAA_LOG_DEBUG(boost::format("Setting a new connection data for channel \"%1%\" %2%")
                        % channel->getId() % LoggingUtils::TransportProtocolIdToString(protocolId));
            channel->setServer(connectionInfo);
        }
    }
}
void DefaultOperationTcpChannel::sync(TransportType type)
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isShutdown_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: channel is shut down") % getId());
        return;
    }

    if (isPaused_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: channel is paused") % getId());
        return;
    }

    const auto& suppportedTypes = getSupportedTransportTypes();
    auto it = suppportedTypes.find(type);
    if (it == suppportedTypes.end() || it->second == ChannelDirection::DOWN) {
        KAA_LOG_ERROR(boost::format("Channel [%1%] ignore sync: unsupported transport type %2%")
                                                                        % getId()
                                                                        % LoggingUtils::toString(type));
        return;
    }

    if (!currentServer_) {
        KAA_LOG_DEBUG(boost::format("Channel [%1%] can't sync: server is null") % getId());
        return;
    }

    if (isFirstResponseReceived_) {
        KAA_MUTEX_UNLOCKING("channelGuard_");
        KAA_UNLOCK(lock);
        KAA_MUTEX_UNLOCKED("channelGuard_");

        std::map<TransportType, ChannelDirection> syncTypes;
        syncTypes.insert(std::make_pair(type, it->second));
        for (const auto& typeIt : suppportedTypes) {
            if (typeIt.first != type) {
                syncTypes.insert(std::make_pair(typeIt.first, ChannelDirection::DOWN));
            }
        }

        boost::system::error_code errorCode = sendKaaSync(syncTypes);
        if (errorCode) {
            KAA_LOG_ERROR(boost::format("Channel [%1%] failed to sync: %2%")
                                                                % getId()
                                                                % errorCode.message());
            onServerFailed();
        }
    } else {
        KAA_LOG_DEBUG(boost::format("Channel [%1%] can't sync: waiting for CONNACK + KAASYNC") % getId());
        isPendingSyncRequest_ = true;
    }
}
Beispiel #3
0
void EventManager::registerEventFamily(IEventFamily* eventFamily)
{
    if (eventFamily) {
        auto it = eventFamilies_.insert(eventFamily);
        if (!it.second) {
            KAA_LOG_WARN("Failed to register event family: already exists");
        }
    } else {
        KAA_LOG_WARN("Failed to register event family: bad input data");
    }
}
Beispiel #4
0
void KaaChannelManager::onServerFailed(ITransportConnectionInfoPtr connectionInfo) {
    if (isShutdown_) {
        KAA_LOG_WARN("Can't update server. Channel manager is down");
        return;
    }
    if (!connectionInfo) {
        KAA_LOG_WARN("Failed to process server failure: bad input data")
        throw KaaException("empty connection info pointer");
    }

    if (connectionInfo->isFailedState()) {
        KAA_LOG_DEBUG("Connection already failed. Ignoring connection failover!");
        return;
    } else {
        connectionInfo->setFailedState();
    }

    if (connectionInfo->getServerType() == ServerType::BOOTSTRAP) {
        ITransportConnectionInfoPtr nextConnectionInfo = getNextBootstrapServer(connectionInfo->getTransportId(), false);
        if (nextConnectionInfo) {
            onTransportConnectionInfoUpdated(nextConnectionInfo);
        } else {
            FailoverStrategyDecision decision = failoverStrategy_->onFailover(Failover::BOOTSTRAP_SERVERS_NA);
            switch (decision.getAction()) {
                 case FailoverStrategyAction::NOOP:
                     KAA_LOG_WARN("No operation is performed according to failover strategy decision.");
                     break;
                 case FailoverStrategyAction::RETRY:
                 {
                     std::size_t period = decision.getRetryPeriod();
                     KAA_LOG_WARN(boost::format("Attempt to reconnect to first bootstrap server will be made in %1% secs "
                             "according to failover strategy decision.") % period);
                     bsTransportId_ = connectionInfo->getTransportId();
                     retryTimer_.stop();
                     retryTimer_.start(period, [&]
                         {
                             onTransportConnectionInfoUpdated(getNextBootstrapServer(bsTransportId_, true));
                         });
                     break;
                 }
                 case FailoverStrategyAction::STOP_APP:
                     KAA_LOG_WARN("Stopping application according to failover strategy decision!");
                     exit(EXIT_FAILURE);
                     break;
                 default:
                    break;
             }
        }
    } else {
        bootstrapManager_.useNextOperationsServer(connectionInfo->getTransportId());
    }
}
Beispiel #5
0
void BootstrapManager::useNextOperationsServer(const TransportProtocolId& protocolId)
{
    KAA_R_MUTEX_UNIQUE_DECLARE(lock, guard_);

    auto lastServerIt = lastOperationsServers_.find(protocolId);
    auto serverIt = operationServers_.find(protocolId);

    if (lastServerIt != lastOperationsServers_.end() && serverIt != operationServers_.end()) {
        OperationsServers::iterator nextOperationIterator = (lastServerIt->second)+1;
        if (nextOperationIterator != serverIt->second.end()) {
            KAA_LOG_INFO(boost::format("New server [%1%] will be user for %2%")
                                            % (*nextOperationIterator)->getAccessPointId()
                                            % LoggingUtils::TransportProtocolIdToString(protocolId));
            lastOperationsServers_[protocolId] = nextOperationIterator;
            if (channelManager_ != nullptr) {
                channelManager_->onTransportConnectionInfoUpdated(*(nextOperationIterator));
            } else {
                KAA_LOG_ERROR("Can not process server change. Channel manager was not specified");
            }
        } else {
            KAA_LOG_WARN(boost::format("Failed to find server for channel %1%.")
                                            % LoggingUtils::TransportProtocolIdToString(protocolId));

            FailoverStrategyDecision decision = failoverStrategy_->onFailover(Failover::OPERATION_SERVERS_NA);
            switch (decision.getAction()) {
                case FailoverStrategyAction::NOOP:
                    KAA_LOG_WARN("No operation is performed according to failover strategy decision.");
                    break;
                case FailoverStrategyAction::RETRY:
                {
                    std::size_t period = decision.getRetryPeriod();
                    KAA_LOG_WARN(boost::format("Attempt to receive operations server list will be made in %1% secs "
                            "according to failover strategy decision.") % period);
                    retryTimer_.stop();
                    retryTimer_.start(period, [&] { receiveOperationsServerList(); });
                    break;
                }
                case FailoverStrategyAction::STOP_APP:
                    KAA_LOG_WARN("Stopping application according to failover strategy decision!");
                    exit(EXIT_FAILURE);
                    break;
                default:
                    break;
            }
        }
    } else {
        throw KaaException("There are no available servers at the time");
    }
}
Beispiel #6
0
void LogCollector::onLogUploadResponse(const LogSyncResponse& response)
{
    KAA_MUTEX_LOCKING("storageGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(storageGuardLock, storageGuard_);
    KAA_MUTEX_LOCKED("storageGuard_");

    if (!response.deliveryStatuses.is_null()) {
        const auto& deliveryStatuses = response.deliveryStatuses.get_array();
        for (const auto& status : deliveryStatuses) {
            if (!removeDeliveryTimeout(status.requestId)) {
                continue;
            }

            if (status.result == SyncResponseResultType::SUCCESS) {
                KAA_LOG_INFO(boost::format("Logs (requestId %ld) successfully delivered") % status.requestId);
                storage_->removeRecordBlock(status.requestId);
            } else {
                storage_->notifyUploadFailed(status.requestId);

                KAA_MUTEX_UNLOCKING("storageGuard_");
                KAA_UNLOCK(storageGuardLock);
                KAA_MUTEX_UNLOCKED("storageGuard_");

                if (!status.errorCode.is_null()) {
                    auto errocCode = status.errorCode.get_LogDeliveryErrorCode();
                    KAA_LOG_WARN(boost::format("Logs (requestId %ld) failed to deliver (error %d)")
                                            % status.requestId % (int)errocCode);

                    executorContext_.getCallbackExecutor().add([this, errocCode] ()
                            {
                                uploadStrategy_->onFailure(*this, errocCode);
                            });
                } else {
                    KAA_LOG_WARN("Log delivery failed, but no error code received");
                }

                KAA_MUTEX_LOCKING("storageGuard_");
                KAA_LOCK(storageGuardLock);
                KAA_MUTEX_LOCKED("storageGuard_");
            }
        }
    }

    KAA_MUTEX_UNLOCKING("storageGuard_");
    KAA_UNLOCK(storageGuardLock);
    KAA_MUTEX_UNLOCKED("storageGuard_");

    processLogUploadDecision(uploadStrategy_->isUploadNeeded(storage_->getStatus()));
}
Beispiel #7
0
void AbstractHttpChannel::sync(TransportType type)
{
    const auto& supportedTypes = getSupportedTransportTypes();
    auto it = supportedTypes.find(type);
    if (it == supportedTypes.end() || it->second == ChannelDirection::DOWN) {
        KAA_LOG_ERROR(boost::format("Channel [%1%] unsupported transport type '%2%'")
                                                        % getId()
                                                        % LoggingUtils::toString(type));
        return;
    }

    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (!currentServer_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: server is null") % getId());
        return;
    }

    processTypes(std::map<TransportType, ChannelDirection>({ { type, it->second } })
#ifdef KAA_THREADSAFE
               , lock
#endif
                );

}
Beispiel #8
0
static bool is_timeout(kaa_log_collector_t *self)
{
    KAA_RETURN_IF_NIL2(self, self->timeouts, false);

    bool is_timeout = false;
    kaa_time_t now = KAA_TIME();

    kaa_list_node_t *it = kaa_list_begin(self->timeouts);
    while (it) {
        timeout_info_t *info = (timeout_info_t *)kaa_list_get_data(it);
        if (now >= info->timeout) {
            KAA_LOG_WARN(self->logger, KAA_ERR_TIMEOUT, "Log delivery timeout occurred (bucket_id %u)", info->log_bucket_id);
            is_timeout = true;
            break;
        }
        it = kaa_list_next(it);
    }

    if (is_timeout) {
        it = kaa_list_begin(self->timeouts);
        while (it) {
            timeout_info_t *info = (timeout_info_t *)kaa_list_get_data(it);
            ext_log_storage_unmark_by_bucket_id(self->log_storage_context, info->log_bucket_id);
            it = kaa_list_next(it);
        }

        kaa_list_clear(self->timeouts, NULL);
        ext_log_upload_strategy_on_timeout(self->log_upload_strategy_context);
    }

    return is_timeout;
}
Beispiel #9
0
std::int32_t EventManager::findEventListeners(const std::list<std::string>& eventFQNs, IFetchEventListenersPtr listener)
{
    if (eventFQNs.empty() || !listener) {
        KAA_LOG_WARN("Failed to add event listeners request: bad input data");
        throw KaaException("Bad event listeners data");
    }

    std::int32_t requestId = UuidGenerator::generateRandomInt();

    std::shared_ptr<EventListenersInfo> info(new EventListenersInfo);
    info->eventFQNs_ = eventFQNs;
    info->listener_ = listener;

    {
        KAA_MUTEX_LOCKING("eventListenersGuard_");
        KAA_MUTEX_UNIQUE_DECLARE(eventListenersLock, eventListenersGuard_);
        KAA_MUTEX_LOCKED("eventListenersGuard_");

        eventListenersRequests_.insert(std::make_pair(requestId, info));
        KAA_MUTEX_UNLOCKED("eventListenersGuard_");
    }

    KAA_LOG_TRACE("Added event listeners resolving request");

    doSync();

    return requestId;
}
void DefaultOperationTcpChannel::onConnack(const ConnackMessage& message)
{
    KAA_LOG_DEBUG(boost::format("Channel [%1%] received Connack: status %2%")
                                                            % getId()
                                                            % message.getMessage());

    switch (message.getReturnCode()) {
        case ConnackReturnCode::ACCEPTED:
            break;
        case ConnackReturnCode::REFUSE_VERIFICATION_FAILED:
        case ConnackReturnCode::REFUSE_BAD_CREDENTIALS:
            KAA_LOG_WARN(boost::format("Channel [%1%] failed server authentication: %2%")
                                            % getId()
                                            % ConnackMessage::returnCodeToString(message.getReturnCode()));

            onServerFailed(KaaFailoverReason::ENDPOINT_NOT_REGISTERED);

            break;
        default:
            KAA_LOG_ERROR(boost::format("Channel [%1%] failed to connect to server: %2%")
                                                                    % getId()
                                                                    % message.getMessage());
            onServerFailed(KaaFailoverReason::CURRENT_OPERATIONS_SERVER_NA);
            break;
    }
}
Beispiel #11
0
bool LogCollector::isDeliveryTimeout()
{

    KAA_MUTEX_LOCKING("timeoutsGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(timeoutsGuardLock, timeoutsGuard_);
    KAA_MUTEX_LOCKED("timeoutsGuard_");

    auto now = clock_t::now();

    IDataChannelPtr logChannel = channelManager_->getChannelByTransportType(TransportType::LOGGING);
    std::int32_t currentAccessPointId  = 0;
    if (logChannel && logChannel->getServer()) {
        currentAccessPointId = logChannel->getServer()->getAccessPointId();
    }

    bool isTimeout = false;
    timeoutAccessPointId_ = 0;

    for (const auto& request : timeouts_) {
        if (now >= request.second.getTimeoutTime()) {
            KAA_LOG_WARN(boost::format("Log delivery timeout detected, bucket id %li") % request.first);
            isTimeout = true;
            timeoutAccessPointId_ = request.second.getTransportAccessPointId();
            // Check if current access point already has timeout
            if (timeoutAccessPointId_ == currentAccessPointId) {
                break;
            }
        }
    }

    return isTimeout;
}
void DefaultOperationTcpChannel::onServerFailed(KaaFailoverReason failoverReason)
{
    if (isFailoverInProgress_) {
        KAA_LOG_TRACE(boost::format("Channel [%1%] failover processing already in progress. "
                                    "Ignore '%2%' failover")
                                                    % getId()
                                                    % LoggingUtils::toString(failoverReason));
        return;
    }

    isFailoverInProgress_ = true;

    closeConnection();

    KaaFailoverReason finalFailoverReason = failoverReason;
    if (failoverReason == KaaFailoverReason::CURRENT_OPERATIONS_SERVER_NA) {
        if (connectivityChecker_ && !connectivityChecker_->checkConnectivity()) {
            KAA_LOG_INFO(boost::format("Channel [%1%] detected loss of connectivity") % getId());
            finalFailoverReason = KaaFailoverReason::NO_CONNECTIVITY;
        }
    }

    auto server = std::dynamic_pointer_cast<ITransportConnectionInfo, IPTransportInfo>(currentServer_);

    KAA_LOG_WARN(boost::format("Channel [%1%] detected '%2%' failover for %3%")
                                                         % getId()
                                                         % LoggingUtils::toString(finalFailoverReason)
                                                         % LoggingUtils::toString(*server));

    channelManager_.onServerFailed(server, finalFailoverReason);
}
Beispiel #13
0
void KaaChannelManager::addChannel(IDataChannelPtr channel)
{
    if (isShutdown_) {
        KAA_LOG_WARN("Can't set channel. Channel manager is down");
        return;
    }
    if (!channel) {
        KAA_LOG_WARN("Failed to add channel: bad input data")
        throw KaaException("empty channel pointer");
    }
    if (isPaused_) {
        channel->pause();
    }

    if (addChannelToList(channel)) {
        useNewChannel(channel);
    }
}
void DefaultOperationTcpChannel::setServer(ITransportConnectionInfoPtr server)
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isShutdown_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] ignore new server: channel is shut down") % getId());
        return;
    }

    if (server->getTransportId() != getTransportProtocolId()) {
        KAA_LOG_WARN(boost::format("Channel [%1%] ignore new server: unsupported transport %2%")
                                                                        % getId()
                                                                        % LoggingUtils::toString(server->getTransportId()));
        return;
    }

    KAA_LOG_TRACE(boost::format("Channel [%1%] preparing to use new server %2%")
                                                            % getId()
                                                            % LoggingUtils::toString(*server));

    currentServer_ = std::make_shared<IPTransportInfo>(server);
    encDec_ = std::make_shared<RsaEncoderDecoder>(clientKeys_.getPublicKey(),
                                                  clientKeys_.getPrivateKey(),
                                                  currentServer_->getPublicKey(),
                                                  context_);

    isFailoverInProgress_ = false;

    if (!isPaused_) {
        KAA_MUTEX_UNLOCKING("channelGuard_");
        KAA_UNLOCK(lock);
        KAA_MUTEX_UNLOCKED("channelGuard_");

        closeConnection();

        KAA_LOG_TRACE(boost::format("Channel [%1%] scheduling open connection")
                                                                        % getId());

        io_.post(std::bind(&DefaultOperationTcpChannel::openConnection, this));
    }
}
Beispiel #15
0
void AbstractHttpChannel::onServerFailed(KaaFailoverReason reason)
{
    auto server = std::dynamic_pointer_cast<ITransportConnectionInfo, IPTransportInfo>(currentServer_);

    KAA_LOG_WARN(boost::format("Channel [%1%] detected '%2%' failover for %3%")
                                                         % getId()
                                                         % LoggingUtils::toString(reason)
                                                         % LoggingUtils::toString(*server));

    channelManager_.onServerFailed(server, reason);
}
Beispiel #16
0
kaa_error_t kaa_configuration_manager_handle_server_sync(kaa_configuration_manager_t *self
                                                       , kaa_platform_message_reader_t *reader
                                                       , uint32_t extension_options
                                                       , size_t extension_length)
{
    KAA_RETURN_IF_NIL2(self, reader, KAA_ERR_BADPARAM);

    KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Received configuration server sync: options %u, payload size %u", extension_options, extension_length);

    if (extension_length >= sizeof(uint32_t)) {
        self->status->config_seq_n = KAA_NTOHL(*((uint32_t *) reader->current));
        KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Configuration state sequence number is '%d'", self->status->config_seq_n);
        reader->current += sizeof(uint32_t);
        if (extension_options & KAA_CONFIGURATION_BODY_PRESENT) {
            uint32_t body_size = KAA_NTOHL(*((uint32_t *) reader->current));
            reader->current += sizeof(uint32_t);
            KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Received configuration body, size '%u' ", body_size);
            const char* body = reader->current;
            kaa_error_t error = kaa_platform_message_skip(reader, kaa_aligned_size_get(body_size));
            if (error) {
                 KAA_LOG_ERROR(self->logger, error, "Failed to read configuration body, size %u", body_size);
                 return error;
            }

#if KAA_CONFIGURATION_DELTA_SUPPORT

#else
            if (self->root_record)
                self->root_record->destroy(self->root_record);

            self->root_record = kaa_configuration_manager_deserialize(body, body_size);
            if (!self->root_record) {
                KAA_LOG_ERROR(self->logger, KAA_ERR_READ_FAILED, "Failed to deserialize configuration body, size %u", body_size);
                return KAA_ERR_READ_FAILED;
            }

            kaa_error_t err = ext_calculate_sha_hash(body, body_size, self->configuration_hash);
            if (err) {
                KAA_LOG_WARN(self->logger, err, "Failed to calculate configuration body hash");
                return err;
            }
            ext_configuration_store(body, body_size);
#endif
            if (self->root_receiver.on_configuration_updated)
                self->root_receiver.on_configuration_updated(self->root_receiver.context, self->root_record);

            kaa_transport_channel_interface_t *channel =
                    kaa_channel_manager_get_transport_channel(self->channel_manager, configuration_sync_services[0]);
            if (channel)
                channel->sync_handler(channel->context, configuration_sync_services, 1);
        }
    }
    return KAA_ERR_NONE;
}
Beispiel #17
0
void LogCollector::switchAccessPoint()
{
    IDataChannelPtr logChannel = channelManager_->getChannelByTransportType(TransportType::LOGGING);
    if (logChannel && logChannel->getServer()) {
        if (timeoutAccessPointId_ == logChannel->getServer()->getAccessPointId()) {
            KAA_LOG_WARN("Try to switch to another Operations server...");
            channelManager_->onServerFailed(logChannel->getServer());
        }
    } else {
        KAA_LOG_ERROR("Can't find LOGGING data channel");
    }
}
Beispiel #18
0
void KaaChannelManager::setConnectivityChecker(ConnectivityCheckerPtr checker) {
    if (isShutdown_) {
        KAA_LOG_WARN("Can't set connectivity checker. Channel manager is down");
        return;
    }

    if (!checker) {
        KAA_LOG_WARN("Connectivity checker is null");
        return;
    }

    connectivityChecker_ = checker;

    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    for (auto& channel : channels_) {
        channel->setConnectivityChecker(connectivityChecker_);
    }
}
Beispiel #19
0
void KaaChannelManager::setFailoverStrategy(IFailoverStrategyPtr strategy) {
    if (isShutdown_) {
        KAA_LOG_WARN("Can't set failover strategy. Channel manager is down");
        return;
    }

    if (!strategy) {
        KAA_LOG_WARN("Failover strategy is null");
        return;
    }

    failoverStrategy_ = strategy;

    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    bootstrapManager_.setFailoverStrategy(failoverStrategy_);
    for (auto& channel : channels_) {
        channel->setFailoverStrategy(failoverStrategy_);
    }
}
Beispiel #20
0
void KaaChannelManager::setChannel(TransportType type, IDataChannelPtr channel)
{
    if (isShutdown_) {
        KAA_LOG_WARN("Can't set channel. Channel manager is down");
        return;
    }
    if (!channel) {
        KAA_LOG_WARN("Failed to set channel: bad input data")
        throw KaaException("empty channel pointer");
    }
    const auto &types = channel->getSupportedTransportTypes();
    auto res = types.find(type);
    if (res == types.end() || !useChannelForType(*res, channel)) {
        KAA_LOG_WARN(boost::format("Can't apply Channel (id='%1%') for transport %2%")
                        % channel->getId()
                        % LoggingUtils::TransportTypeToString(type));
        throw KaaException("invalid channel or transport type");
    }
    if (isPaused_) {
        channel->pause();
    }
    addChannelToList(channel);
}
void DefaultOperationTcpChannel::syncAll()
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isShutdown_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: channel is shut down") % getId());
        return;
    }

    if (isPaused_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: channel is on oause") % getId());
        return;
    }

    if (!currentServer_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: server is null") % getId());
        return;
    }

    if (isFirstResponseReceived_) {
        KAA_MUTEX_UNLOCKING("channelGuard_");
        KAA_UNLOCK(lock);
        KAA_MUTEX_UNLOCKED("channelGuard_");

        boost::system::error_code errorCode = sendKaaSync(getSupportedTransportTypes());
        if (errorCode) {
            KAA_LOG_ERROR(boost::format("Channel [%1%]. Failed to sync: %2%") % getId() % errorCode.message());
            onServerFailed();
        }
    } else {
        KAA_LOG_DEBUG(boost::format("Can't sync channel [%1%]. Waiting for CONNACK message + KAASYNC message") % getId());
        isPendingSyncRequest_ = true;
    }
}
Beispiel #22
0
void EventManager::onEventFromServer(const std::string& eventClassFQN, const std::vector<std::uint8_t>& data,
                                     const std::string& source)
{
    if (eventClassFQN.empty()) {
        KAA_LOG_WARN("Failed to process incoming event: bad input data");
        return;
    }

    bool isProcessed = false;

    for (auto* family : eventFamilies_) {
        const auto& list = family->getSupportedEventClassFQNs();
        auto it = std::find(list.begin(), list.end(), eventClassFQN);
        if (it != list.end()) {
            KAA_LOG_TRACE(boost::format("Processing event for %1%") % eventClassFQN);
            family->onGenericEvent(eventClassFQN, data, source);
            isProcessed = true;
        }
    }

    if (!isProcessed) {
        KAA_LOG_WARN(boost::format("Event '%1%' wasn't processed: could not find appropriate family") % eventClassFQN);
    }
}
void DefaultOperationTcpChannel::resume()
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isShutdown_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't resume: channel is shut down") % getId());
        return;
    }

    if (isPaused_) {
        isPaused_ = false;
        io_.post(std::bind(&DefaultOperationTcpChannel::openConnection, this));
    }
}
Beispiel #24
0
void KaaChannelManager::removeChannel(IDataChannelPtr channel)
{

    if (!channel) {
        KAA_LOG_WARN("Failed to remove channel: bad input data")
        throw KaaException("empty channel pointer");
    }

    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (channels_.erase(channel)) {
        replaceChannel(channel);
    }
}
void DefaultOperationTcpChannel::onReadEvent(const boost::system::error_code& err)
{
    if (!err) {
        std::ostringstream responseStream;
        responseStream << responseBuffer_.get();
        const auto& responseStr = responseStream.str();
        try {
            if (responseStr.empty()) {
                 KAA_LOG_ERROR(boost::format("Channel [%1%] no data read from socket") % getId());
            } else {
                responseProcessor.processResponseBuffer(responseStr.data(), responseStr.size());
            }
        } catch (const TransportRedirectException& exception) {
            KAA_LOG_INFO(boost::format("Channel [%1%] received REDIRECT response") % getId());
            return;
        } catch (const KaaException& exception) {
            KAA_LOG_ERROR(boost::format("Channel [%1%] failed to process data: %2%") % getId() % exception.what());
            onServerFailed();
        }
    } else {
        KAA_LOG_WARN(boost::format("Channel [%1%] socket error: %2%") % getId() % err.message());

        KAA_MUTEX_LOCKING("channelGuard_");
        KAA_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
        KAA_MUTEX_LOCKED("channelGuard_");

        if (err != boost::asio::error::operation_aborted && isConnected_) {
            KAA_MUTEX_UNLOCKING("channelGuard_");
            KAA_UNLOCK(channelLock);
            KAA_MUTEX_UNLOCKED("channelGuard_")

            onServerFailed();
            return;
        } else {
            KAA_LOG_DEBUG(boost::format("Channel [%1%] socket operations aborted") % getId());
            return;
        }
    }

    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isConnected_) {
        readFromSocket();
    }
}
Beispiel #26
0
void AbstractHttpChannel::syncAll()
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (!currentServer_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: server is null") % getId());
        return;
    }

    processTypes(getSupportedTransportTypes()
#ifdef KAA_THREADSAFE
               , lock
#endif
                );
}
Beispiel #27
0
bool KaaChannelManager::addChannelToList(IDataChannelPtr channel)
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    auto res = channels_.insert(channel);

    if (res.second) {
    	channel->setFailoverStrategy(failoverStrategy_);
        channel->setConnectivityChecker(connectivityChecker_);

        ITransportConnectionInfoPtr connectionInfo;

        TransportProtocolId protocolId = channel->getTransportProtocolId();
        if (channel->getServerType() == ServerType::BOOTSTRAP) {
            connectionInfo = getCurrentBootstrapServer(protocolId);
        } else {
            KAA_MUTEX_LOCKING("lastOpsServersGuard_");
            KAA_MUTEX_UNIQUE_DECLARE(lastOpsServers_Lock, lastOpsServersGuard_);
            KAA_MUTEX_LOCKED("lastOpsServersGuard_");

            auto it = lastOpsServers_.find(channel->getTransportProtocolId());
            if (it != lastOpsServers_.end()) {
                connectionInfo = it->second;
            }
        }

        if (connectionInfo) {
            KAA_LOG_DEBUG(boost::format("Setting a new server for channel \"%1%\" %2%")
                        % channel->getId() % LoggingUtils::TransportProtocolIdToString(protocolId));
            channel->setServer(connectionInfo);
        } else {
            if (channel->getServerType() == ServerType::BOOTSTRAP) {
                KAA_LOG_WARN(boost::format("Failed to find bootstrap server for channel \"%1%\" %2%")
                            % channel->getId() % LoggingUtils::TransportProtocolIdToString(protocolId));
            } else {
                KAA_LOG_INFO(boost::format("Failed to find operations server for channel \"%1%\" %2%")
                            % channel->getId() % LoggingUtils::TransportProtocolIdToString(protocolId));
            }
        }
    }

    return res.second;
}
Beispiel #28
0
void KaaChannelManager::resume()
{
    if (isShutdown_) {
        KAA_LOG_WARN("Can't resume. Channel manager is down");
        return;
    }
    if (isPaused_) {
        isPaused_ = false;

        KAA_MUTEX_LOCKING("mappedChannelGuard_");
        KAA_R_MUTEX_UNIQUE_DECLARE(mappedChannelLock, mappedChannelGuard_);
        KAA_MUTEX_LOCKED("mappedChannelGuard_");

        for (auto& channel : mappedChannels_) {
            channel.second->resume();
        }
    }
}
void DefaultOperationTcpChannel::pause()
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isShutdown_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't pause: channel is shut down") % getId());
        return;
    }

    if (!isPaused_) {
        isPaused_ = true;
        KAA_MUTEX_UNLOCKING("channelGuard_");
        KAA_UNLOCK(lock);
        KAA_MUTEX_UNLOCKED("channelGuard_");
        closeConnection();
    }
}
Beispiel #30
0
void LogCollector::processLogUploadDecision(LogUploadStrategyDecision decision)
{
    switch (decision) {
    case LogUploadStrategyDecision::UPLOAD: {
        KAA_LOG_DEBUG("Going to upload logs");
        doSync();
        break;
    }
    case LogUploadStrategyDecision::NOOP:
        KAA_LOG_TRACE("Nothing to do now");
        if (storage_->getStatus().getRecordsCount() > 0) {
            startLogUploadCheckTimer();
        }
        break;
    default:
        KAA_LOG_WARN("Unknown log upload decision");
        break;
    }
}