Пример #1
0
void KaaChannelManager::clearChannelList()
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

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

    channels_.clear();
    mappedChannels_.clear();
}
Пример #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);
        }
    }
}
Пример #3
0
std::list<IDataChannelPtr> KaaChannelManager::getChannels()
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    std::list<IDataChannelPtr> channels(channels_.begin(), channels_.end());
    return channels;
}
Пример #4
0
void BootstrapManager::setTransport(IBootstrapTransport* transport)
{
    KAA_R_MUTEX_UNIQUE_DECLARE(lock, guard_);
    bootstrapTransport_ = dynamic_cast<BootstrapTransport*>(transport);
    if (bootstrapTransport_ != nullptr) {
        return;
    }
    throw KaaException("Bad bootstrap transport");
}
Пример #5
0
void BootstrapManager::useNextOperationsServerByAccessPointId(std::int32_t id)
{
    KAA_R_MUTEX_UNIQUE_DECLARE(lock, guard_);

    KAA_LOG_DEBUG(boost::format("Going to use new operations server: access_point=0x%X") % id);

    auto servers = getOPSByAccessPointId(id);
    if (servers.size() > 0) {
        notifyChannelManangerAboutServer(servers);
    } else {
        serverToApply.reset(new std::int32_t(id));
        bootstrapTransport_->sync();
    }
}
Пример #6
0
void KaaChannelManager::doShutdown()
{
    if (!isShutdown_) {
        isShutdown_ = true;

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

        for (auto& channel : mappedChannels_) {
            channel.second->shutdown();
        }
    }
}
Пример #7
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");
    }
}
Пример #8
0
IDataChannelPtr KaaChannelManager::getChannelByTransportType(TransportType type)
{
    KAA_MUTEX_LOCKING("mappedChannelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(mappedChannelLock, mappedChannelGuard_);
    KAA_MUTEX_LOCKED("mappedChannelGuard_");

    IDataChannelPtr channel = nullptr;
    auto it = mappedChannels_.find(type);

    if (it != mappedChannels_.end()) {
        channel = it->second;
    }

    return channel;
}
Пример #9
0
void KaaChannelManager::removeChannel(const std::string& id)
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    for (auto it = channels_.begin(); it != channels_.end(); ++it) {
        if ((*it)->getId() == id) {
            IDataChannelPtr channel = *it;
            channels_.erase(it);
            replaceChannel(channel);
            return;
        }
    }
}
Пример #10
0
bool KaaChannelManager::useChannelForType(const std::pair<TransportType, ChannelDirection>& type, IDataChannelPtr channel)
{
    if (type.second == ChannelDirection::UP || type.second == ChannelDirection::BIDIRECTIONAL) {
        KAA_LOG_INFO(boost::format("Channel (id='%1%') will be used for %2% transport type")
                            % channel->getId() % LoggingUtils::TransportTypeToString(type.first));

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

        mappedChannels_[type.first] = channel;
        return true;
    }
    return false;
}
Пример #11
0
void KaaChannelManager::replaceChannel(IDataChannelPtr channel)
{
    KAA_MUTEX_LOCKING("mappedChannelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(mappedChannelLock, mappedChannelGuard_);
    KAA_MUTEX_LOCKED("mappedChannelGuard_");

    for (const auto& channelInfo : mappedChannels_) {
        if (channelInfo.second == channel) {
            useNewChannelForType(channelInfo.first);
        }
    }

    KAA_UNLOCK(mappedChannelLock);

    channel->shutdown();
}
Пример #12
0
IDataChannelPtr KaaChannelManager::getChannel(const std::string& channelId)
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    IDataChannelPtr channel = nullptr;

    for (const auto& c : channels_) {
        if (c->getId() == channelId) {
            channel = c;
        }
    }

    return channel;
}
Пример #13
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);
    }
}
Пример #14
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;
}
Пример #15
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();
        }
    }
}
Пример #16
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_);
    }
}
Пример #17
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_);
    }
}
Пример #18
0
void BootstrapManager::onServerListUpdated(const std::vector<ProtocolMetaData>& operationsServers)
{
    if (operationsServers.empty()) {
        KAA_LOG_WARN("Received empty operations server list");
        FailoverStrategyDecision decision = failoverStrategy_->onFailover(Failover::NO_OPERATION_SERVERS);
        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;
		}
        return;
    }

    KAA_R_MUTEX_UNIQUE_DECLARE(lock, guard_);

    KAA_LOG_INFO(boost::format("Received %1% new operations servers") % operationsServers.size());

    lastOperationsServers_.clear();
    operationServers_.clear();

    for (const auto& serverMetaData : operationsServers) {
        ITransportConnectionInfoPtr connectionInfo(
                new GenericTransportInfo(ServerType::OPERATIONS, serverMetaData));

        auto& servers = operationServers_[serverMetaData.protocolVersionInfo];
        servers.push_back(connectionInfo);
    }

    for (auto& transportSpecificServers : operationServers_) {
        std::shuffle (transportSpecificServers.second.begin()
                    , transportSpecificServers.second.end()
                    , std::default_random_engine(std::chrono::high_resolution_clock::now().time_since_epoch().count()));

        lastOperationsServers_[transportSpecificServers.first] =
                                    transportSpecificServers.second.begin();
    }

    if (serverToApply) {
        auto servers = getOPSByAccessPointId(*serverToApply);
        if (!servers.empty()) {
            KAA_LOG_DEBUG(boost::format("Found %1% servers by access point id %2%")
                                            % servers.size() % *serverToApply);
            serverToApply.reset();
            notifyChannelManangerAboutServer(servers);
        }
    } else {
        for (const auto& transportSpecificServers : operationServers_) {
            channelManager_->onTransportConnectionInfoUpdated(transportSpecificServers.second.front());
        }
    }
}
Пример #19
0
void BootstrapManager::setChannelManager(IKaaChannelManager* manager)
{
    KAA_R_MUTEX_UNIQUE_DECLARE(lock, guard_);
    channelManager_ = manager;
}