msb protocol synch change
[msb/apigateway.git] / msb-core / apiroute / apiroute-service / src / main / java / org / openo / msb / wrapper / CustomRouteServiceWrapper.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.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     public CustomRouteInfo[] getAllCustomRouteInstances() {
52
53
54         Jedis jedis = null;
55         CustomRouteInfo[] customRouteList = null;
56         try {
57             jedis = JedisUtil.borrowJedisInstance();
58             if (jedis == null) {
59                 throw new ExtendedInternalServerErrorException(
60                         "fetch from jedis pool failed,null object!");
61             }
62
63             String routekey =
64                     RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, "*",
65                             RouteUtil.ROUTE_PATH_INFO);
66             Set<String> routeSet = jedis.keys(routekey);
67             customRouteList = new CustomRouteInfo[routeSet.size()];
68
69             int i = 0;
70             for (String routePath : routeSet) {
71                 String[] routePathArray = routePath.split(":");
72                 CustomRouteInfo customRoute = getCustomRouteInstance(routePathArray[3], jedis);
73                 customRouteList[i] = customRoute;
74                 i++;
75             }
76
77
78         } catch (Exception e) {
79             LOGGER.error("call redis throw exception", e);
80             throw new ExtendedInternalServerErrorException("call redis throw exception:"
81                     + e.getMessage());
82
83         } finally {
84             JedisUtil.returnJedisInstance(jedis);
85         }
86
87         return customRouteList;
88     }
89
90
91
92     public CustomRouteInfo getCustomRouteInstance(String serviceName) {
93
94         if (StringUtils.isBlank(serviceName)) {
95             throw new ExtendedNotSupportedException("serviceName  can't be empty");
96         }
97
98         CustomRouteInfo customRouteInfo;
99
100         Jedis jedis = null;
101         try {
102             jedis = JedisUtil.borrowJedisInstance();
103             if (jedis == null) {
104                 throw new ExtendedInternalServerErrorException(
105                         "fetch from jedis pool failed,null object!");
106             }
107
108             customRouteInfo = getCustomRouteInstance(serviceName, jedis);
109
110
111         } catch (Exception e) {
112             LOGGER.error("call redis throw exception", e);
113             throw new ExtendedInternalServerErrorException("call redis throw exception:"
114                     + e.getMessage());
115         } finally {
116             JedisUtil.returnJedisInstance(jedis);
117         }
118
119         if (null == customRouteInfo) {
120             String errInfo = "customRouteInfo not found: serviceName-" + serviceName;
121             LOGGER.warn(errInfo);
122             throw new ExtendedNotFoundException(errInfo);
123
124         }
125
126         return customRouteInfo;
127
128     }
129
130     public CustomRouteInfo getCustomRouteInstance(String serviceName, Jedis jedis) throws Exception {
131
132
133         CustomRouteInfo customRouteInfo = null;
134
135
136         String routekey =
137                 RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName,
138                         RouteUtil.ROUTE_PATH_INFO);
139         Map<String, String> infomap = jedis.hgetAll(routekey);
140         if (!infomap.isEmpty()) {
141             customRouteInfo = new CustomRouteInfo();
142             customRouteInfo.setServiceName(serviceName);
143             customRouteInfo.setUrl(infomap.get("url"));
144             customRouteInfo.setControl(infomap.get("control"));
145             customRouteInfo.setStatus(infomap.get("status"));
146             customRouteInfo.setVisualRange(infomap.get("visualRange"));
147             customRouteInfo.setUseOwnUpstream(infomap.get("useOwnUpstream"));
148
149
150             String serviceLBkey =
151                     RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName,
152                             RouteUtil.ROUTE_PATH_LOADBALANCE);
153             Set<String> serviceLBset = jedis.keys(serviceLBkey + ":*");
154             int serverNum = serviceLBset.size();
155             RouteServer[] CustomRouteServerList = new RouteServer[serverNum];
156             int i = 0;
157             for (String serviceInfo : serviceLBset) {
158                 Map<String, String> serviceLBmap = jedis.hgetAll(serviceInfo);
159                 RouteServer server = new RouteServer();
160                 server.setIp(serviceLBmap.get("ip"));
161                 server.setPort(serviceLBmap.get("port"));
162                 server.setWeight(Integer.parseInt(serviceLBmap.get("weight")));
163                 CustomRouteServerList[i] = server;
164                 i++;
165             }
166
167             customRouteInfo.setServers(CustomRouteServerList);
168         }
169
170
171         return customRouteInfo;
172     }
173
174     public synchronized CustomRouteInfo updateCustomRouteInstance(String serviceName,
175             CustomRouteInfo customRouteInfo, String serverPort) {
176         if (StringUtils.isBlank(serviceName)) {
177             throw new ExtendedNotSupportedException("serviceName  can't be empty");
178         }
179
180         try {
181
182             if (serviceName.equals(customRouteInfo.getServiceName())) {
183                 deleteCustomRoute(serviceName, RouteUtil.ROUTE_PATH_LOADBALANCE + "*", serverPort);
184             } else {
185                 deleteCustomRoute(serviceName, "*", serverPort);
186             }
187
188
189             saveCustomRouteInstance(customRouteInfo, serverPort);
190
191
192
193         } catch (ExtendedNotSupportedException e) {
194             throw e;
195         } catch (Exception e) {
196             LOGGER.error("updateCustomRoute throw exception", e);
197             throw new ExtendedInternalServerErrorException("update CustomRoute throw exception"
198                     + e.getMessage());
199
200         }
201
202         return customRouteInfo;
203
204     }
205
206     public synchronized CustomRouteInfo updateCustomRouteStatus(String serviceName, String status) {
207
208         if (StringUtils.isBlank(serviceName)) {
209             throw new ExtendedNotSupportedException("serviceName  can't be empty");
210         }
211
212         if (!RouteUtil.contain(RouteUtil.statusRangeMatches, status)) {
213             throw new ExtendedNotSupportedException(
214                     "save CustomRouteInfo Status FAIL:status is wrong,value range:("
215                             + RouteUtil.show(RouteUtil.statusRangeMatches) + ")");
216         }
217
218         CustomRouteInfo new_customRouteInfo = getCustomRouteInstance(serviceName);
219
220
221
222         String serviceInfokey =
223                 RouteUtil.getPrefixedKey("", RouteUtil.CUSTOMROUTE, serviceName,
224                         RouteUtil.ROUTE_PATH_INFO);
225         Map<String, String> serviceInfoMap = new HashMap<String, String>();
226         serviceInfoMap.put("status", status);
227
228
229         Jedis jedis = null;
230         try {
231             jedis = JedisUtil.borrowJedisInstance();
232             if (jedis == null) {
233                 throw new ExtendedInternalServerErrorException(
234                         "fetch from jedis pool failed,null object!");
235             }
236             jedis.hmset(serviceInfokey, serviceInfoMap);
237             new_customRouteInfo.setStatus(status);
238
239         } catch (Exception e) {
240
241             LOGGER.error("update CustomRoute status throw exception", e);
242             throw new ExtendedInternalServerErrorException(
243                     "update CustomRoute status throw exception" + e.getMessage());
244
245         } finally {
246             JedisUtil.returnJedisInstance(jedis);
247         }
248
249         return new_customRouteInfo;
250     }
251
252     public synchronized CustomRouteInfo saveCustomRouteInstance(CustomRouteInfo customRouteInfo,
253             String serverPort) {
254
255         if (StringUtils.isBlank(customRouteInfo.getServiceName())
256                 || customRouteInfo.getServers().length == 0) {
257             throw new ExtendedNotSupportedException(
258                     "save CustomRouteInfo FAIL: Some required fields are empty");
259         }
260
261        
262             if (!RegExpTestUtil.urlRegExpTest(customRouteInfo.getServiceName())) {
263                 throw new ExtendedNotSupportedException(
264                         "save CustomRouteInfo FAIL: ServiceName is not a valid format(ServiceName must be begin with /)");
265     
266             }
267         
268             if (StringUtils.isNotBlank(customRouteInfo.getUrl())){
269                 if (!RegExpTestUtil.urlRegExpTest(customRouteInfo.getUrl())) {
270                     throw new ExtendedNotSupportedException(
271                             "save CustomRouteInfo FAIL:url is not a valid format(url must be begin with /)");
272         
273                 }
274             }
275
276         if (!RouteUtil.contain(RouteUtil.visualRangeRange, customRouteInfo.getVisualRange())) {
277             throw new ExtendedNotSupportedException(
278                     "save CustomRouteInfo FAIL:VisualRange is wrong,value range:("
279                             + RouteUtil.show(RouteUtil.visualRangeMatches) + ")");
280         }
281
282         if (!RouteUtil.contain(RouteUtil.controlRangeMatches, customRouteInfo.getControl())) {
283             throw new ExtendedNotSupportedException(
284                     "save CustomRouteInfo FAIL:control is wrong,value range:("
285                             + RouteUtil.show(RouteUtil.controlRangeMatches) + ")");
286         }
287
288         if (!RouteUtil.contain(RouteUtil.statusRangeMatches, customRouteInfo.getStatus())) {
289             throw new ExtendedNotSupportedException(
290                     "save CustomRouteInfo FAIL:status is wrong,value range:("
291                             + RouteUtil.show(RouteUtil.statusRangeMatches) + ")");
292         }
293
294         if (!RouteUtil.contain(RouteUtil.useOwnUpstreamRangeMatches, customRouteInfo.getUseOwnUpstream())) {
295             throw new ExtendedNotSupportedException(
296                     "save apiRouteInfo FAIL:useOwnUpstream is wrong,value range:("
297                             + RouteUtil.show(RouteUtil.useOwnUpstreamRangeMatches) + ")");
298         }
299
300         RouteServer[] serverList = customRouteInfo.getServers();
301         for (int i = 0; i < serverList.length; i++) {
302             RouteServer server = serverList[i];
303             if (!RegExpTestUtil.ipRegExpTest(server.getIp())) {
304                 throw new ExtendedNotSupportedException("save CustomRouteInfo FAIL:IP("
305                         + server.getIp() + ")is not a valid ip address");
306             }
307
308             if (!RegExpTestUtil.portRegExpTest(server.getPort())) {
309                 throw new ExtendedNotSupportedException("save CustomRouteInfo FAIL:Port("
310                         + server.getPort() + ")is not a valid Port address");
311             }
312         }
313
314
315         String serviceInfokey =
316                 RouteUtil.getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE,
317                         customRouteInfo.getServiceName().trim(), RouteUtil.ROUTE_PATH_INFO);
318         Map<String, String> serviceInfoMap = new HashMap<String, String>();
319         serviceInfoMap.put("url", "/".equals(customRouteInfo.getUrl().trim())
320                 ? ""
321                 : customRouteInfo.getUrl().trim());
322         serviceInfoMap.put("control", customRouteInfo.getControl());
323         serviceInfoMap.put("status", customRouteInfo.getStatus());
324         serviceInfoMap.put("visualRange", customRouteInfo.getVisualRange());
325         serviceInfoMap.put("useOwnUpstream", customRouteInfo.getUseOwnUpstream());
326
327
328
329         String serviceLBkey =
330                 RouteUtil.getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE,
331                         customRouteInfo.getServiceName(), RouteUtil.ROUTE_PATH_LOADBALANCE);
332
333
334         Jedis jedis = null;
335         try {
336             jedis = JedisUtil.borrowJedisInstance();
337             if (jedis == null) {
338                 throw new ExtendedInternalServerErrorException(
339                         "fetch from jedis pool failed,null object!");
340             }
341             jedis.hmset(serviceInfokey, serviceInfoMap);
342
343
344             for (int i = 0; i < serverList.length; i++) {
345                 Map<String, String> servermap = new HashMap<String, String>();
346                 RouteServer server = serverList[i];
347
348                 servermap.put("ip", server.getIp());
349                 servermap.put("port", server.getPort());
350                 servermap.put("weight", Integer.toString(server.getWeight()));
351
352                 jedis.hmset(serviceLBkey + ":server" + (i + 1), servermap);
353             }
354
355
356         } catch (Exception e) {
357             LOGGER.error("call redis throw exception", e);
358             throw new ExtendedInternalServerErrorException("call redis throw exception:"
359                     + e.getMessage());
360
361         } finally {
362             JedisUtil.returnJedisInstance(jedis);;
363         }
364
365         return customRouteInfo;
366     }
367
368
369
370     public synchronized void deleteCustomRoute(String serviceName, String delKey, String serverPort) {
371
372         if (StringUtils.isBlank(serviceName)) {
373             throw new ExtendedNotSupportedException("serviceName  can't be empty");
374         }
375
376         Jedis jedis = null;
377
378         try {
379             jedis = JedisUtil.borrowJedisInstance();
380             if (jedis == null) {
381                 throw new ExtendedInternalServerErrorException(
382                         "fetch from jedis pool failed,null object!");
383             }
384
385             String routekey =
386                     RouteUtil
387                             .getPrefixedKey(serverPort, RouteUtil.CUSTOMROUTE, serviceName, delKey);
388             Set<String> infoSet = jedis.keys(routekey);
389
390             if (infoSet.isEmpty()) {
391               LOGGER.warn("delete CustomRoute FAIL:serviceName-"
392                         + serviceName + " not fond ");
393             }
394             else{
395
396               String[] paths = new String[infoSet.size()];
397               infoSet.toArray(paths);
398               jedis.del(paths);
399             }
400
401         } catch (ExtendedNotFoundException e) {
402             throw e;
403         } catch (Exception e) {
404
405             LOGGER.error("delete CustomRoute throw exception", e);
406             throw new ExtendedInternalServerErrorException("delete CustomRoute throw exception:"
407                     + e.getMessage());
408
409         } finally {
410             JedisUtil.returnJedisInstance(jedis);
411         }
412
413
414     }
415 }