/** * @RDE_HEADER@ * LocalServer * $Id$ * $HeadURL$ * $Author$ */ // Own #include "local_server.h" #include // ESRI #include #include #include //Qt #include namespace Esri { namespace ArcGISRuntime { QString toString(const Esri::ArcGISRuntime::Error &value) { std::ostringstream stream; stream << "Esri::ArcGISRuntime::Error: " << " code=" << value.code() << ", domain=" << (int)value.domain() << ", extendedErrorType=" << (int)value.extendedErrorType() << ", message='" << value.message() << "'" << ", additionalMessage='" << value.additionalMessage() << "'"; return QString::fromStdString(stream.str()); } std::ostream &operator<< (std::ostream &stream, const Esri::ArcGISRuntime::Error &value) { stream << toString(value); return stream; } } // namespace ArcGISRuntime } // namespace Esri //---------------------------------------------------------------------------- namespace SituationMap { bool LocalServiceData::isEmpty() const { return m_svcUrl.isEmpty(); } void LocalServiceData::setSvcUrl(const QUrl &svcUrl) { m_svcUrl = svcUrl; } const QUrl &LocalServiceData::svcUrl() const { return m_svcUrl; } void LocalServiceData::setSync(bool sync) { m_sync = sync; } bool LocalServiceData::isSync() const { return m_sync; } //---------------------------------------------------------------------------- static QString toString(const Esri::ArcGISRuntime::LocalServerStatus &value) { switch (value) { case Esri::ArcGISRuntime::LocalServerStatus::Stopped: return QLatin1String("Stopped"); case Esri::ArcGISRuntime::LocalServerStatus::Starting: return QLatin1String("Starting"); case Esri::ArcGISRuntime::LocalServerStatus::Started: return QLatin1String("Started"); case Esri::ArcGISRuntime::LocalServerStatus::Stopping: return QLatin1String("Stopping"); case Esri::ArcGISRuntime::LocalServerStatus::Failed: return QLatin1String("Failed"); } // switch return QLatin1String("Esri-LocalServerStatusERROR"); } //----------------------------------------------------------------------------- class LocalServer::Private { public: Private() = default; ~Private() = default; // ESRI data: Esri::ArcGISRuntime::LocalServer *m_localServer = nullptr; // Own data: QMap m_gpServiceMap; QMap m_serviceSubLocationMap; QMap m_svcData; }; // class LocalServer::Private //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- LocalServer *LocalServer::instance() { static LocalServer *_instance = nullptr; if (_instance == nullptr) _instance = new LocalServer; return _instance; } //----------------------------------------------------------------------------- LocalServer::LocalServer() : BaseClass() , m_logger(getLogger("LocalServer")) , d(new Private) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; DEBUG_LOG(m_logger) << LOGFUNCTION << " installPath = " << " '" << Esri::ArcGISRuntime::LocalServer::installPath() << "'"; QString newInstallPath; QString user = QString::fromLocal8Bit( qgetenv("USER") ); if (user.compare(QLatin1Literal("ctc")) == 0) newInstallPath = SituationMap::getResourcePath() + QLatin1String("/localserver100.2_ctc/"); // USER ctc else newInstallPath = SituationMap::getResourcePath() + QLatin1String("/localserver100.2/"); // USER ctc_ws Esri::ArcGISRuntime::LocalServer::setInstallPath(newInstallPath); if (Esri::ArcGISRuntime::LocalServer::isInstallValid()) NOTICE_LOG(m_logger) << LOGFUNCTION << " installPath ok = " << " '" << Esri::ArcGISRuntime::LocalServer::installPath() << "'"; else FATAL_LOG(m_logger) << LOGFUNCTION << " installPath failed = " << " InstallPath = '" << Esri::ArcGISRuntime::LocalServer::installPath() << "'"; d->m_localServer = Esri::ArcGISRuntime::LocalServer::instance(); connect(d->m_localServer, &Esri::ArcGISRuntime::LocalServer::errorOccurred, this, &LocalServer::onLocalServerError); connect(d->m_localServer, &Esri::ArcGISRuntime::LocalServer::statusChanged, this, &LocalServer::onLocalServerStatusChanged); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } LocalServer::~LocalServer() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; this->stop(); delete d; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void LocalServer::start() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; d->m_localServer->start(); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void LocalServer::stop() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; stopAllLocalGeoprocessingServices(); d->m_localServer->stop(); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } bool LocalServer::isLocalServerStarted() const { return d->m_localServer->status() == Esri::ArcGISRuntime::LocalServerStatus::Started; } bool LocalServer::isLocalServerStopped() const { return d->m_localServer->status() == Esri::ArcGISRuntime::LocalServerStatus::Stopped; } bool LocalServer::setLocalGeoprocessingService(const QString &serviceName, const QString &packagePath, const QString &serviceSubLocation, bool sync) { TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " serviceName: '" << serviceName << "'" << " packagePath: '" << packagePath << "'" << " serviceSubLocation: '" << serviceSubLocation << "'"; if (d->m_gpServiceMap.contains(serviceName)) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName: '" << serviceName << "'" << " already provided"; return false; } QString localPackagePath = packagePath; { QFileInfo fileinfo(packagePath); if (!fileinfo.isAbsolute()) localPackagePath = SituationMap::getResourcePath() + QLatin1String("/gpk/") + packagePath; } QFileInfo fileinfo(localPackagePath); if (!fileinfo.exists()) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName: '" << serviceName << "'" << " packagePath does not exist: " << " localPackagePath: '" << localPackagePath << "'"; return false; } if (!fileinfo.isReadable()) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName: '" << serviceName << "'" << " packagePath is not readable: " << " localPackagePath: '" << localPackagePath << "'"; return false; } NOTICE_LOG(m_logger) << LOGFUNCTION << " create LocalGeoprocessingService: " << " localPackagePath: '" << localPackagePath << "'"; Esri::ArcGISRuntime::LocalGeoprocessingService *lgps = new Esri::ArcGISRuntime::LocalGeoprocessingService(localPackagePath, this); lgps->setObjectName(QString(QLatin1Literal("LocalGeoprocessingService-%1")).arg(serviceName)); if (sync) lgps->setServiceType(Esri::ArcGISRuntime::GeoprocessingServiceType::SynchronousExecute); // SynchronousExecute | AsynchronousSubmit | ... else lgps->setServiceType(Esri::ArcGISRuntime::GeoprocessingServiceType::AsynchronousSubmit); // SynchronousExecute | AsynchronousSubmit | ... connect(lgps, &Esri::ArcGISRuntime::LocalGeoprocessingService::errorOccurred, this, &LocalServer::onLGPSError); connect(lgps, &Esri::ArcGISRuntime::LocalGeoprocessingService::statusChanged, this, &LocalServer::onLGPSStatusChanged); // add to own management: d->m_gpServiceMap[serviceName] = lgps; d->m_serviceSubLocationMap[serviceName] = serviceSubLocation; TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " serviceName: '" << serviceName << "'" << " localPackagePath: '" << localPackagePath << "'" << " serviceSubLocation: '" << serviceSubLocation << "'"; return true; } bool LocalServer::startLocalGeoprocessingService(const QString &serviceName) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (!d->m_gpServiceMap.contains(serviceName)) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << " not found"; return false; } Esri::ArcGISRuntime::LocalGeoprocessingService *lgps = d->m_gpServiceMap[serviceName]; if (!lgps) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << ", no service"; return false; } if (isLocalServerStarted()) lgps->start(); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; return true; } bool LocalServer::stopLocalGeoprocessingService(const QString &serviceName) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (!d->m_gpServiceMap.contains(serviceName)) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << " not found"; return false; } Esri::ArcGISRuntime::LocalGeoprocessingService *lgps = d->m_gpServiceMap[serviceName]; if (!lgps) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << ", no service"; return false; } lgps->stop(); return true; } bool LocalServer::isLocalGeoprocessingServiceStarted(const QString &serviceName) const { if (!d->m_gpServiceMap.contains(serviceName)) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << " not found"; return false; } Esri::ArcGISRuntime::LocalGeoprocessingService *lgps = d->m_gpServiceMap[serviceName]; if (!lgps) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << ", no service"; return false; } return lgps->status() == Esri::ArcGISRuntime::LocalServerStatus::Started; } bool LocalServer::isLocalGeoprocessingServiceStopped(const QString &serviceName) const { if (!d->m_gpServiceMap.contains(serviceName)) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << " not found"; return false; } Esri::ArcGISRuntime::LocalGeoprocessingService *lgps = d->m_gpServiceMap[serviceName]; if (!lgps) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << ", no service"; return false; } return lgps->status() == Esri::ArcGISRuntime::LocalServerStatus::Stopped; } bool LocalServer::isLocalGeoprocessingServiceSynchronousExecute(const QString &serviceName) const { if (!d->m_gpServiceMap.contains(serviceName)) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << " not found"; return false; } Esri::ArcGISRuntime::LocalGeoprocessingService *lgps = d->m_gpServiceMap[serviceName]; if (!lgps) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << ", no service"; return false; } return lgps->serviceType() == Esri::ArcGISRuntime::GeoprocessingServiceType::SynchronousExecute; } bool LocalServer::isLocalGeoprocessingServiceAsynchronousSubmit(const QString &serviceName) const { if (!d->m_gpServiceMap.contains(serviceName)) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << " not found"; return false; } Esri::ArcGISRuntime::LocalGeoprocessingService *lgps = d->m_gpServiceMap[serviceName]; if (!lgps) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << ", no service"; return false; } return lgps->serviceType() == Esri::ArcGISRuntime::GeoprocessingServiceType::AsynchronousSubmit; } bool LocalServer::localGeoprocessingServiceData(const QString &serviceName, LocalServiceData &localServiceDataOut) const { if (!d->m_svcData.contains(serviceName)) { DEBUG_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << " not found"; return false; } localServiceDataOut = d->m_svcData[serviceName]; return true; } void LocalServer::startAllPendingLocalGeoprocessingServices() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; QMapIterator mapIt(d->m_gpServiceMap); while (mapIt.hasNext()) { mapIt.next(); const QString &serviceName = mapIt.key(); Esri::ArcGISRuntime::LocalGeoprocessingService *lgps = mapIt.value(); if (!lgps) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << ", no service"; continue; } if (lgps->status() == Esri::ArcGISRuntime::LocalServerStatus::Started) { DEBUG_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << ", already started, continue"; continue; } else lgps->start(); } // while TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void LocalServer::stopAllLocalGeoprocessingServices() { QMapIterator mapIt(d->m_gpServiceMap); while (mapIt.hasNext()) { mapIt.next(); const QString &serviceName = mapIt.key(); Esri::ArcGISRuntime::LocalGeoprocessingService *lgps = mapIt.value(); if (!lgps) { ERROR_LOG(m_logger) << LOGFUNCTION << " serviceName '" << serviceName << "'" << ", no service"; continue; } lgps->stop(); } // while TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void LocalServer::onLocalServerError(const Esri::ArcGISRuntime::Error &error) { ERROR_LOG(m_logger) << LOGFUNCTION << " EsriError occured: " << error; } void LocalServer::onLocalServerStatusChanged() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; NOTICE_LOG(m_logger) << LOGFUNCTION << " LocalServer: status changed to: " << toString(d->m_localServer->status()); emit localServerStatusChanged(); if (d->m_localServer->status() == Esri::ArcGISRuntime::LocalServerStatus::Started) { NOTICE_LOG(m_logger) << LOGFUNCTION << " LocalServer: STARTED" << " (url= '" << d->m_localServer->url().toString() << "')" << " (Esri::ArcGISRuntime::LocalServer->tempDataPath= '" << d->m_localServer->tempDataPath() << "')"; startAllPendingLocalGeoprocessingServices(); } TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void LocalServer::onLGPSError(const Esri::ArcGISRuntime::Error &error) { QString senderName; Esri::ArcGISRuntime::LocalGeoprocessingService *lgs = qobject_cast(sender()); if (lgs) senderName = lgs->objectName(); ERROR_LOG(m_logger) << LOGFUNCTION << " LocalGeoprocessingService -> EsriError occured: " << error; } void LocalServer::onLGPSStatusChanged() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; Esri::ArcGISRuntime::LocalGeoprocessingService *lgsp = qobject_cast(sender()); if (!lgsp) { ERROR_LOG(m_logger) << LOGFUNCTION << " qobject_cast failed to get sender!?"; return; } QString senderName = lgsp->objectName(); const QString &serviceName = d->m_gpServiceMap.key(lgsp); if (lgsp->status() == Esri::ArcGISRuntime::LocalServerStatus::Started) { NOTICE_LOG(m_logger) << LOGFUNCTION << " ***** LocalGeoprocessingService:" << " sender= '" << senderName << "'" << " status changed to: " << toString(lgsp->status()) << " url= '" << lgsp->url().toString() << "'"; LocalServiceData svcData; const QString &serviceSubLocation = d->m_serviceSubLocationMap[serviceName]; const QString &url = lgsp->url().toString() + QLatin1String("/") + serviceSubLocation; svcData.setSvcUrl(QUrl(url)); svcData.setSync(lgsp->serviceType() == Esri::ArcGISRuntime::GeoprocessingServiceType::SynchronousExecute); d->m_svcData[serviceName] = svcData; // store in own management emit localGeoprocessingServiceStatusChanged(serviceName); emit localGeoprocessingServiceStarted(serviceName, svcData); } NOTICE_LOG(m_logger) << LOGFUNCTION << " LocalGeoprocessingService:" << " sender= '" << senderName << "'" << " status changed to: " << toString(lgsp->status()); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } } // namespace SituationMap