Issue-id: OCS-9
[msb/apigateway.git] / msb-core / apiroute / apiroute-service / src / main / java / org / openo / msb / wrapper / CustomRouteServiceWrapper.java
1 /**
2  * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved.
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.util.HashMap;
19 import java.util.Map;
20 import java.util.Set;
21
22 import org.apache.commons.lang3.StringUtils;
23 import org.openo.msb.api.CustomRouteInfo;
24 import org.openo.msb.api.RouteServer;
25 import org.openo.msb.api.exception.ExtendedInternalServerErrorException;
26 import org.openo.msb.api.exception.ExtendedNotFoundException;
27 import org.openo.msb.api.exception.ExtendedNotSupportedException;
28 import org.openo.msb.wrapper.util.JedisUtil;
29 import org.openo.msb.wrapper.util.RegExpTestUtil;
30 import org.openo.msb.wrapper.util.RouteUtil;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import redis.clients.jedis.Jedis;
35
36 public class CustomRouteServiceWrapper {
37
38
39     private static final Logger LOGGER = LoggerFactory.getLogger(CustomRouteServiceWrapper.class);
40
41     private static CustomRouteServiceWrapper instance = new CustomRouteServiceWrapper();
42
43     private CustomRouteServiceWrapper() {}
44
45     public static CustomRouteServiceWrapper getInstance() {
46         return instance;
47     }
48
49
50     /**
51      * @Title: getAllCustomRouteService
52      * @Description: TODO(获取全部内容服务列表)
53      * @param: @return
54      * @return: CustomRouteInfo[]
55      */
56     public CustomRouteInfo[] getAllCustomRouteInstances() {
57
58
59         Jedis jedis = null;
60         CustomRouteInfo[] customRouteList = 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.getPrefixedKey("", RouteUtil.CUSTOMROUTE, "*",
71                             RouteUtil.ROUTE_PATH_INFO);
72             Set<String> routeSet = jedis.keys(routekey);
73             customRouteList = new CustomRouteInfo[routeSet.size()];
74
75             int i = 0;
76             for (String routePath : routeSet) {
77                 String[] routePathArray = routePath.split(":");
78                 CustomRouteInfo customRoute = getCustomRouteInstance(routePathArray[3], jedis);
79                 customRouteList[i] = customRoute;
80                 i++;
81             }
82
83
84         } catch (Exception e) {
85             LOGGER.error("call redis throw exception", e);
86             throw new ExtendedInternalServerErrorException("call redis throw exception:"
87                     + e.getMessage());
88
89         } finally {
90             JedisUtil.returnJedisInstance(jedis);
91         }
92
93         return customRouteList;
94     }
95
96
97
98     /**
99      * @Title: getCustomRouteInstance
100      * @Description: TODO(通过服务名获取单个内容服务对象信息)
101      * @param: @param serviceName
102      * @param: @return
103      * @return: CustomRouteInfo
104      */
105     public CustomRouteInfo getCustomRouteInstance(String serviceName) {
106
107         if (StringUtils.isBlank(serviceName)) {
108             throw new ExtendedNotSupportedException("serviceName  can't be empty");
109         }
110
111         CustomRouteInfo customRouteInfo;
112
113         Jedis jedis = null;
114         try {
115             jedis = JedisUtil.borrowJedisInstance();
116             if (jedis == null) {
117                 throw new ExtendedInternalServerErrorException(
118                         "fetch from jedis pool failed,null object!");
119             }
120
121             customRouteInfo = getCustomRouteInstance(serviceName, jedis);
122
123
124         } catch (Exception e) {
125             LOGGER.error("call redis throw exception", e);
126             throw new ExtendedInternalServerErrorException("call redis throw exception:"
127                     + e.getMessage());
128         } finally {
129             JedisUtil.returnJedisInstance(jedis);
130         }
131
132         if (null == customRouteInfo) {
133             String errInfo = "customRouteInfo not found: serviceName-" + serviceName;
134             LOGGER.warn(errInfo);
135             throw new ExtendedNotFoundException(errInfo);
136
137         }
138
139         return customRouteInfo;
140
141     }
142
143     public CustomRouteInfo getCustomRouteInstance(String serviceName, Jedis jedis) throws Exception {
144
145
146         CustomRouteInfo customRouteInfo = null;
147
148
149         // 获取info信息
150         String routekey =
151                 RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName,
152                         RouteUtil.ROUTE_PATH_INFO);
153         Map<String, String> infomap = jedis.hgetAll(routekey);
154         if (!infomap.isEmpty()) {
155             customRouteInfo = new CustomRouteInfo();
156             customRouteInfo.setServiceName(serviceName);
157             customRouteInfo.setUrl(infomap.get("url"));
158             customRouteInfo.setControl(infomap.get("control"));
159             customRouteInfo.setStatus(infomap.get("status"));
160             customRouteInfo.setVisualRange(infomap.get("visualRange"));
161             customRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream"));
162
163
164             // 获取负载均衡信息
165             String serviceLBkey =
166                     RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName,
167                             RouteUtil.ROUTE_PATH_LOADBALANCE);
168             Set<String> serviceLBset = jedis.keys(serviceLBkey + ":*");
169             int serverNum = serviceLBset.size();
170             RouteServer[] CustomRouteServerList = new RouteServer[serverNum];
171             int i = 0;
172             for (String serviceInfo : serviceLBset) {
173                 Map<String, String> serviceLBmap = jedis.hgetAll(serviceInfo);
174                 RouteServer server = new RouteServer();
175                 server.setIp(serviceLBmap.get("ip"));
176                 server.setPort(serviceLBmap.get("port"));
177                 server.setWeight(Integer.parseInt(serviceLBmap.get("weight")));
178                 CustomRouteServerList[i] = server;
179                 i++;
180             }
181
182             customRouteInfo.setServers(CustomRouteServerList);
183         }
184
185
186         return customRouteInfo;
187     }
188
189     /**
190      * @Title: updateCustomRouteInstance
191      * @Description: TODO(更新单个服务信息)
192      * @param: @param serviceName
193      * @param: @param CustomRouteInfo
194      * @param: @return
195      * @return: CustomRouteInfo
196      */
197     public synchronized CustomRouteInfo updateCustomRouteInstance(String serviceName,
198             CustomRouteInfo customRouteInfo, String serverPort) {
199         if (StringUtils.isBlank(serviceName)) {
200             throw new ExtendedNotSupportedException("serviceName  can't be empty");
201         }
202
203         try {
204
205             if (serviceName.equals(customRouteInfo.getServiceName())) {
206                 // 删除已存在负载均衡服务器信息
207                 deleteCustomRoute(serviceName, RouteUtil.ROUTE_PATH_LOADBALANCE + "*", serverPort);
208             } else {
209                 // 如果已修改服务名,先删除此服务全部已有信息
210                 deleteCustomRoute(serviceName, "*", serverPort);
211             }
212
213
214             saveCustomRouteInstance(customRouteInfo, serverPort);
215
216
217
218         } catch (ExtendedNotSupportedException e) {
219             throw e;
220         } catch (Exception e) {
221             LOGGER.error("updateCustomRoute throw exception", e);
222             throw new ExtendedInternalServerErrorException("update CustomRoute throw exception"
223                     + e.getMessage());
224
225         }
226
227         return customRouteInfo;
228
229     }
230
231     /**
232      * @Title updateCustomRouteStatus
233      * @Description TODO(更新单个服务状态)
234      * @param serviceName
235      * @param status
236      * @return
237      * @return RouteResult
238      */
239     public synchronized CustomRouteInfo updateCustomRouteStatus(String serviceName, String status) {
240
241         if (StringUtils.isBlank(serviceName)) {
242             throw new ExtendedNotSupportedException("serviceName  can't be empty");
243         }
244
245         if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) {
246             throw new ExtendedNotSupportedException(
247                     "save CustomRouteInfo Status FAIL:status is wrong,value range:("
248                             + RouteUtil.show(RouteUtil.statusRangeMatches) + ")");
249         }
250
251         CustomRouteInfo new_customRouteInfo = getCustomRouteInstance(serviceName);
252
253
254
255         // 准备info信息
256         String serviceInfokey =
257                 RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName,
258                         RouteUtil.ROUTE_PATH_INFO);
259         Map<String, String> serviceInfoMap = new HashMap<String, String>();
260         serviceInfoMap.put("status", status);
261
262
263         Jedis jedis = null;
264         try {
265             jedis = JedisUtil.borrowJedisInstance();
266             if (jedis == null) {
267                 throw new ExtendedInternalServerErrorException(
268                         "fetch from jedis pool failed,null object!");
269             }
270             // 保存info信息
271             jedis.hmset(serviceInfokey, serviceInfoMap);
272             new_customRouteInfo.setStatus(status);
273
274         } catch (Exception e) {
275
276             LOGGER.error("update CustomRoute status throw exception", e);
277             throw new ExtendedInternalServerErrorException(
278                     "update CustomRoute status throw exception" + e.getMessage());
279
280         } finally {
281             JedisUtil.returnJedisInstance(jedis);
282         }
283
284         return new_customRouteInfo;
285     }
286
287     /**
288      * @Title: saveCustomRouteInstance
289      * @Description: TODO(存储单个服务信息)
290      * @param: @param CustomRouteInfo
291      * @param: @return
292      * @return: CustomRouteInfo
293      */
294     public synchronized CustomRouteInfo saveCustomRouteInstance(CustomRouteInfo customRouteInfo,
295             String serverPort) {
296
297         if (StringUtils.isBlank(customRouteInfo.getServiceName())
298                 || customRouteInfo.getServers().length == 0) {
299             throw new ExtendedNotSupportedException(
300                     "save CustomRouteInfo FAIL: Some required fields are empty");
301         }
302
303        
304             if (!RegExpTestUtil.urlRegExpTest(customRouteInfo.getServiceName())) {
305                 throw new ExtendedNotSupportedException(
306                         "save CustomRouteInfo FAIL: ServiceName is not a valid format(ServiceName must be begin with /)");
307     
308             }
309         
310             if (StringUtils.isNotBlank(customRouteInfo.getUrl())){
311                 if (!RegExpTestUtil.urlRegExpTest(customRouteInfo.getUrl())) {
312                     throw new ExtendedNotSupportedException(
313                             "save CustomRouteInfo FAIL:url is not a valid format(url must be begin with /)");
314         
315                 }
316             }
317
318         if (!RouteUtil.contain(RouteUtil.visualRangeRange, customRouteInfo.getVisualRange())) {
319             throw new ExtendedNotSupportedException(
320                     "save CustomRouteInfo FAIL:VisualRange is wrong,value range:("
321                             + RouteUtil.show(RouteUtil.visualRangeMatches) + ")");
322         }
323
324         if (!RouteUtil.contain(RouteUtil.controlRangeMatches, customRouteInfo.getControl())) {
325             throw new ExtendedNotSupportedException(
326                     "save CustomRouteInfo FAIL:control is wrong,value range:("
327                             + RouteUtil.show(RouteUtil.controlRangeMatches) + ")");
328         }
329
330         if (!RouteUtil.contain(RouteUtil.statusRangeMatches, customRouteInfo.getStatus())) {
331             throw new ExtendedNotSupportedException(
332                     "save CustomRouteInfo FAIL:status is wrong,value range:("
333                             + RouteUtil.show(RouteUtil.statusRangeMatches) + ")");
334         }
335
336         if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, customRouteInfo.getUseOwnUpstream())) {
337             throw new ExtendedNotSupportedException(
338                     "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:("
339                             + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")");
340         }
341
342         // 检查服务实例格式
343         RouteServer[] serverList = customRouteInfo.getServers();
344         for (int i = 0; i < serverList.length; i++) {
345             RouteServer server = serverList[i];
346             if (!RegExpTestUtil.ipRegExpTest(server.getIp())) {
347                 throw new ExtendedNotSupportedException("save CustomRouteInfo FAIL:IP("
348                         + server.getIp() + ")is not a valid ip address");
349             }
350
351             if (!RegExpTestUtil.portRegExpTest(server.getPort())) {
352                 throw new ExtendedNotSupportedException("save CustomRouteInfo FAIL:Port("
353                         + server.getPort() + ")is not a valid Port address");
354             }
355         }
356
357
358         // 准备info信息
359         String serviceInfokey =
360                 RouteUtil.getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE,
361                         customRouteInfo.getServiceName().trim(), RouteUtil.ROUTE_PATH_INFO);
362         Map<String, String> serviceInfoMap = new HashMap<String, String>();
363         serviceInfoMap.put("url", "/".equals(customRouteInfo.getUrl().trim())
364                 ? ""
365                 : customRouteInfo.getUrl().trim());
366         serviceInfoMap.put("control", customRouteInfo.getControl());
367         serviceInfoMap.put("status", customRouteInfo.getStatus());
368         serviceInfoMap.put("visualRange", customRouteInfo.getVisualRange());
369         serviceInfoMap.put("useOwnUpstream", customRouteInfo.getUseOwnUpstream());
370
371
372
373         // 准备负载均衡信息
374         String serviceLBkey =
375                 RouteUtil.getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE,
376                         customRouteInfo.getServiceName(), RouteUtil.ROUTE_PATH_LOADBALANCE);
377
378
379         Jedis jedis = null;
380         try {
381             jedis = JedisUtil.borrowJedisInstance();
382             if (jedis == null) {
383                 throw new ExtendedInternalServerErrorException(
384                         "fetch from jedis pool failed,null object!");
385             }
386             // 保存info信息
387             jedis.hmset(serviceInfokey, serviceInfoMap);
388
389             // 保存负载均衡信息
390
391             for (int i = 0; i < serverList.length; i++) {
392                 Map<String, String> servermap = new HashMap<String, String>();
393                 RouteServer server = serverList[i];
394
395                 servermap.put("ip", server.getIp());
396                 servermap.put("port", server.getPort());
397                 servermap.put("weight", Integer.toString(server.getWeight()));
398
399                 jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap);
400             }
401
402
403         } catch (Exception e) {
404             LOGGER.error("call redis throw exception", e);
405             throw new ExtendedInternalServerErrorException("call redis throw exception:"
406                     + e.getMessage());
407
408         } finally {
409             JedisUtil.returnJedisInstance(jedis);;
410         }
411
412         return customRouteInfo;
413     }
414
415
416
417     /**
418      * @Title: deleteCustomRoute
419      * @Description: TODO(删除单个服务信息)
420      * @param: @param type
421      * @param: @param serviceName
422      * @param: @param delKey
423      * @param: @return
424      * @return: void
425      */
426     public synchronized void deleteCustomRoute(String serviceName, String delKey, String serverPort) {
427
428         if (StringUtils.isBlank(serviceName)) {
429             throw new ExtendedNotSupportedException("serviceName  can't be empty");
430         }
431
432         Jedis jedis = null;
433
434         try {
435             jedis = JedisUtil.borrowJedisInstance();
436             if (jedis == null) {
437                 throw new ExtendedInternalServerErrorException(
438                         "fetch from jedis pool failed,null object!");
439             }
440
441             // 获取info信息
442             String routekey =
443                     RouteUtil
444                             .getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE, serviceName, delKey);
445             Set<String> infoSet = jedis.keys(routekey);
446
447             if (infoSet.isEmpty()) {
448                 throw new ExtendedNotFoundException("delete CustomRoute FAIL:serviceName-"
449                         + serviceName + " not fond ");
450             }
451
452
453             String[] paths = new String[infoSet.size()];
454
455             // Set-->数组
456             infoSet.toArray(paths);
457
458             jedis.del(paths);
459
460         } catch (ExtendedNotFoundException e) {
461             throw e;
462         } catch (Exception e) {
463
464             LOGGER.error("delete CustomRoute throw exception", e);
465             throw new ExtendedInternalServerErrorException("delete CustomRoute throw exception:"
466                     + e.getMessage());
467
468         } finally {
469             JedisUtil.returnJedisInstance(jedis);
470         }
471
472
473     }
474 }