msb protocol synch change
[msb/apigateway.git] / msb-core / apiroute / apiroute-service / src / main / java / org / openo / msb / wrapper / ApiRouteServiceWrapper.java
1 /**
2  * Copyright 2016 ZTE Corporation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.openo.msb.wrapper;
17
18 import java.io.File;
19 import java.io.FileNotFoundException;
20 import java.io.IOException;
21 import java.net.URL;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.apache.commons.lang3.StringUtils;
27 import org.openo.msb.api.ApiRouteInfo;
28 import org.openo.msb.api.DiscoverInfo;
29 import org.openo.msb.api.RouteServer;
30 import org.openo.msb.api.exception.ExtendedInternalServerErrorException;
31 import org.openo.msb.api.exception.ExtendedNotFoundException;
32 import org.openo.msb.api.exception.ExtendedNotSupportedException;
33 import org.openo.msb.wrapper.util.JedisUtil;
34 import org.openo.msb.wrapper.util.RegExpTestUtil;
35 import org.openo.msb.wrapper.util.RouteUtil;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 import redis.clients.jedis.Jedis;
40
41
42 public class ApiRouteServiceWrapper {
43
44     private static final Logger LOGGER = LoggerFactory.getLogger(ApiRouteServiceWrapper.class);
45
46
47     private static ApiRouteServiceWrapper instance = new ApiRouteServiceWrapper();
48
49     private ApiRouteServiceWrapper() {}
50
51     public static ApiRouteServiceWrapper getInstance() {
52         return instance;
53     }
54
55   
56     public ApiRouteInfo[] getAllApiRouteInstances() {
57
58
59         Jedis jedis = null;
60         ApiRouteInfo[] apiRouteList = null;
61         try {
62             jedis = JedisUtil.borrowJedisInstance();
63             if (jedis == null) {
64                 throw new ExtendedInternalServerErrorException(
65                         "fetch from jedis pool failed,null object!");
66             }
67
68       
69             String routekey =
70                     RouteUtil
71                             .getPrefixedKey("", RouteUtil.APIROUTE, "*", RouteUtil.ROUTE_PATH_INFO);
72             Set<String> routeSet = jedis.keys(routekey);
73             apiRouteList = new ApiRouteInfo[routeSet.size()];
74
75             int i = 0;
76             for (String routePath : routeSet) {
77                 String[] routePathArray = routePath.split(":");
78                 ApiRouteInfo apiRoute =
79                         getApiRouteInstance(routePathArray[3], routePathArray[4], jedis);
80                 apiRouteList[i] = apiRoute;
81                 i++;
82             }
83
84
85         } catch (Exception e) {
86             LOGGER.error("call redis throw exception", e);
87             throw new ExtendedInternalServerErrorException("call redis throw exception:"
88                     + e.getMessage());
89
90         } finally {
91             JedisUtil.returnJedisInstance(jedis);
92         }
93
94         return apiRouteList;
95     }
96
97
98
99     public static boolean checkRedisConnect() {
100
101         Jedis jedis = null;
102         try {
103             jedis = JedisUtil.borrowJedisInstance();
104             if (jedis != null) {
105                 return true;
106             }
107         } catch (Exception e) {
108             LOGGER.error("call redis throw exception", e);
109         } finally {
110             JedisUtil.returnJedisInstance(jedis);
111         }
112
113         return false;
114     }
115
116  
117     public ApiRouteInfo getApiRouteInstance(String serviceName, String version) {
118
119         if (StringUtils.isBlank(serviceName)) {
120             throw new ExtendedNotSupportedException("serviceName  can't be empty");
121         }
122
123         if (StringUtils.isNotBlank(version)) {
124             if (!RegExpTestUtil.versionRegExpTest(version)) {
125                 throw new ExtendedNotSupportedException("version (" + version
126                         + ") is not a valid  format");
127             }
128         }
129
130
131         ApiRouteInfo apiRouteInfo = null;
132
133         Jedis jedis = null;
134         try {
135             jedis = JedisUtil.borrowJedisInstance();
136             if (jedis == null) {
137                 throw new ExtendedInternalServerErrorException(
138                         "fetch from jedis pool failed,null object!");
139             }
140
141             apiRouteInfo = getApiRouteInstance(serviceName, version, jedis);
142
143
144         } catch (Exception e) {
145             LOGGER.error("call redis throw exception", e);
146             throw new ExtendedInternalServerErrorException("call redis throw exception:"
147                     + e.getMessage());
148
149         } finally {
150             JedisUtil.returnJedisInstance(jedis);
151         }
152
153         if (null == apiRouteInfo) {
154             String errInfo =
155                     "ApiRouteInfo not found: serviceName-" + serviceName + " ,version-" + version;
156             LOGGER.warn(errInfo);
157             throw new ExtendedNotFoundException(errInfo);
158
159         }
160
161         return apiRouteInfo;
162
163     }
164
165     public ApiRouteInfo getApiRouteInstance(String serviceName, String version, Jedis jedis)
166             throws Exception {
167         if ("null".equals(version)) {
168             version = "";
169         }
170
171         ApiRouteInfo apiRouteInfo = null;
172
173
174    
175         String routekey =
176                 RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version,
177                         RouteUtil.ROUTE_PATH_INFO);
178         Map<String, String> infomap = jedis.hgetAll(routekey);
179         if (!infomap.isEmpty()) {
180             apiRouteInfo = new ApiRouteInfo();
181             apiRouteInfo.setServiceName(serviceName);
182             apiRouteInfo.setVersion(version);
183             apiRouteInfo.setUrl(infomap.get("url"));
184             apiRouteInfo.setMetricsUrl(infomap.get("metricsUrl"));
185             apiRouteInfo.setApiJson(infomap.get("apijson"));
186             apiRouteInfo.setApiJsonType(infomap.get("apiJsonType"));
187             apiRouteInfo.setControl(infomap.get("control"));
188             apiRouteInfo.setStatus(infomap.get("status"));
189             apiRouteInfo.setVisualRange(infomap.get("visualRange"));
190             apiRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream"));
191
192
193         
194             String serviceLBkey =
195                     RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version,
196                             RouteUtil.ROUTE_PATH_LOADBALANCE);
197             Set<String> serviceLBset = jedis.keys(serviceLBkey + ":*");
198             int serverNum = serviceLBset.size();
199             RouteServer[] apiRouteServerList = new RouteServer[serverNum];
200             int i = 0;
201             for (String serviceInfo : serviceLBset) {
202                 Map<String, String> serviceLBmap = jedis.hgetAll(serviceInfo);
203                 RouteServer server = new RouteServer();
204                 server.setIp(serviceLBmap.get("ip"));
205                 server.setPort(serviceLBmap.get("port"));
206                 server.setWeight(Integer.parseInt(serviceLBmap.get("weight")));
207                 apiRouteServerList[i] = server;
208                 i++;
209             }
210
211             apiRouteInfo.setServers(apiRouteServerList);
212
213          
214         }
215
216
217         return apiRouteInfo;
218     }
219
220   
221     public synchronized ApiRouteInfo updateApiRouteInstance(String serviceName, String version,
222             ApiRouteInfo apiRouteInfo, String serverPort) {
223
224         if ("null".equals(version)) {
225             version = "";
226         }
227         
228         if (StringUtils.isBlank(serviceName)) {
229             throw new ExtendedNotSupportedException("serviceName  can't be empty");
230         }
231
232         if (StringUtils.isNotBlank(version)) {
233             if (!RegExpTestUtil.versionRegExpTest(version)) {
234                 throw new ExtendedNotSupportedException("version (" + version
235                         + ") is not a valid  format");
236             }
237         }
238
239         
240
241
242         try {
243
244
245             if (serviceName.equals(apiRouteInfo.getServiceName())
246                     && version.equals(apiRouteInfo.getVersion())) {
247           
248                 deleteApiRoute(serviceName, version, RouteUtil.ROUTE_PATH_LOADBALANCE + "*",
249                         serverPort);
250
251             } else {
252            
253                 deleteApiRoute(serviceName, version, "*", serverPort);
254             }
255
256
257             saveApiRouteInstance(apiRouteInfo, serverPort);
258
259
260         } catch (ExtendedNotSupportedException e) {
261             throw e;
262         } catch (Exception e) {
263             LOGGER.error("update ApiRoute throw exception", e);
264             throw new ExtendedInternalServerErrorException("update apiRouteInfo throw exception"
265                     + e.getMessage());
266
267         }
268
269         return apiRouteInfo;
270
271     }
272
273    
274     public synchronized ApiRouteInfo updateApiRouteStatus(String serviceName, String version,
275             String status) {
276
277         if ("null".equals(version)) {
278             version = "";
279         }
280         
281         if (StringUtils.isBlank(serviceName)) {
282             throw new ExtendedNotSupportedException("serviceName  can't be empty");
283         }
284
285         if (StringUtils.isNotBlank(version)) {
286             if (!RegExpTestUtil.versionRegExpTest(version)) {
287                 throw new ExtendedNotSupportedException("version (" + version
288                         + ") is not a valid  format");
289             }
290         }
291
292         if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) {
293             throw new ExtendedNotSupportedException(
294                     "save ApiRouteInfo  Status FAIL:status is wrong,value range:("
295                             + RouteUtil.show(RouteUtil.statusRangeMatches) + ")");
296         }
297
298         ApiRouteInfo new_apiRouteInfo = getApiRouteInstance(serviceName, version);
299
300
301
302         String serviceInfokey =
303                 RouteUtil.getPrefixedKey("", RouteUtil.APIROUTE, serviceName, version,
304                         RouteUtil.ROUTE_PATH_INFO);
305         Map<String, String> serviceInfoMap = new HashMap<String, String>();
306         serviceInfoMap.put("status", status);
307
308
309         Jedis jedis = null;
310         try {
311             jedis = JedisUtil.borrowJedisInstance();
312             if (jedis == null) {
313                 throw new Exception("fetch from jedis pool failed,null object!");
314             }
315    
316             jedis.hmset(serviceInfokey, serviceInfoMap);
317             new_apiRouteInfo.setStatus(status);
318
319
320         } catch (Exception e) {
321             LOGGER.error("update ApiRoute status throw exception", e);
322             throw new ExtendedInternalServerErrorException("update ApiRoute status throw exception"
323                     + e.getMessage());
324
325         } finally {
326             JedisUtil.returnJedisInstance(jedis);
327         }
328
329         return new_apiRouteInfo;
330     }
331
332
333    
334     public synchronized ApiRouteInfo saveApiRouteInstance(ApiRouteInfo apiRouteInfo,
335             String serverPort) {
336
337        
338         
339         if (StringUtils.isBlank(apiRouteInfo.getServiceName())
340                 || apiRouteInfo.getServers().length == 0) {
341             throw new ExtendedNotSupportedException(
342                     "save apiRouteInfo FAIL: Some required fields are empty");
343         }
344
345         if (StringUtils.isNotBlank(apiRouteInfo.getVersion())) {
346             if (!RegExpTestUtil.versionRegExpTest(apiRouteInfo.getVersion())) {
347                 throw new ExtendedNotSupportedException("version (" + apiRouteInfo.getVersion()
348                         + ") is not a valid  format");
349             }
350         }
351
352         if (StringUtils.isNotBlank(apiRouteInfo.getUrl())) {
353             if (!RegExpTestUtil.urlRegExpTest(apiRouteInfo.getUrl())) {
354                 throw new ExtendedNotSupportedException(
355                         "save apiRouteInfo FAIL:url is not a valid format(url must be begin with /)");
356     
357             }
358         }
359
360         if (!RouteUtil.contain(RouteUtil.visualRangeRange, apiRouteInfo.getVisualRange())) {
361             throw new ExtendedNotSupportedException(
362                     "save apiRouteInfo FAIL:VisualRange is wrong,value range:("
363                             + RouteUtil.show(RouteUtil.visualRangeMatches) + ")");
364         }
365
366         if (!RouteUtil.contain(RouteUtil.controlRangeMatches, apiRouteInfo.getControl())) {
367             throw new ExtendedNotSupportedException(
368                     "save apiRouteInfo FAIL:control is wrong,value range:("
369                             + RouteUtil.show(RouteUtil.controlRangeMatches) + ")");
370         }
371
372         if (!RouteUtil.contain(RouteUtil.statusRangeMatches, apiRouteInfo.getStatus())) {
373             throw new ExtendedNotSupportedException(
374                     "save apiRouteInfo FAIL:status is wrong,value range:("
375                             + RouteUtil.show(RouteUtil.statusRangeMatches) + ")");
376         }
377
378         if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, apiRouteInfo.getUseOwnUpstream())) {
379             throw new ExtendedNotSupportedException(
380                     "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:("
381                             + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")");
382         }
383
384        
385         RouteServer[] serverList = apiRouteInfo.getServers();
386         for (int i = 0; i < serverList.length; i++) {
387             RouteServer server = serverList[i];
388             if (!RegExpTestUtil.ipRegExpTest(server.getIp())) {
389                 throw new ExtendedNotSupportedException("save apiRouteInfo FAIL:IP("
390                         + server.getIp() + ")is not a valid ip address");
391             }
392
393             if (!RegExpTestUtil.portRegExpTest(server.getPort())) {
394                 throw new ExtendedNotSupportedException("save apiRouteInfo FAIL:Port("
395                         + server.getPort() + ")is not a valid Port address");
396             }
397         }
398
399
400         String serviceInfokey =
401                 RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE,
402                         apiRouteInfo.getServiceName().trim(), apiRouteInfo.getVersion().trim(),
403                         RouteUtil.ROUTE_PATH_INFO);
404         Map<String, String> serviceInfoMap = new HashMap<String, String>();
405         serviceInfoMap.put("url", "/".equals(apiRouteInfo.getUrl().trim()) ? "" : apiRouteInfo
406                 .getUrl().trim());
407         serviceInfoMap.put("apijson", apiRouteInfo.getApiJson());
408         serviceInfoMap.put("apiJsonType", apiRouteInfo.getApiJsonType());
409         serviceInfoMap.put("metricsUrl", apiRouteInfo.getMetricsUrl());
410         serviceInfoMap.put("control", apiRouteInfo.getControl());
411         serviceInfoMap.put("status", apiRouteInfo.getStatus());
412         serviceInfoMap.put("visualRange", apiRouteInfo.getVisualRange());
413         serviceInfoMap.put("useOwnUpstream", apiRouteInfo.getUseOwnUpstream());
414
415
416         String serviceLBkey =
417                 RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE,
418                         apiRouteInfo.getServiceName(), apiRouteInfo.getVersion(),
419                         RouteUtil.ROUTE_PATH_LOADBALANCE);
420
421
422         Jedis jedis = null;
423         try {
424             jedis = JedisUtil.borrowJedisInstance();
425             if (jedis == null) {
426                 throw new ExtendedInternalServerErrorException(
427                         "fetch from jedis pool failed,null object!");
428             }
429             jedis.hmset(serviceInfokey, serviceInfoMap);
430
431    
432             for (int i = 0; i < serverList.length; i++) {
433                 Map<String, String> servermap = new HashMap<String, String>();
434                 RouteServer server = serverList[i];
435
436                 servermap.put("ip", server.getIp());
437                 servermap.put("port", server.getPort());
438                 servermap.put("weight", Integer.toString(server.getWeight()));
439
440                 jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap);
441             }
442            
443
444         } catch (Exception e) {
445             LOGGER.error("call redis throw exception", e);
446             throw new ExtendedInternalServerErrorException("call redis throw exception:"
447                     + e.getMessage());
448
449         } finally {
450             JedisUtil.returnJedisInstance(jedis);
451         }
452
453         return apiRouteInfo;
454     }
455
456
457
458
459     public synchronized void deleteApiRoute(String serviceName, String version, String delKey,
460             String serverPort) {
461
462         if ("null".equals(version)) {
463             version = "";
464         }
465         
466         if (StringUtils.isBlank(serviceName)) {
467             throw new ExtendedNotSupportedException("serviceName  can't be empty");
468         }
469
470         if (StringUtils.isNotBlank(version)) {
471             if (!RegExpTestUtil.versionRegExpTest(version)) {
472                 throw new ExtendedNotSupportedException("version (" + version
473                         + ") is not a valid  format");
474             }
475         }
476
477         
478         Jedis jedis = null;
479         try {
480             jedis = JedisUtil.borrowJedisInstance();
481             if (jedis == null) {
482                 throw new ExtendedInternalServerErrorException(
483                         "fetch from jedis pool failed,null object!");
484             }
485
486
487             String routekey =
488                     RouteUtil.getPrefixedKey(serverPort, RouteUtil.APIROUTE, serviceName, version,
489                             delKey);
490             Set<String> infoSet = jedis.keys(routekey);
491
492             if (infoSet.isEmpty()) {
493               LOGGER.warn("delete ApiRoute FAIL:serviceName-"
494                   + serviceName + ",version:" + version + " not fond ");
495             }
496             else{
497
498                           String[] paths = new String[infoSet.size()];
499               infoSet.toArray(paths);
500               jedis.del(paths);
501             }
502
503
504         } catch (ExtendedNotFoundException e) {
505             throw e;
506         } catch (Exception e) {
507             LOGGER.error("delete ApiRoute throw exception", e);
508             throw new ExtendedInternalServerErrorException("delete ApiRoute throw exception:"
509                     + e.getMessage());
510         } finally {
511             JedisUtil.returnJedisInstance(jedis);
512         }
513
514
515     }
516
517  
518     public String[] getAllApiDocs() {
519         URL apiDocsPath = ApiRouteServiceWrapper.class.getResource("/ext/initSwaggerJson");
520         if (apiDocsPath != null) {
521             String path = apiDocsPath.getPath();
522
523             try {
524                 return readfile(path);
525             } catch (FileNotFoundException e) {
526                 // TODO Auto-generated catch block
527                 LOGGER.error("read  ApiDocs Files throw FileNotFoundException", e);
528                 throw new ExtendedInternalServerErrorException("read  ApiDocs Files throw FileNotFoundException:"
529                         + e.getMessage());
530             } catch (IOException e) {
531                 // TODO Auto-generated catch block
532                 LOGGER.error("read  ApiDocs Files throw IOexception", e);
533                 throw new ExtendedInternalServerErrorException("read  ApiDocs Files throw IOexception:"
534                         + e.getMessage());
535             }
536
537         }
538
539
540         return null;
541     }
542
543     public String[] readfile(String filepath) throws FileNotFoundException, IOException {
544         File file = new File(filepath);
545         if (file.isDirectory()) {
546             String[] filelist = file.list();
547             return filelist;
548         }
549         return null;
550     }
551
552     public String getApiGatewayPort() {
553         // return JedisUtil.serverIp+":"+JedisUtil.serverPort;
554         return System.getenv("APIGATEWAY_EXPOSE_PORT") == null ? String
555                 .valueOf(JedisUtil.serverPort) : System.getenv("APIGATEWAY_EXPOSE_PORT");
556
557     }
558
559     public DiscoverInfo getServiceDiscoverInfo() {
560         return RouteUtil.discoverInfo;
561
562     }
563
564
565 }