正在显示
1 个修改的文件
包含
138 行增加
和
278 行删除
| @@ -7,342 +7,202 @@ | @@ -7,342 +7,202 @@ | ||
| 7 | * copyright: 广州城市信息研究所有限公司 | 7 | * copyright: 广州城市信息研究所有限公司 |
| 8 | ***************************************************************************/ | 8 | ***************************************************************************/ |
| 9 | #include "dmpservermanager.h" | 9 | #include "dmpservermanager.h" |
| 10 | -#include <boost/format.hpp> | ||
| 11 | -#include <boost/algorithm/string.hpp> | ||
| 12 | -#include <boost/regex.hpp> | ||
| 13 | -#include <boost/lexical_cast.hpp> | ||
| 14 | - | ||
| 15 | #include "dmpserver.h" | 10 | #include "dmpserver.h" |
| 16 | - | ||
| 17 | -using namespace std; | ||
| 18 | -namespace | 11 | +#include "dmphttputils.h" |
| 12 | +#include "dmpserverConfig.h" | ||
| 13 | +#include <memory> | ||
| 14 | +#include <boost/property_tree/ptree.hpp> | ||
| 15 | +#include <boost/property_tree/json_parser.hpp> | ||
| 16 | +#include <boost/property_tree/xml_parser.hpp> | ||
| 17 | +#include <sstream> | ||
| 18 | +#include <fstream> | ||
| 19 | +#include <math.h> | ||
| 20 | +#include "dmptilethumbnail.h" | ||
| 21 | +#include "dmptilelayer.h" | ||
| 22 | +#include <iostream> | ||
| 23 | +#include "dmplogger.h" | ||
| 24 | +#include "dmptilethumbnail.h" | ||
| 25 | +#include "dmptilelayer.h" | ||
| 26 | + | ||
| 27 | +DmpServerManager::DmpServerManager() | ||
| 19 | { | 28 | { |
| 29 | + serverRegistry_ = new DmpServerRegistry(); | ||
| 30 | +} | ||
| 20 | 31 | ||
| 21 | - string MakeServerKey(const string &name, const string &version) | 32 | +DmpServerManager::~DmpServerManager() |
| 33 | +{ | ||
| 34 | + if (serverRegistry_) | ||
| 22 | { | 35 | { |
| 23 | - boost::format fmt = boost::format("%1%_%2%") % name % version; | ||
| 24 | - return fmt.str(); | 36 | + delete serverRegistry_; |
| 37 | + serverRegistry_ = NULL; | ||
| 25 | } | 38 | } |
| 26 | 39 | ||
| 27 | - bool IsVersionGreater(const string &v1, const string &v2) | 40 | + ProjectMap::iterator iter = projects_.begin(); |
| 41 | + for (; iter != projects_.end(); ++iter) | ||
| 28 | { | 42 | { |
| 29 | - vector<string> vecSeg1; | ||
| 30 | - boost::split(vecSeg1, v1, boost::is_any_of("."), boost::token_compress_on); | ||
| 31 | - vector<string> vecSeg2; | ||
| 32 | - boost::split(vecSeg2, v2, boost::is_any_of("."), boost::token_compress_on); | ||
| 33 | - | ||
| 34 | - vector<string>::iterator it1 = vecSeg1.begin(); | ||
| 35 | - vector<string>::iterator it2 = vecSeg2.begin(); | ||
| 36 | - bool isint; | ||
| 37 | - while (it1 != vecSeg1.end() && it2 != vecSeg2.end()) | 43 | + DmpProject *mapProject = iter->second; |
| 44 | + if (mapProject) | ||
| 38 | { | 45 | { |
| 39 | - if (*it1 != *it2) | ||
| 40 | - { | ||
| 41 | - // Compare as numbers | ||
| 42 | - int i1 = atoi(it1->c_str()); | ||
| 43 | - int i2 = atoi(it2->c_str()); | ||
| 44 | - if (i1 != i2) | ||
| 45 | - { | ||
| 46 | - return i1 > i2; | ||
| 47 | - } | ||
| 48 | - } | ||
| 49 | - ++it1; | ||
| 50 | - ++it2; | 46 | + delete mapProject; |
| 47 | + mapProject = nullptr; | ||
| 51 | } | 48 | } |
| 52 | - return false; | ||
| 53 | - } | ||
| 54 | -} // namespace | 49 | + } |
| 50 | + projects_.clear(); | ||
| 51 | +} | ||
| 55 | 52 | ||
| 56 | -DmpServerManager::DmpServerManager(const std::string& root_path) | ||
| 57 | - :root_path_(root_path) | 53 | +void DmpServerManager::init(const boost::filesystem::path &modulePath) |
| 58 | { | 54 | { |
| 55 | + serverRegistry_->init(modulePath); | ||
| 56 | + if(!loadServices()) | ||
| 57 | + { | ||
| 58 | + std::cout << "加载服务失败!" << std::endl; | ||
| 59 | + LOGGER_ERROR("加载服务失败!"); | ||
| 60 | + } | ||
| 61 | + //LoadDmpServices(); | ||
| 62 | +} | ||
| 59 | 63 | ||
| 64 | +std::string DmpServerManager::getCapabilities() | ||
| 65 | +{ | ||
| 66 | + return serverRegistry_->getCapabilities(); | ||
| 60 | } | 67 | } |
| 61 | 68 | ||
| 62 | -DmpServerManager::~DmpServerManager() | 69 | +std::shared_ptr<DmpServer> DmpServerManager::serverForRequest(const DmpServerRequest &request) |
| 63 | { | 70 | { |
| 64 | - CleanUp(); | ||
| 65 | - std::cout << "Destructing DmpServerManager" << std::endl; | 71 | + return serverRegistry_->getServerForRequest(request); |
| 66 | } | 72 | } |
| 67 | 73 | ||
| 68 | -void DmpServerManager::Init(const boost::filesystem::path &module_path) | 74 | +std::shared_ptr<DmpServerApi> DmpServerManager::apiForRequest(const DmpServerRequest &request) |
| 69 | { | 75 | { |
| 70 | - nativeLoader_.LoadModules(module_path, *this); | ||
| 71 | - | ||
| 72 | - LoadServices(); | 76 | + return serverRegistry_->getApiForRequest(request); |
| 73 | } | 77 | } |
| 74 | 78 | ||
| 75 | -int DmpServerManager::GetServicePaths(const std::string& service_dir, std::vector<std::string>& service_paths) | 79 | +DmpProject *DmpServerManager::getProject(const std::string &serviceName) |
| 76 | { | 80 | { |
| 77 | - if (!boost::filesystem::exists(service_dir)) | 81 | + std::map<std::string, DmpProject *>::iterator iter = projects_.find(serviceName); |
| 82 | + if (iter != projects_.end()) | ||
| 78 | { | 83 | { |
| 79 | - return -1; | 84 | + return iter->second; |
| 80 | } | 85 | } |
| 81 | - boost::filesystem::directory_iterator end_iter; | ||
| 82 | - for (boost::filesystem::directory_iterator iter(service_dir); iter != end_iter; ++iter) | 86 | + else |
| 83 | { | 87 | { |
| 84 | - if (boost::filesystem::is_regular_file(iter->status()) && iter->path().extension() == ".json") | ||
| 85 | - { | ||
| 86 | - std::string file_name = iter->path().filename().string(); | ||
| 87 | - boost::cmatch what; | ||
| 88 | - boost::regex reg("(^\\w+)\\.(\\w+)\\.(\\w+)$", boost::regex_constants::icase); | ||
| 89 | - if(boost::regex_match(file_name.c_str(), what, reg) && what.size() == 4) | ||
| 90 | - { | ||
| 91 | - service_paths.push_back(iter->path().string()); | ||
| 92 | - } | ||
| 93 | - } | ||
| 94 | - else if (boost::filesystem::is_directory(iter->status())) | ||
| 95 | - { | ||
| 96 | - GetServicePaths(iter->path().string(), service_paths); | ||
| 97 | - } | 88 | + return nullptr; |
| 98 | } | 89 | } |
| 99 | - return service_paths.size(); | ||
| 100 | } | 90 | } |
| 101 | 91 | ||
| 102 | -bool DmpServerManager::LoadServices() | 92 | +bool DmpServerManager::removeProject(const std::string &serviceName) |
| 103 | { | 93 | { |
| 104 | - //获取服务的路径 | ||
| 105 | - std::vector<std::string> service_paths; | ||
| 106 | - int size = GetServicePaths(root_path_, service_paths); | ||
| 107 | - if(size < 1) { | ||
| 108 | - return false; | ||
| 109 | - } | ||
| 110 | - for (const auto &service_path : service_paths) | 94 | + try |
| 111 | { | 95 | { |
| 112 | - //获取服务名称和服务类型vev[0],vec[1] | ||
| 113 | - std::string::size_type pos = service_path.find_last_of("/"); | ||
| 114 | - if(pos != std::string::npos) { | ||
| 115 | - std::vector<std::string> vec; | ||
| 116 | - std::string file_name = service_path.substr(pos + 1); | ||
| 117 | - boost::split(vec, file_name, boost::is_any_of("."), boost::token_compress_on); | ||
| 118 | - std::string service_name = vec[0]; | ||
| 119 | - | ||
| 120 | - if(boost::iequals(vec[1], "MapServer")) | ||
| 121 | - { | ||
| 122 | - DmpMapService* mapservice = new DmpMapService(service_name, service_path); | ||
| 123 | - //通知所有服务器,注册到MapServer中;为什么不由MapServer直接Add,因为MapServer不知道有多少Server,Server是动态注册到系统中的 | ||
| 124 | - for (const auto &server : servers_) { | ||
| 125 | - server.second->Register(mapservice); | ||
| 126 | - } | ||
| 127 | - if(mapservice->Read()) | ||
| 128 | - { | ||
| 129 | - services_[service_name] = mapservice; | ||
| 130 | - mapservice->set_state(ServiceState::STARTED); | ||
| 131 | - } | ||
| 132 | - } | 96 | + std::map<std::string, DmpProject *>::iterator iter = projects_.find(serviceName); |
| 97 | + if (iter != projects_.end()) | ||
| 98 | + { | ||
| 99 | + delete iter->second; | ||
| 100 | + projects_.erase(iter); | ||
| 133 | } | 101 | } |
| 134 | } | 102 | } |
| 103 | + catch (const std::exception &e) | ||
| 104 | + { | ||
| 105 | + std::cerr << e.what() << '\n'; | ||
| 106 | + return false; | ||
| 107 | + } | ||
| 108 | + return true; | ||
| 135 | } | 109 | } |
| 136 | 110 | ||
| 137 | -std::shared_ptr<DmpServer> DmpServerManager::GetServer(const string &name, const string &version) | 111 | +bool DmpServerManager::publish(const std::string& serverName, const std::string& serviceName, const std::string& title, int capabilities, const std::string& projectData) |
| 138 | { | 112 | { |
| 139 | - std::shared_ptr<DmpServer> sp_server = nullptr; | ||
| 140 | - string key; | ||
| 141 | - string nameUpper = boost::to_upper_copy(name); | ||
| 142 | - VersionMap::const_iterator it = serverVersions_.find(nameUpper); | ||
| 143 | - if (it != serverVersions_.end()) | 113 | + //project |
| 114 | + std::string projData; | ||
| 115 | + if (!DmpServerUtils::Base64Decode(projectData, &projData)) | ||
| 144 | { | 116 | { |
| 145 | - key = version.empty() ? it->second.second : MakeServerKey(nameUpper, version); | ||
| 146 | - ServerMap::const_iterator iter = servers_.find(key); | ||
| 147 | - if (iter != servers_.end()) | ||
| 148 | - { | ||
| 149 | - sp_server = iter->second; | ||
| 150 | - } | ||
| 151 | - else | ||
| 152 | - { | ||
| 153 | - sp_server = servers_[it->second.second]; | ||
| 154 | - } | 117 | + return false; |
| 155 | } | 118 | } |
| 156 | - else | 119 | + DmpProject *project = new DmpProject(); |
| 120 | + if (!project->Read(projData)) | ||
| 157 | { | 121 | { |
| 122 | + delete project; | ||
| 123 | + return false; | ||
| 158 | } | 124 | } |
| 159 | - return sp_server; | ||
| 160 | -} | ||
| 161 | -void DmpServerManager::RegisterServer(std::shared_ptr<DmpServer> server) | ||
| 162 | -{ | ||
| 163 | - string name = server->Name(); | ||
| 164 | - boost::to_upper(name); | ||
| 165 | - string version = server->Version(); | ||
| 166 | 125 | ||
| 167 | - string key = MakeServerKey(name, version); | ||
| 168 | - if (servers_.find(key) != servers_.end()){ | ||
| 169 | - return; | ||
| 170 | - } | ||
| 171 | - servers_[key] = server; | ||
| 172 | - if (serverVersions_.find(name) == serverVersions_.end()){ | ||
| 173 | - serverVersions_.insert(pair<string, pair<string, string>>(name, pair<string, string>(version, key))); | 126 | + if (!serverRegistry_->getServer(serverName)->publish(serviceName, title, capabilities, *project)) |
| 127 | + { | ||
| 128 | + delete project; | ||
| 129 | + return false; | ||
| 174 | } | 130 | } |
| 131 | + projects_[serviceName] = project; | ||
| 132 | + | ||
| 133 | + return true; | ||
| 175 | } | 134 | } |
| 176 | 135 | ||
| 177 | -int DmpServerManager::UnregisterServer(const string &name, const string &version) | 136 | +bool DmpServerManager::deleteService(const std::string &serverName, const std::string &serviceName) |
| 178 | { | 137 | { |
| 179 | - int removed = 0; | ||
| 180 | - VersionMap::const_iterator it = serverVersions_.find(name); | ||
| 181 | - if (it != serverVersions_.end()) | 138 | + if (serverRegistry_->getServer(serverName)->remove(serviceName) && removeProject(serviceName)) |
| 182 | { | 139 | { |
| 183 | - if (version.empty()) | ||
| 184 | - { | ||
| 185 | - ServerMap::iterator iter = servers_.begin(); | ||
| 186 | - while (iter != servers_.end()) | ||
| 187 | - { | ||
| 188 | - if (iter->second->Name() == name) | ||
| 189 | - { | ||
| 190 | - iter = servers_.erase(iter); | ||
| 191 | - ++removed; | ||
| 192 | - } | ||
| 193 | - else | ||
| 194 | - { | ||
| 195 | - ++iter; | ||
| 196 | - } | ||
| 197 | - } | ||
| 198 | - serverVersions_.erase(it); | ||
| 199 | - } | ||
| 200 | - else | ||
| 201 | - { | ||
| 202 | - string key = MakeServerKey(name, version); | ||
| 203 | - ServerMap::iterator found = servers_.find(key); | ||
| 204 | - if (found != servers_.end()) | ||
| 205 | - { | ||
| 206 | - servers_.erase(found); | ||
| 207 | - removed = 1; | ||
| 208 | - | ||
| 209 | - //findGreaterVersion为匿名函数 | ||
| 210 | - string maxVer; | ||
| 211 | - std::function<void(const ServerMap::value_type &)> | ||
| 212 | - findGreaterVersion = [name, &maxVer](const ServerMap::value_type &item) { | ||
| 213 | - if (item.second->Name() == name && | ||
| 214 | - (maxVer.empty() || IsVersionGreater(item.second->Version(), maxVer))) | ||
| 215 | - maxVer = item.second->Version(); | ||
| 216 | - }; | ||
| 217 | - | ||
| 218 | - serverVersions_.erase(name); | ||
| 219 | - | ||
| 220 | - std::for_each(servers_.begin(), servers_.end(), findGreaterVersion); | ||
| 221 | - if (!maxVer.empty()) | ||
| 222 | - { | ||
| 223 | - // Set the new default service | ||
| 224 | - string key = MakeServerKey(name, maxVer); | ||
| 225 | - serverVersions_.insert(pair<string, pair<string, string>>(name, pair<string, string>(version, key))); | ||
| 226 | - } | ||
| 227 | - } | ||
| 228 | - } | 140 | + return true; |
| 141 | + } | ||
| 142 | + else | ||
| 143 | + { | ||
| 144 | + return false; | ||
| 229 | } | 145 | } |
| 230 | - return removed; | ||
| 231 | } | 146 | } |
| 232 | 147 | ||
| 233 | -void DmpServerManager::CleanUp() | 148 | +bool DmpServerManager::startService(const std::string &serverName, const std::string &serviceName) |
| 234 | { | 149 | { |
| 235 | - serverVersions_.clear(); | ||
| 236 | - servers_.clear(); | ||
| 237 | - nativeLoader_.UnloadModules(); | 150 | + return serverRegistry_->getServer(serverName)->start(serviceName); |
| 238 | } | 151 | } |
| 239 | 152 | ||
| 240 | -std::shared_ptr<DmpServer> DmpServerManager::ServerForRequest(const DmpServerRequest &request) | 153 | +bool DmpServerManager::stopService(const std::string &serverName, const std::string &serviceName) |
| 241 | { | 154 | { |
| 242 | - for (const auto &server : servers_) | ||
| 243 | - { | ||
| 244 | - if(server.second->Accept(request.path())) | ||
| 245 | - { | ||
| 246 | - return server.second; | ||
| 247 | - } | ||
| 248 | - } | ||
| 249 | - return nullptr; | 155 | + return serverRegistry_->getServer(serverName)->stop(serviceName); |
| 250 | } | 156 | } |
| 251 | - | ||
| 252 | -bool DmpServerManager::PublishMapServer(const std::string& service_name, const std::string& capabilities, | ||
| 253 | - const std::string& project_data, const std::string& service_title, | ||
| 254 | - const std::string& catalog) | 157 | +bool DmpServerManager::loadServices() |
| 255 | { | 158 | { |
| 256 | - std::string map_dir; | ||
| 257 | - std::string service_file; | ||
| 258 | - std::string proj_file; | ||
| 259 | - if(catalog.empty()) { | ||
| 260 | - map_dir = root_path_ + "/" + service_name + ".MapServer"; | ||
| 261 | - } else { | ||
| 262 | - map_dir = root_path_ + "/" + catalog + "/" + service_name + ".MapServer"; | ||
| 263 | - } | ||
| 264 | - if (!boost::filesystem::exists(map_dir)) | ||
| 265 | - { | ||
| 266 | - boost::filesystem::create_directories(map_dir); | ||
| 267 | - } | ||
| 268 | - service_file = map_dir + "/" + service_name + ".MapServer.json"; | ||
| 269 | - proj_file = map_dir + "/" + service_name + ".MapServer.dmd"; | ||
| 270 | - | ||
| 271 | - //project | ||
| 272 | - std::string proj_data; | ||
| 273 | - if(!DmpServerUtils::Base64Decode(project_data, &proj_data)){ | ||
| 274 | - return false; | ||
| 275 | - } | ||
| 276 | - DmpProject project; | ||
| 277 | - if(!project.Write(proj_file, proj_data)){ | ||
| 278 | - return false; | ||
| 279 | - } | ||
| 280 | - | ||
| 281 | - //services | ||
| 282 | - vector<string> vec_cap; | ||
| 283 | - boost::split(vec_cap, capabilities, boost::is_any_of(","), boost::token_compress_on); | ||
| 284 | - if(vec_cap.size() == 0){ | ||
| 285 | - return false; | ||
| 286 | - } | ||
| 287 | - DmpMapService* mapserver = new DmpMapService(service_name,service_file); | ||
| 288 | - for (const auto &cap : vec_cap) | ||
| 289 | - { | ||
| 290 | - std::shared_ptr<DmpServer> server = GetServer(cap, ""); | ||
| 291 | - if(!server->Register(mapserver)){ | 159 | + boost::property_tree::ptree pt,ptList; |
| 160 | + std::string conn = DmpServerConfig::Instance()->getMetaUrl(); | ||
| 161 | + const std::string url= conn + URI_RELOAD; | ||
| 162 | + std::string strContent=DmpHttp::get(url); | ||
| 163 | + if(strContent.length()==0) | ||
| 164 | + { | ||
| 292 | return false; | 165 | return false; |
| 293 | } | 166 | } |
| 294 | - } | ||
| 295 | - | ||
| 296 | - if (mapserver->Write()) { | ||
| 297 | - services_[service_name] = mapserver; | ||
| 298 | - mapserver->set_state(ServiceState::STARTED); | ||
| 299 | - } | ||
| 300 | - return true; | 167 | + std::stringstream ssData; |
| 168 | + ssData<<strContent.c_str(); | ||
| 169 | + boost::property_tree::read_json(ssData, pt); | ||
| 170 | + int iCount = std::atoi(pt.get<std::string>("data.count").c_str()); | ||
| 171 | + if(iCount>0) | ||
| 172 | + { | ||
| 173 | + ptList=pt.get_child("data.list"); | ||
| 174 | + for (auto& e : ptList) | ||
| 175 | + { | ||
| 176 | + std::string name = e.second.get<std::string>("name"); | ||
| 177 | + std::string title = e.second.get<std::string>("title"); | ||
| 178 | + std::string type = e.second.get<std::string>("type"); | ||
| 179 | + int capabilities =e.second.get<int>("capabilities"); | ||
| 180 | + std::string project = e.second.get<std::string>("project"); | ||
| 181 | + this->initServices(type,name,title,capabilities,project); | ||
| 182 | + } | ||
| 183 | + } | ||
| 184 | + return true; | ||
| 301 | } | 185 | } |
| 302 | - | ||
| 303 | -bool DmpServerManager::PublishTileServer(const std::string& service_name,const std::string& type,const std::string& vendor, | ||
| 304 | - const std::string& srs,const std::string& path,const std::string& abstract,const std::string& layerinfo, | ||
| 305 | - const std::string& project_data,const std::string& service_title,const std::string& catalog) | 186 | +bool DmpServerManager::initServices(const std::string& serverName, const std::string& serviceName, const std::string& title, int capabilities, const std::string& projectData) |
| 306 | { | 187 | { |
| 307 | - | ||
| 308 | - std::string map_dir; | ||
| 309 | - std::string service_file; | ||
| 310 | - std::string proj_file; | ||
| 311 | - if(catalog.empty()) { | ||
| 312 | - map_dir = root_path_ + "/" + service_name + ".MapServer"; | ||
| 313 | - } else { | ||
| 314 | - map_dir = root_path_ + "/" + catalog + "/" + service_name + ".MapServer"; | ||
| 315 | - } | ||
| 316 | - if (!boost::filesystem::exists(map_dir)) | ||
| 317 | - { | ||
| 318 | - boost::filesystem::create_directories(map_dir); | ||
| 319 | - } | ||
| 320 | - service_file = map_dir + "/" + service_name + ".MapServer.json"; | ||
| 321 | - proj_file = map_dir + "/" + service_name + ".MapServer.dmd"; | ||
| 322 | - | ||
| 323 | - DmpProject project; | ||
| 324 | - if(!project.Write(proj_file, project_data)){ | ||
| 325 | - return false; | ||
| 326 | - } | ||
| 327 | - | ||
| 328 | - //services | ||
| 329 | - vector<string> vec_cap; | ||
| 330 | - boost::split(vec_cap, type, boost::is_any_of(","), boost::token_compress_on); | ||
| 331 | - if(vec_cap.size() == 0){ | ||
| 332 | - return false; | ||
| 333 | - } | ||
| 334 | - DmpMapService* mapserver = new DmpMapService(service_name,service_file); | ||
| 335 | - for (const auto &cap : vec_cap) | ||
| 336 | - { | ||
| 337 | - std::shared_ptr<DmpServer> server = GetServer(cap, ""); | ||
| 338 | - if(!server->Register(mapserver)){ | 188 | + //project |
| 189 | + std::string projData; | ||
| 190 | + if (!DmpServerUtils::Base64Decode(projectData, &projData)) | ||
| 191 | + { | ||
| 192 | + return false; | ||
| 193 | + } | ||
| 194 | + DmpProject *project = new DmpProject(); | ||
| 195 | + if (!project->Read(projData)) | ||
| 196 | + { | ||
| 197 | + delete project; | ||
| 339 | return false; | 198 | return false; |
| 340 | } | 199 | } |
| 341 | - } | ||
| 342 | - if (mapserver->Write()) { | ||
| 343 | - services_[service_name] = mapserver; | ||
| 344 | - mapserver->set_state(ServiceState::STARTED); | ||
| 345 | - } | ||
| 346 | 200 | ||
| 347 | - return true; | 201 | + if (!serverRegistry_->getServer(serverName)->publish(serviceName, title, capabilities, *project)) |
| 202 | + { | ||
| 203 | + delete project; | ||
| 204 | + return false; | ||
| 205 | + } | ||
| 206 | + projects_[serviceName] = project; | ||
| 207 | + return true; | ||
| 348 | } | 208 | } |
请
注册
或
登录
后发表评论