520 lines
16 KiB
C++
Executable File
520 lines
16 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* LocalServer
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
// Own
|
|
#include "local_server.h"
|
|
#include <Common/resource_path.h>
|
|
|
|
|
|
// ESRI
|
|
#include <arcgis/Error.h>
|
|
|
|
#include <arcgis/LocalServer/LocalServer.h>
|
|
#include <arcgis/LocalServer/LocalGeoprocessingService.h>
|
|
|
|
|
|
//Qt
|
|
#include <QMap>
|
|
|
|
|
|
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<QString, Esri::ArcGISRuntime::LocalGeoprocessingService *> m_gpServiceMap;
|
|
QMap<QString, QString> m_serviceSubLocationMap;
|
|
|
|
|
|
QMap<QString, LocalServiceData> 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<QString, Esri::ArcGISRuntime::LocalGeoprocessingService *> 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<QString, Esri::ArcGISRuntime::LocalGeoprocessingService *> 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<Esri::ArcGISRuntime::LocalGeoprocessingService *>(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<Esri::ArcGISRuntime::LocalGeoprocessingService *>(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
|
|
|