2 * Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
16 package org.openo.msb.wrapper;
\r
18 import java.io.File;
\r
19 import java.io.FileNotFoundException;
\r
20 import java.io.IOException;
\r
21 import java.net.URL;
\r
22 import java.util.HashMap;
\r
23 import java.util.Map;
\r
24 import java.util.Set;
\r
26 import org.apache.commons.lang3.StringUtils;
\r
27 import org.openo.msb.api.ApiRouteInfo;
\r
28 import org.openo.msb.api.DiscoverInfo;
\r
29 import org.openo.msb.api.RouteServer;
\r
30 import org.openo.msb.api.exception.ExtendedInternalServerErrorException;
\r
31 import org.openo.msb.api.exception.ExtendedNotFoundException;
\r
32 import org.openo.msb.api.exception.ExtendedNotSupportedException;
\r
33 import org.openo.msb.wrapper.util.JedisUtil;
\r
34 import org.openo.msb.wrapper.util.RegExpTestUtil;
\r
35 import org.openo.msb.wrapper.util.RouteUtil;
\r
36 import org.slf4j.Logger;
\r
37 import org.slf4j.LoggerFactory;
\r
39 import redis.clients.jedis.Jedis;
\r
44 * @ClassName: ApiRouteServiceWrapper
\r
45 * @Description: TODO(ApiRoute服务类)
\r
46 * @author tanghua10186366
\r
47 * @date 2015年9月25日 上午9:44:04
\r
50 public class ApiRouteServiceWrapper {
\r
52 private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteServiceWrapper.class);
\r
55 private static ApiRouteServiceWrapper instance = new ApiRouteServiceWrapper();
\r
57 private ApiRouteServiceWrapper() {}
\r
59 public static ApiRouteServiceWrapper getInstance() {
\r
64 * @Title: getAllApiRouteInstances
\r
65 * @Description: TODO(获取全部服务列表)
\r
67 * @return: ApiRouteInfoBean[]
\r
69 public ApiRouteInfo[] getAllApiRouteInstances() {
\r
73 ApiRouteInfo[] apiRouteList = null;
\r
75 jedis = JedisUtil.borrowJedisInstance();
\r
76 if (jedis == null) {
\r
77 throw new ExtendedInternalServerErrorException(
\r
78 "fetch from jedis pool failed,null object!");
\r
84 .getPrefixedKey("", RouteUtil.APIROUTE, "*", RouteUtil.ROUTE_PATH_INFO);
\r
85 Set<String> routeSet = jedis.keys(routekey);
\r
86 apiRouteList = new ApiRouteInfo[routeSet.size()];
\r
89 for (String routePath : routeSet) {
\r
90 String[] routePathArray = routePath.split(":");
\r
91 ApiRouteInfo apiRoute =
\r
92 getApiRouteInstance(routePathArray[3], routePathArray[4], jedis);
\r
93 apiRouteList[i] = apiRoute;
\r
98 } catch (Exception e) {
\r
99 LOGGER.error("call redis throw exception", e);
\r
100 throw new ExtendedInternalServerErrorException("call redis throw exception:"
\r
104 JedisUtil.returnJedisInstance(jedis);
\r
107 return apiRouteList;
\r
112 public static boolean checkRedisConnect() {
\r
114 Jedis jedis = null;
\r
116 jedis = JedisUtil.borrowJedisInstance();
\r
117 if (jedis != null) {
\r
120 } catch (Exception e) {
\r
121 LOGGER.error("call redis throw exception", e);
\r
123 JedisUtil.returnJedisInstance(jedis);
\r
130 * @Title: getApiRouteInstance
\r
131 * @Description: TODO(通过服务名+版本号获取单个服务对象信息)
\r
132 * @param: @param serviceName
\r
133 * @param: @param version
\r
135 * @return: ApiRouteInfo
\r
137 public ApiRouteInfo getApiRouteInstance(String serviceName, String version) {
\r
139 if (StringUtils.isBlank(serviceName)) {
\r
140 throw new ExtendedNotSupportedException("serviceName can't be empty");
\r
143 if (StringUtils.isNotBlank(version)) {
\r
144 if (!RegExpTestUtil.versionRegExpTest(version)) {
\r
145 throw new ExtendedNotSupportedException("version (" + version
\r
146 + ") is not a valid format");
\r
151 ApiRouteInfo apiRouteInfo = null;
\r
153 Jedis jedis = null;
\r
155 jedis = JedisUtil.borrowJedisInstance();
\r
156 if (jedis == null) {
\r
157 throw new ExtendedInternalServerErrorException(
\r
158 "fetch from jedis pool failed,null object!");
\r
161 apiRouteInfo = getApiRouteInstance(serviceName, version, jedis);
\r
164 } catch (Exception e) {
\r
165 LOGGER.error("call redis throw exception", e);
\r
166 throw new ExtendedInternalServerErrorException("call redis throw exception:"
\r
170 JedisUtil.returnJedisInstance(jedis);
\r
173 if (null == apiRouteInfo) {
\r
175 "ApiRouteInfo not found: serviceName-" + serviceName + " ,version-" + version;
\r
176 LOGGER.warn(errInfo);
\r
177 throw new ExtendedNotFoundException(errInfo);
\r
181 return apiRouteInfo;
\r
185 public ApiRouteInfo getApiRouteInstance(String serviceName, String version, Jedis jedis)
\r
187 if ("null".equals(version)) {
\r
191 ApiRouteInfo apiRouteInfo = null;
\r
196 RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version,
\r
197 RouteUtil.ROUTE_PATH_INFO);
\r
198 Map<String, String> infomap = jedis.hgetAll(routekey);
\r
199 if (!infomap.isEmpty()) {
\r
200 apiRouteInfo = new ApiRouteInfo();
\r
201 apiRouteInfo.setServiceName(serviceName);
\r
202 apiRouteInfo.setVersion(version);
\r
203 apiRouteInfo.setUrl(infomap.get("url"));
\r
204 apiRouteInfo.setMetricsUrl(infomap.get("metricsUrl"));
\r
205 apiRouteInfo.setApiJson(infomap.get("apijson"));
\r
206 apiRouteInfo.setApiJsonType(infomap.get("apiJsonType"));
\r
207 apiRouteInfo.setControl(infomap.get("control"));
\r
208 apiRouteInfo.setStatus(infomap.get("status"));
\r
209 apiRouteInfo.setVisualRange(infomap.get("visualRange"));
\r
210 apiRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream"));
\r
214 String serviceLBkey =
\r
215 RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version,
\r
216 RouteUtil.ROUTE_PATH_LOADBALANCE);
\r
217 Set<String> serviceLBset = jedis.keys(serviceLBkey + ":*");
\r
218 int serverNum = serviceLBset.size();
\r
219 RouteServer[] apiRouteServerList = new RouteServer[serverNum];
\r
221 for (String serviceInfo : serviceLBset) {
\r
222 Map<String, String> serviceLBmap = jedis.hgetAll(serviceInfo);
\r
223 RouteServer server = new RouteServer();
\r
224 server.setIp(serviceLBmap.get("ip"));
\r
225 server.setPort(serviceLBmap.get("port"));
\r
226 server.setWeight(Integer.parseInt(serviceLBmap.get("weight")));
\r
227 apiRouteServerList[i] = server;
\r
231 apiRouteInfo.setServers(apiRouteServerList);
\r
235 // ApiRouteLifeCycle lifeCycle = new ApiRouteLifeCycle();
\r
236 // String serviceLifekey =
\r
237 // RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version,
\r
238 // RouteUtil.APIROUTE_PATH_LIFE);
\r
239 // Map<String, String> serviceLifeMap = jedis.hgetAll(serviceLifekey);
\r
241 // lifeCycle.setInstallPath(serviceLifeMap.get("path"));
\r
242 // lifeCycle.setStartScript(serviceLifeMap.get("start"));
\r
243 // lifeCycle.setStopScript(serviceLifeMap.get("stop"));
\r
245 // apiRouteInfo.setLifeCycle(lifeCycle);
\r
249 return apiRouteInfo;
\r
253 * @Title: updateApiRouteInstance
\r
254 * @Description: TODO(更新单个服务信息)
\r
255 * @param: @param serviceName
\r
256 * @param: @param version
\r
257 * @param: @param apiRouteInfo
\r
259 * @return: ApiRouteInfo
\r
261 public synchronized ApiRouteInfo updateApiRouteInstance(String serviceName, String version,
\r
262 ApiRouteInfo apiRouteInfo, String serverPort) {
\r
264 if ("null".equals(version)) {
\r
268 if (StringUtils.isBlank(serviceName)) {
\r
269 throw new ExtendedNotSupportedException("serviceName can't be empty");
\r
272 if (StringUtils.isNotBlank(version)) {
\r
273 if (!RegExpTestUtil.versionRegExpTest(version)) {
\r
274 throw new ExtendedNotSupportedException("version (" + version
\r
275 + ") is not a valid format");
\r
285 if (serviceName.equals(apiRouteInfo.getServiceName())
\r
286 && version.equals(apiRouteInfo.getVersion())) {
\r
288 deleteApiRoute(serviceName, version, RouteUtil.ROUTE_PATH_LOADBALANCE + "*",
\r
292 // 如果已修改服务名或者版本号,先删除此服务全部已有信息
\r
293 deleteApiRoute(serviceName, version, "*", serverPort);
\r
297 saveApiRouteInstance(apiRouteInfo, serverPort);
\r
300 } catch (ExtendedNotSupportedException e) {
\r
302 } catch (Exception e) {
\r
303 LOGGER.error("update ApiRoute throw exception", e);
\r
304 throw new ExtendedInternalServerErrorException("update apiRouteInfo throw exception"
\r
309 return apiRouteInfo;
\r
314 * @Title updateApiRouteStatus
\r
315 * @Description TODO(更新单个服务状态)
\r
316 * @param serviceName
\r
320 * @return RouteResult
\r
322 public synchronized ApiRouteInfo updateApiRouteStatus(String serviceName, String version,
\r
325 if ("null".equals(version)) {
\r
329 if (StringUtils.isBlank(serviceName)) {
\r
330 throw new ExtendedNotSupportedException("serviceName can't be empty");
\r
333 if (StringUtils.isNotBlank(version)) {
\r
334 if (!RegExpTestUtil.versionRegExpTest(version)) {
\r
335 throw new ExtendedNotSupportedException("version (" + version
\r
336 + ") is not a valid format");
\r
340 if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) {
\r
341 throw new ExtendedNotSupportedException(
\r
342 "save ApiRouteInfo Status FAIL:status is wrong,value range:("
\r
343 + RouteUtil.show(RouteUtil.statusRangeMatches) + ")");
\r
346 ApiRouteInfo new_apiRouteInfo = getApiRouteInstance(serviceName, version);
\r
350 String serviceInfokey =
\r
351 RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version,
\r
352 RouteUtil.ROUTE_PATH_INFO);
\r
353 Map<String, String> serviceInfoMap = new HashMap<String, String>();
\r
354 serviceInfoMap.put("status", status);
\r
357 Jedis jedis = null;
\r
359 jedis = JedisUtil.borrowJedisInstance();
\r
360 if (jedis == null) {
\r
361 throw new Exception("fetch from jedis pool failed,null object!");
\r
364 jedis.hmset(serviceInfokey, serviceInfoMap);
\r
365 new_apiRouteInfo.setStatus(status);
\r
368 } catch (Exception e) {
\r
369 LOGGER.error("update ApiRoute status throw exception", e);
\r
370 throw new ExtendedInternalServerErrorException("update ApiRoute status throw exception"
\r
374 JedisUtil.returnJedisInstance(jedis);
\r
377 return new_apiRouteInfo;
\r
382 * @Title: saveApiRouteInstance
\r
383 * @Description: TODO(存储单个服务信息)
\r
384 * @param: @param apiRouteInfo
\r
386 * @return: ApiRouteInfo
\r
388 public synchronized ApiRouteInfo saveApiRouteInstance(ApiRouteInfo apiRouteInfo,
\r
389 String serverPort) {
\r
393 if (StringUtils.isBlank(apiRouteInfo.getServiceName())
\r
394 || apiRouteInfo.getServers().length == 0) {
\r
395 throw new ExtendedNotSupportedException(
\r
396 "save apiRouteInfo FAIL: Some required fields are empty");
\r
399 if (StringUtils.isNotBlank(apiRouteInfo.getVersion())) {
\r
400 if (!RegExpTestUtil.versionRegExpTest(apiRouteInfo.getVersion())) {
\r
401 throw new ExtendedNotSupportedException("version (" + apiRouteInfo.getVersion()
\r
402 + ") is not a valid format");
\r
406 if (StringUtils.isNotBlank(apiRouteInfo.getUrl())) {
\r
407 if (!RegExpTestUtil.urlRegExpTest(apiRouteInfo.getUrl())) {
\r
408 throw new ExtendedNotSupportedException(
\r
409 "save apiRouteInfo FAIL:url is not a valid format(url must be begin with /)");
\r
414 if (!RouteUtil.contain(RouteUtil.visualRangeRange, apiRouteInfo.getVisualRange())) {
\r
415 throw new ExtendedNotSupportedException(
\r
416 "save apiRouteInfo FAIL:VisualRange is wrong,value range:("
\r
417 + RouteUtil.show(RouteUtil.visualRangeMatches) + ")");
\r
420 if (!RouteUtil.contain(RouteUtil.controlRangeMatches, apiRouteInfo.getControl())) {
\r
421 throw new ExtendedNotSupportedException(
\r
422 "save apiRouteInfo FAIL:control is wrong,value range:("
\r
423 + RouteUtil.show(RouteUtil.controlRangeMatches) + ")");
\r
426 if (!RouteUtil.contain(RouteUtil.statusRangeMatches, apiRouteInfo.getStatus())) {
\r
427 throw new ExtendedNotSupportedException(
\r
428 "save apiRouteInfo FAIL:status is wrong,value range:("
\r
429 + RouteUtil.show(RouteUtil.statusRangeMatches) + ")");
\r
432 if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, apiRouteInfo.getUseOwnUpstream())) {
\r
433 throw new ExtendedNotSupportedException(
\r
434 "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:("
\r
435 + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")");
\r
439 RouteServer[] serverList = apiRouteInfo.getServers();
\r
440 for (int i = 0; i < serverList.length; i++) {
\r
441 RouteServer server = serverList[i];
\r
442 if (!RegExpTestUtil.ipRegExpTest(server.getIp())) {
\r
443 throw new ExtendedNotSupportedException("save apiRouteInfo FAIL:IP("
\r
444 + server.getIp() + ")is not a valid ip address");
\r
447 if (!RegExpTestUtil.portRegExpTest(server.getPort())) {
\r
448 throw new ExtendedNotSupportedException("save apiRouteInfo FAIL:Port("
\r
449 + server.getPort() + ")is not a valid Port address");
\r
454 String serviceInfokey =
\r
455 RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE,
\r
456 apiRouteInfo.getServiceName().trim(), apiRouteInfo.getVersion().trim(),
\r
457 RouteUtil.ROUTE_PATH_INFO);
\r
458 Map<String, String> serviceInfoMap = new HashMap<String, String>();
\r
459 serviceInfoMap.put("url", "/".equals(apiRouteInfo.getUrl().trim()) ? "" : apiRouteInfo
\r
461 serviceInfoMap.put("apijson", apiRouteInfo.getApiJson());
\r
462 serviceInfoMap.put("apiJsonType", apiRouteInfo.getApiJsonType());
\r
463 serviceInfoMap.put("metricsUrl", apiRouteInfo.getMetricsUrl());
\r
464 serviceInfoMap.put("control", apiRouteInfo.getControl());
\r
465 serviceInfoMap.put("status", apiRouteInfo.getStatus());
\r
466 serviceInfoMap.put("visualRange", apiRouteInfo.getVisualRange());
\r
467 serviceInfoMap.put("useOwnUpstream", apiRouteInfo.getUseOwnUpstream());
\r
470 String serviceLBkey =
\r
471 RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE,
\r
472 apiRouteInfo.getServiceName(), apiRouteInfo.getVersion(),
\r
473 RouteUtil.ROUTE_PATH_LOADBALANCE);
\r
476 Jedis jedis = null;
\r
478 jedis = JedisUtil.borrowJedisInstance();
\r
479 if (jedis == null) {
\r
480 throw new ExtendedInternalServerErrorException(
\r
481 "fetch from jedis pool failed,null object!");
\r
484 jedis.hmset(serviceInfokey, serviceInfoMap);
\r
487 for (int i = 0; i < serverList.length; i++) {
\r
488 Map<String, String> servermap = new HashMap<String, String>();
\r
489 RouteServer server = serverList[i];
\r
491 servermap.put("ip", server.getIp());
\r
492 servermap.put("port", server.getPort());
\r
493 servermap.put("weight", Integer.toString(server.getWeight()));
\r
495 jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap);
\r
499 // ApiRouteLifeCycle lifeCycle = apiRouteInfo.getLifeCycle();
\r
500 // if (lifeCycle != null) {
\r
501 // String serviceLifekey =
\r
502 // RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE,
\r
503 // apiRouteInfo.getServiceName(), apiRouteInfo.getVersion(),
\r
504 // RouteUtil.APIROUTE_PATH_LIFE);
\r
505 // Map<String, String> serviceLifeMap = new HashMap<String, String>();
\r
506 // serviceLifeMap.put("path", lifeCycle.getInstallPath());
\r
507 // serviceLifeMap.put("start", lifeCycle.getStartScript());
\r
508 // serviceLifeMap.put("stop", lifeCycle.getStopScript());
\r
509 // jedis.hmset(serviceLifekey, serviceLifeMap);
\r
514 } catch (Exception e) {
\r
515 LOGGER.error("call redis throw exception", e);
\r
516 throw new ExtendedInternalServerErrorException("call redis throw exception:"
\r
520 JedisUtil.returnJedisInstance(jedis);
\r
523 return apiRouteInfo;
\r
529 * @Title: deleteApiRoute
\r
530 * @Description: TODO(删除单个服务信息)
\r
531 * @param: @param type
\r
532 * @param: @param serviceName
\r
533 * @param: @param version
\r
534 * @param: @param delKey
\r
538 public synchronized void deleteApiRoute(String serviceName, String version, String delKey,
\r
539 String serverPort) {
\r
541 if ("null".equals(version)) {
\r
545 if (StringUtils.isBlank(serviceName)) {
\r
546 throw new ExtendedNotSupportedException("serviceName can't be empty");
\r
549 if (StringUtils.isNotBlank(version)) {
\r
550 if (!RegExpTestUtil.versionRegExpTest(version)) {
\r
551 throw new ExtendedNotSupportedException("version (" + version
\r
552 + ") is not a valid format");
\r
557 Jedis jedis = null;
\r
559 jedis = JedisUtil.borrowJedisInstance();
\r
560 if (jedis == null) {
\r
561 throw new ExtendedInternalServerErrorException(
\r
562 "fetch from jedis pool failed,null object!");
\r
567 RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE, serviceName, version,
\r
569 Set<String> infoSet = jedis.keys(routekey);
\r
571 if (infoSet.isEmpty()) {
\r
572 throw new ExtendedNotFoundException("delete ApiRoute FAIL:serviceName-"
\r
573 + serviceName + ",version:" + version + " not fond ");
\r
576 String[] paths = new String[infoSet.size()];
\r
579 infoSet.toArray(paths);
\r
584 } catch (ExtendedNotFoundException e) {
\r
586 } catch (Exception e) {
\r
587 LOGGER.error("delete ApiRoute throw exception", e);
\r
588 throw new ExtendedInternalServerErrorException("delete ApiRoute throw exception:"
\r
591 JedisUtil.returnJedisInstance(jedis);
\r
598 * @Title: getAllApiDocs
\r
599 * @Description: TODO(获取本地ext\initSwaggerJson目录的全部json文件目录)
\r
601 * @return: String[]
\r
603 public String[] getAllApiDocs() {
\r
604 URL apiDocsPath = ApiRouteServiceWrapper.class.getResource("/ext/initSwaggerJson");
\r
605 if (apiDocsPath != null) {
\r
606 String path = apiDocsPath.getPath();
\r
609 return readfile(path);
\r
610 } catch (FileNotFoundException e) {
\r
611 // TODO Auto-generated catch block
\r
612 LOGGER.error("read ApiDocs Files throw FileNotFoundException", e);
\r
613 throw new ExtendedInternalServerErrorException("read ApiDocs Files throw FileNotFoundException:"
\r
615 } catch (IOException e) {
\r
616 // TODO Auto-generated catch block
\r
617 LOGGER.error("read ApiDocs Files throw IOexception", e);
\r
618 throw new ExtendedInternalServerErrorException("read ApiDocs Files throw IOexception:"
\r
631 public String[] readfile(String filepath) throws FileNotFoundException, IOException {
\r
632 File file = new File(filepath);
\r
633 if (file.isDirectory()) {
\r
634 String[] filelist = file.list();
\r
640 public String getApiGatewayPort() {
\r
641 // return JedisUtil.serverIp+":"+JedisUtil.serverPort;
\r
642 return System.getenv("APIGATEWAY_EXPOSE_PORT") == null ? String
\r
643 .valueOf(JedisUtil.serverPort) : System.getenv("APIGATEWAY_EXPOSE_PORT");
\r
647 public DiscoverInfo getServiceDiscoverInfo() {
\r
648 return RouteUtil.discoverInfo;
\r