void terrama2::services::view::core::makeView(ViewId viewId, std::shared_ptr< terrama2::services::view::core::ViewLogger > logger, std::weak_ptr<DataManager> weakDataManager) { auto dataManager = weakDataManager.lock(); if(!dataManager.get()) { TERRAMA2_LOG_ERROR() << QObject::tr("Unable to access DataManager"); return; } try { RegisterId logId = 0; if(logger.get()) logId = logger->start(viewId); TERRAMA2_LOG_DEBUG() << QObject::tr("Starting view %1 generation.").arg(viewId); auto lock = dataManager->getLock(); auto viewPtr = dataManager->findView(viewId); if(viewPtr->dataSeriesList.size() != viewPtr->filtersPerDataSeries.size()) { QString message = QObject::tr("View %1 do not have the right number of filters for data.").arg(viewId); if(logger.get()) logger->error(message.toStdString(), viewId); TERRAMA2_LOG_ERROR() << message; throw Exception() << ErrorDescription(message); } std::vector<std::unordered_map<terrama2::core::DataSetPtr, terrama2::core::DataSetSeries>> seriesList; for(auto dataSeriesId : viewPtr->dataSeriesList) { terrama2::core::DataSeriesPtr inputDataSeries = dataManager->findDataSeries(dataSeriesId); terrama2::core::DataProviderPtr inputDataProvider = dataManager->findDataProvider(inputDataSeries->dataProviderId); auto dataAccessor = terrama2::core::DataAccessorFactory::getInstance().make(inputDataProvider, inputDataSeries); terrama2::core::Filter filter(viewPtr->filtersPerDataSeries.at(dataSeriesId)); std::unordered_map<terrama2::core::DataSetPtr, terrama2::core::DataSetSeries > series = dataAccessor->getSeries(filter); seriesList.push_back(series); } lock.unlock(); if(seriesList.size() > 0) { drawSeriesList(viewId, logger, seriesList, viewPtr->resolutionWidth, viewPtr->resolutionHeight, viewPtr->srid); TERRAMA2_LOG_INFO() << QObject::tr("View %1 generated successfully.").arg(viewId); } else { QString message = QObject::tr("View %1 has no associated data to be generated.").arg(viewId); if(logger.get()) logger->info(message.toStdString(), viewId); TERRAMA2_LOG_INFO() << message; } if(logger.get()) logger->done(terrama2::core::TimeUtils::nowUTC(), logId); } catch(const terrama2::Exception& e) { TERRAMA2_LOG_ERROR() << boost::get_error_info<terrama2::ErrorDescription>(e) << std::endl; TERRAMA2_LOG_INFO() << QObject::tr("Build of view %1 finished with error(s).").arg(viewId); } catch(const boost::exception& e) { TERRAMA2_LOG_ERROR() << boost::get_error_info<terrama2::ErrorDescription>(e); TERRAMA2_LOG_INFO() << QObject::tr("Build of view %1 finished with error(s).").arg(viewId); } catch(const std::exception& e) { TERRAMA2_LOG_ERROR() << e.what(); TERRAMA2_LOG_INFO() << QObject::tr("Build of view %1 finished with error(s).").arg(viewId); } catch(...) { TERRAMA2_LOG_ERROR() << QObject::tr("Unkown error."); TERRAMA2_LOG_INFO() << QObject::tr("Build of view %1 finished with error(s).").arg(viewId); } }
void terrama2::services::view::core::Service::viewJob(const terrama2::core::ExecutionPackage& executionPackage, std::shared_ptr<ViewLogger> logger, std::weak_ptr<DataManager> weakDataManager) { auto dataManager = weakDataManager.lock(); if(!dataManager.get()) { TERRAMA2_LOG_ERROR() << QObject::tr("Unable to access DataManager"); notifyWaitQueue(executionPackage.processId); sendProcessFinishedSignal(executionPackage.processId, executionPackage.executionDate, false); return; } RegisterId logId = executionPackage.registerId; ViewId viewId = executionPackage.processId; std::string viewName = ""; QJsonObject jsonAnswer; try { TERRAMA2_LOG_DEBUG() << QObject::tr("Starting view %1 generation.").arg(viewId); auto mapsServer = MapsServerFactory::getInstance().make(mapsServerUri_, "GEOSERVER"); ///////////////////////////////////////////////////////////////////////// // aquiring metadata auto lock = dataManager->getLock(); auto viewPtr = dataManager->findView(viewId); viewName = viewPtr->viewName; terrama2::core::DataSeriesPtr inputDataSeries = dataManager->findDataSeries(viewPtr->dataSeriesID); terrama2::core::DataProviderPtr inputDataProvider = dataManager->findDataProvider(inputDataSeries->dataProviderId); lock.unlock(); ///////////////////////////////////////////////////////////////////////// auto processingStartTime = terrama2::core::TimeUtils::nowUTC(); QJsonObject mapsServerAnswer = mapsServer->generateLayers(viewPtr, inputDataSeries, inputDataProvider, dataManager, logger, logId); TERRAMA2_LOG_INFO() << tr("View %1(%2) generated successfully.").arg(QString::fromStdString(viewName)).arg(viewId); auto processingEndTime = terrama2::core::TimeUtils::nowUTC(); logger->setStartProcessingTime(processingStartTime, executionPackage.registerId); logger->setEndProcessingTime(processingEndTime, executionPackage.registerId); logger->result(ViewLogger::Status::DONE, terrama2::core::TimeUtils::nowUTC(), logId); jsonAnswer = mapsServerAnswer; jsonAnswer.insert("class", QString("RegisteredViews")); jsonAnswer.insert("process_id",static_cast<int32_t>(viewPtr->id)); jsonAnswer.insert("maps_server", QString::fromStdString(mapsServerUri_.uri())); sendProcessFinishedSignal(viewId, executionPackage.executionDate, true, jsonAnswer); notifyWaitQueue(viewId); return; } catch(const terrama2::core::LogException& e) { auto error = boost::get_error_info<terrama2::ErrorDescription>(e); std::string errMsg; if(error) { errMsg = error->toStdString(); TERRAMA2_LOG_ERROR() << errMsg; } else { TERRAMA2_LOG_ERROR() << QObject::tr("Error logging view build error."); } TERRAMA2_LOG_INFO() << QObject::tr("Build of view %1(%2) finished with error(s).").arg(QString::fromStdString(viewName)).arg(viewId); } catch(const terrama2::Exception& e) { auto error = boost::get_error_info<terrama2::ErrorDescription>(e); std::string errMsg; if(error) { errMsg = error->toStdString(); TERRAMA2_LOG_ERROR() << errMsg; } else { TERRAMA2_LOG_ERROR() << QObject::tr("Error logging view build error."); } TERRAMA2_LOG_INFO() << QObject::tr("Build of view %1(%2) finished with error(s).").arg(QString::fromStdString(viewName)).arg(viewId); if(logId != 0) logger->log(ViewLogger::MessageType::ERROR_MESSAGE, errMsg, logId); } catch(const boost::exception& e) { auto error = boost::get_error_info<terrama2::ErrorDescription>(e); std::string errMsg; if(error) { errMsg = error->toStdString(); TERRAMA2_LOG_ERROR() << errMsg; } else { TERRAMA2_LOG_ERROR() << QObject::tr("Error logging view build error."); } TERRAMA2_LOG_INFO() << QObject::tr("Build of view %1(%2) finished with error(s).").arg(QString::fromStdString(viewName)).arg(viewId); if(logId != 0) logger->log(ViewLogger::MessageType::ERROR_MESSAGE, errMsg, logId); } catch(const std::exception& e) { std::string errMsg = e.what(); TERRAMA2_LOG_ERROR() << errMsg; TERRAMA2_LOG_INFO() << QObject::tr("Build of view %1(%2) finished with error(s).").arg(QString::fromStdString(viewName)).arg(viewId); if(logId != 0) logger->log(ViewLogger::MessageType::ERROR_MESSAGE, errMsg, logId); } catch(...) { std::string errMsg = "Unknown error."; TERRAMA2_LOG_ERROR() << QObject::tr("Unknown error."); TERRAMA2_LOG_INFO() << QObject::tr("Build of view %1(%2) finished with error(s).").arg(QString::fromStdString(viewName)).arg(viewId); if(logId != 0) logger->log(ViewLogger::MessageType::ERROR_MESSAGE, errMsg, logId); } if(logId != 0) logger->result(ViewLogger::Status::ERROR, terrama2::core::TimeUtils::nowUTC(), logId); sendProcessFinishedSignal(viewId, executionPackage.executionDate, false); notifyWaitQueue(viewId); }
void terrama2::services::view::core::Service::removeCompleteView(const ViewPtr& viewPtr, DataSeriesId dataSeriesId, bool removeAll) noexcept { ViewId id = viewPtr->id; try { std::lock_guard<std::mutex> lock(mutex_); TERRAMA2_LOG_INFO() << tr("Trying to remove view %1.").arg(id); auto it = timers_.find(id); if(it != timers_.end()) { auto timer = timers_.at(id); timer->disconnect(); timers_.erase(id); } // remove from queue processQueue_.erase(std::remove_if(processQueue_.begin(), processQueue_.end(), [&id](const terrama2::core::ExecutionPackage& executionPackage) { return id == executionPackage.processId; }), processQueue_.end()); if (removeAll) { terrama2::core::DataProviderPtr inputDataProvider; // Locking datamanager { auto dataManager = dataManager_.lock(); auto lock = dataManager->getLock(); terrama2::core::DataSeriesPtr inputDataSeries = dataManager->findDataSeries(dataSeriesId); inputDataProvider = dataManager->findDataProvider(inputDataSeries->dataProviderId); lock.unlock(); } try { // Retrieving Maps server handler MapsServerPtr mapsServer = MapsServerFactory::getInstance().make(mapsServerUri_, "GEOSERVER"); // removing from geoserver mapsServer->cleanup(viewPtr, inputDataProvider, logger_); } catch(const terrama2::services::view::core::NotFoundGeoserverException& e) { // Nothing TERRAMA2_LOG_DEBUG() << tr("There is no workspace in GeoServer"); } catch(const terrama2::services::view::core::ViewGeoserverException&) { // TODO: Improve validation in order to notify WebApp TERRAMA2_LOG_WARNING() << tr("Could not perform clean up in GeoServer and database. Please remove it manually"); } } waitQueue_.erase(id); TERRAMA2_LOG_INFO() << tr("View %1 removed successfully.").arg(id); } catch(const boost::exception& e) { TERRAMA2_LOG_ERROR() << boost::get_error_info<terrama2::ErrorDescription>(e); TERRAMA2_LOG_INFO() << tr("Could not remove view: %1.").arg(id); } catch(const std::exception& e) { TERRAMA2_LOG_ERROR() << e.what(); TERRAMA2_LOG_INFO() << tr("Could not remove view: %1.").arg(id); } catch(...) { TERRAMA2_LOG_ERROR() << tr("Unknown error"); TERRAMA2_LOG_INFO() << tr("Could not remove view: %1.").arg(id); } }
void terrama2::services::analysis::core::Context::loadMonitoredObject(AnalysisHashCode analysisHashCode) { std::lock_guard<std::recursive_mutex> lock(mutex_); auto dataManagerPtr = dataManager_.lock(); if(!dataManagerPtr) { QString errMsg(QObject::tr("Invalid data manager.")); throw terrama2::core::InvalidDataManagerException() << terrama2::ErrorDescription(errMsg); } auto analysis = getAnalysis(analysisHashCode); for(auto analysisDataSeries : analysis->analysisDataSeriesList) { auto dataSeriesPtr = dataManagerPtr->findDataSeries(analysisDataSeries.dataSeriesId); auto datasets = dataSeriesPtr->datasetList; if(analysisDataSeries.type == AnalysisDataSeriesType::DATASERIES_MONITORED_OBJECT_TYPE) { assert(datasets.size() == 1); auto dataset = datasets[0]; auto dataProvider = dataManagerPtr->findDataProvider(dataSeriesPtr->dataProviderId); terrama2::core::Filter filter; //accessing data terrama2::core::DataAccessorPtr accessor = terrama2::core::DataAccessorFactory::getInstance().make(dataProvider, dataSeriesPtr); auto seriesMap = accessor->getSeries(filter); auto series = seriesMap[dataset]; std::string identifier = analysisDataSeries.metadata["identifier"]; std::shared_ptr<ContextDataSeries> dataSeriesContext(new ContextDataSeries); if(!series.syncDataSet) { QString errMsg(QObject::tr("No data available for DataSeries %1").arg(dataSeriesPtr->id)); throw terrama2::InvalidArgumentException() << terrama2::ErrorDescription(errMsg); } if(!series.syncDataSet->dataset()) { QString errMsg(QObject::tr("Adding an invalid dataset to the analysis context: DataSeries %1").arg(dataSeriesPtr->id)); throw terrama2::InvalidArgumentException() << terrama2::ErrorDescription(errMsg); } std::size_t geomPropertyPosition = te::da::GetFirstPropertyPos(series.syncDataSet->dataset().get(), te::dt::GEOMETRY_TYPE); dataSeriesContext->series = series; dataSeriesContext->identifier = identifier; dataSeriesContext->geometryPos = geomPropertyPosition; ContextKey key; key.datasetId_ = dataset->id; key.analysisHashCode_ = analysisHashCode; datasetMap_[key] = dataSeriesContext; } else if(analysisDataSeries.type == AnalysisDataSeriesType::DATASERIES_PCD_TYPE) { for(auto dataset : dataSeriesPtr->datasetList) { auto dataProvider = dataManagerPtr->findDataProvider(dataSeriesPtr->dataProviderId); terrama2::core::Filter filter; //accessing data terrama2::core::DataAccessorPtr accessor = terrama2::core::DataAccessorFactory::getInstance().make(dataProvider, dataSeriesPtr); auto seriesMap = accessor->getSeries(filter); auto series = seriesMap[dataset]; std::string identifier = analysisDataSeries.metadata["identifier"]; std::shared_ptr<ContextDataSeries> dataSeriesContext(new ContextDataSeries); std::size_t geomPropertyPosition = te::da::GetFirstPropertyPos(series.syncDataSet->dataset().get(), te::dt::GEOMETRY_TYPE); dataSeriesContext->series = series; dataSeriesContext->identifier = identifier; dataSeriesContext->geometryPos = geomPropertyPosition; ContextKey key; key.datasetId_ = dataset->id; key.analysisHashCode_ = analysisHashCode; datasetMap_[key] = dataSeriesContext; } } } }
void terrama2::services::analysis::core::Context::addDataSeries(const AnalysisHashCode analysisHashCode, terrama2::core::DataSeriesPtr dataSeries, std::shared_ptr<te::gm::Geometry> envelope, const std::string& dateFilter, bool createSpatialIndex) { std::lock_guard<std::recursive_mutex> lock(mutex_); bool needToAdd = false; for(auto dataset : dataSeries->datasetList) { if(!exists(analysisHashCode, dataset->id, dateFilter)) { needToAdd = true; break; } } auto analysis = Context::getInstance().getAnalysis(analysisHashCode); if(!needToAdd) return; time_t ts = 0; struct tm t; char buf[16]; ::localtime_r(&ts, &t); ::strftime(buf, sizeof(buf), "%Z", &t); boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone(buf)); boost::local_time::local_date_time ldt = boost::local_time::local_microsec_clock::local_time(zone); auto dataManagerPtr = dataManager_.lock(); if(!dataManagerPtr) { QString errMsg(QObject::tr("Invalid data manager.")); throw terrama2::core::InvalidDataManagerException() << terrama2::ErrorDescription(errMsg); } auto dataProvider = dataManagerPtr->findDataProvider(dataSeries->dataProviderId); terrama2::core::Filter filter; filter.discardAfter = analysisStartTime_[analysisHashCode]; if(!dateFilter.empty()) { double seconds = terrama2::core::TimeUtils::convertTimeString(dateFilter, "SECOND", "h"); ldt -= boost::posix_time::seconds(seconds); std::unique_ptr<te::dt::TimeInstantTZ> titz(new te::dt::TimeInstantTZ(ldt)); filter.discardBefore = std::move(titz); } //accessing data terrama2::core::DataAccessorPtr accessor = terrama2::core::DataAccessorFactory::getInstance().make(dataProvider, dataSeries, filter); std::unordered_map<terrama2::core::DataSetPtr, terrama2::core::DataSetSeries > seriesMap = accessor->getSeries(filter); if(seriesMap.empty()) { QString errMsg(QObject::tr("The data series %1 does not contain data").arg(dataSeries->id)); throw EmptyDataSeriesException() << terrama2::ErrorDescription(errMsg); } for(auto mapItem : seriesMap) { auto series = mapItem.second; std::shared_ptr<ContextDataSeries> dataSeriesContext(new ContextDataSeries); std::size_t geomPropertyPosition = te::da::GetFirstPropertyPos(series.syncDataSet->dataset().get(), te::dt::GEOMETRY_TYPE); dataSeriesContext->series = series; dataSeriesContext->geometryPos = geomPropertyPosition; if(createSpatialIndex) { int size = series.syncDataSet->size(); for(std::size_t i = 0; i < size; ++i) { auto geom = series.syncDataSet->getGeometry(i, geomPropertyPosition); dataSeriesContext->rtree.insert(*geom->getMBR(), i); } } ContextKey key; key.datasetId_ = series.dataSet->id; key.analysisHashCode_ = analysisHashCode; key.dateFilter_ = dateFilter; datasetMap_[key] = dataSeriesContext; } }
void terrama2::services::analysis::core::Context::addDCPDataSeries(const AnalysisHashCode analysisHashCode, terrama2::core::DataSeriesPtr dataSeries, const std::string& dateFilter, const bool lastValue) { std::lock_guard<std::recursive_mutex> lock(mutex_); bool needToAdd = false; for(auto dataset : dataSeries->datasetList) { if(!exists(analysisHashCode, dataset->id, dateFilter)) { needToAdd = true; break; } } auto analysis = Context::getInstance().getAnalysis(analysisHashCode); if(!needToAdd) return; time_t ts = 0; struct tm t; char buf[16]; ::localtime_r(&ts, &t); ::strftime(buf, sizeof(buf), "%Z", &t); boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone(buf)); boost::local_time::local_date_time ldt = boost::local_time::local_microsec_clock::local_time(zone); auto dataManagerPtr = dataManager_.lock(); if(!dataManagerPtr) { QString errMsg(QObject::tr("Invalid data manager.")); throw terrama2::core::InvalidDataManagerException() << terrama2::ErrorDescription(errMsg); } auto dataProvider = dataManagerPtr->findDataProvider(dataSeries->dataProviderId); terrama2::core::Filter filter; filter.lastValue = lastValue; filter.discardAfter = analysisStartTime_[analysisHashCode]; if(!dateFilter.empty()) { double seconds = terrama2::core::TimeUtils::convertTimeString(dateFilter, "SECOND", "h"); ldt -= boost::posix_time::seconds(seconds); std::unique_ptr<te::dt::TimeInstantTZ> titz(new te::dt::TimeInstantTZ(ldt)); filter.discardBefore = std::move(titz); } //accessing data terrama2::core::DataAccessorPtr accessor = terrama2::core::DataAccessorFactory::getInstance().make(dataProvider, dataSeries, filter); std::unordered_map<terrama2::core::DataSetPtr, terrama2::core::DataSetSeries > seriesMap = accessor->getSeries(filter); if(seriesMap.empty()) { QString errMsg(QObject::tr("The data series %1 does not contain data").arg(dataSeries->id)); throw EmptyDataSeriesException() << terrama2::ErrorDescription(errMsg); } for(auto mapItem : seriesMap) { auto series = mapItem.second; std::shared_ptr<ContextDataSeries> dataSeriesContext(new ContextDataSeries); dataSeriesContext->series = series; terrama2::core::DataSetDcpPtr dcpDataset = std::dynamic_pointer_cast<const terrama2::core::DataSetDcp>(series.dataSet); if(!dcpDataset->position) { QString errMsg(QObject::tr("Invalid location for DCP.")); throw InvalidDataSetException() << terrama2::ErrorDescription(errMsg); } int srid = dcpDataset->position->getSRID(); if(srid == 0) { if(dcpDataset->format.find("srid") != dcpDataset->format.end()) { srid = std::stoi(dcpDataset->format.at("srid")); dcpDataset->position->setSRID(srid); } } // if data projection is in decimal degrees we need to convert it to a meter projection. auto spatialReferenceSystem = te::srs::SpatialReferenceSystemManager::getInstance().getSpatialReferenceSystem(dcpDataset->position->getSRID()); std::string unitName = spatialReferenceSystem->getUnitName(); if(unitName == "degree") { // Converts the data to UTM int sridUTM = terrama2::core::getUTMSrid(dcpDataset->position.get()); dcpDataset->position->transform(sridUTM); } dataSeriesContext->rtree.insert(*dcpDataset->position->getMBR(), dcpDataset->id); ContextKey key; key.datasetId_ = series.dataSet->id; key.analysisHashCode_ = analysisHashCode; key.dateFilter_ = dateFilter; datasetMap_[key] = dataSeriesContext; } }