Exemple #1
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());
    }
}
Exemple #2
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::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));
    }
}
Exemple #4
0
IPTransportInfo::IPTransportInfo(ITransportConnectionInfoPtr connectionInfo)
    : GenericTransportInfo(connectionInfo->getServerType(), ProtocolMetaData())
{
    if (!connectionInfo || connectionInfo->getConnectionInfo().empty()) {
        KAA_LOG_ERROR("Failed to create IP transport data: bad input data");
        throw KaaException("Bad connection data");
    }

    serverType_ = connectionInfo->getServerType();
    connectionData_ = connectionInfo->getConnectionInfo();
    accessPointId_ = connectionInfo->getAccessPointId();
    protocolId_ = connectionInfo->getTransportId();

    std::uint8_t *data = connectionData_.data();
    std::int32_t publicKeyLength = boost::asio::detail::socket_ops::network_to_host_long(*((int32_t *)data));
    data += sizeof(std::int32_t);

    publicKey_ = PublicKey(data, publicKeyLength);
    data += publicKeyLength;

    std::int32_t hostLength = boost::asio::detail::socket_ops::network_to_host_long(*((int32_t *)data));
    data += sizeof(std::int32_t);
    host_.assign(data, data + hostLength);
    data += hostLength;

    port_ = boost::asio::detail::socket_ops::network_to_host_long(*((int32_t *)data));

    std::ostringstream ss;
    ss << "http://" << host_ << ":" << port_;
    url_.assign(ss.str());

    if ((3 * sizeof(std::int32_t) + publicKeyLength + hostLength) > connectionData_.size()) {
        KAA_LOG_ERROR("Failed to create IP transport data: less size of input data than needed");
        throw KaaException("Bad connection data");
    }

    KAA_LOG_TRACE(boost::format("Create IP transport data: host=%1%, port=%2%, publicKeyLength=%3%") % host_% port_ % publicKey_.size());
}
void AbstractHttpChannel::setServer(ITransportConnectionInfoPtr server)
{
    if (server->getTransportId() != getTransportProtocolId()) {
        KAA_LOG_ERROR(boost::format("Channel [%1%] ignored invalid server info") % getId());
        return;
    }

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

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

    currentServer_ = std::make_shared<IPTransportInfo>(server);

    httpDataProcessor_.setEncoderDecoder(
            std::make_shared<RsaEncoderDecoder>(clientKeys_.getPublicKey(),
                                                clientKeys_.getPrivateKey(),
                                                currentServer_->getPublicKey(),
                                                context_));
}