Issue-id: OCS-9
[msb/apigateway.git] / msb-core / apiroute / apiroute-service / src / main / java / org / openo / msb / wrapper / MicroServiceWrapper.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.Set;
19
20 import org.apache.commons.lang3.StringUtils;
21 import org.openo.msb.api.MicroServiceFullInfo;
22 import org.openo.msb.api.MicroServiceInfo;
23 import org.openo.msb.api.Node;
24 import org.openo.msb.api.NodeInfo;
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.MicroServiceDB;
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 public class MicroServiceWrapper {
35
36     private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceWrapper.class);
37
38     private static MicroServiceWrapper instance = new MicroServiceWrapper();
39
40
41     private MicroServiceWrapper() {}
42
43     public static MicroServiceWrapper getInstance() {
44         return instance;
45     }
46
47
48     /**
49      * @Title: getAllMicroServiceInstances
50      * @Description: getAllMicroServiceInstances
51      * @param: @return
52      * @return: Response
53      * @throws Exception
54      */
55     public MicroServiceFullInfo[] getAllMicroServiceInstances(){
56
57         try {
58             return MicroServiceDB.getInstance().getAllMicroServiceInstances();
59
60         } catch (Exception e) {
61             throw new ExtendedInternalServerErrorException(e.getMessage());
62         }
63
64     }
65
66     /**
67      * @Title: getMicroServiceInstance
68      * @Description: (getMicroServiceInstance)
69      * @param: @param serviceName
70      * @param: @param version
71      * @param: @return
72      * @return: ApiRouteInfo
73      */
74     public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version,String serverPort) {
75         if("null".equals(version)) {
76             version="";
77         }
78         serviceName=serviceName.replace("*", "/");
79         
80         if (StringUtils.isBlank(serviceName)) {
81             throw new ExtendedNotSupportedException("serviceName  can't be empty");
82         }
83
84         if (StringUtils.isNotBlank(version)) {
85             if (!RegExpTestUtil.versionRegExpTest(version)) {
86                 throw new ExtendedNotSupportedException("version (" + version
87                         + ") is not a valid  format");
88             }
89         }
90
91         MicroServiceFullInfo microServiceInfo;
92         try {
93             microServiceInfo =
94                     MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,serverPort);
95
96         } catch (Exception e) {
97             throw new ExtendedInternalServerErrorException(e.getMessage());
98         }
99
100         if (null == microServiceInfo) {
101             String errInfo =
102                     "microservice not found: serviceName-" + serviceName + ",version-" + version;
103             LOGGER.warn(errInfo);
104             throw new ExtendedNotFoundException(errInfo);
105
106         }
107
108         return microServiceInfo;
109     }
110
111
112
113     /**
114      * @Title: updateMicroServiceInstance
115      * @Description: updateMicroServiceInstance
116      * @param: serviceName
117      * @param: version
118      * @param: microServiceInfo
119      * @return: RouteResult
120      */
121     public synchronized MicroServiceFullInfo updateMicroServiceInstance(String serviceName,
122             String version, MicroServiceInfo microServiceInfo) {
123         if("null".equals(version)) {
124             version="";
125         }
126         serviceName=serviceName.replace("*", "/");
127
128         try {
129        
130             
131             MicroServiceFullInfo oldService= getMicroServiceInstance(serviceName,version,"");
132
133             // Delete the original record
134             MicroServiceDB.getInstance().deleteMicroService(serviceName, version,"");
135             // Notify the listeners
136             MicroServiceDB.getInstance().noticeApiListener(oldService, "DELETE","");
137             // Save the new record
138             MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,"");
139           
140             MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "ADD","");
141             MicroServiceFullInfo newMicroServiceInfo =
142                     MicroServiceDB.getInstance().getMicroServiceInstance(
143                             microServiceInfo.getServiceName(), microServiceInfo.getVersion(),"");
144             return newMicroServiceInfo;
145         } catch (Exception e) {
146             LOGGER.error("update MicroService throw exception", e);
147             throw new ExtendedInternalServerErrorException(e.getMessage());
148         }
149
150
151     }
152
153     public synchronized MicroServiceFullInfo updateMicroServiceNode(String serviceName,
154             String version, String ip,String port, int ttl) {
155         if("null".equals(version)) {
156             version="";
157         }
158         serviceName=serviceName.replace("*", "/");
159         
160         if (StringUtils.isBlank(serviceName)) {
161             throw new ExtendedNotSupportedException(
162                     "update MicroService Node FAIL:serviceName  can't be empty");
163         }
164
165         if (StringUtils.isNotBlank(version)) {
166             if (!RegExpTestUtil.versionRegExpTest(version)) {
167                 throw new ExtendedNotSupportedException(
168                         "update MicroService Node FAIL:version is not a valid  format");
169             }
170         }
171
172         if (!RegExpTestUtil.ipRegExpTest(ip)) {
173             throw new ExtendedNotSupportedException("update MicroService Node FAIL:ip(" + ip
174                     + ")is not a valid IP address");
175         }
176         
177         if (!RegExpTestUtil.portRegExpTest(port)) {
178             throw new ExtendedNotSupportedException("update MicroService Node FAIL:port(" + port
179                     + ")is not a valid Port address");
180         }
181         
182         try {
183
184             MicroServiceDB.getInstance().updateMicroServiceNode2Redis(serviceName, version, ip,port,ttl);
185
186             MicroServiceFullInfo newMicroServiceInfo =
187                     MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,"");
188
189             return newMicroServiceInfo;
190         } catch (NullPointerException e) {
191             throw new ExtendedNotFoundException(e.getMessage());
192         } catch (Exception e) {
193             LOGGER.error("update MicroServiceNode throw exception", e);
194             throw new ExtendedInternalServerErrorException(e.getMessage());
195         }
196     }
197
198     /**
199      * @Title updateMicroServiceStatus
200      * @Description updateMicroServiceStatus
201      * @param serviceName
202      * @param version
203      * @param status
204      * @return
205      * @return RouteResult
206      */
207  
208     public synchronized MicroServiceFullInfo updateMicroServiceStatus(String serviceName, String version,
209             String status) {
210
211         if ("null".equals(version)) {
212             version = "";
213         }
214         serviceName=serviceName.replace("*", "/");
215
216         if (StringUtils.isBlank(serviceName)) {
217             throw new ExtendedNotSupportedException(
218                     "update MicroService status FAIL:serviceName  can't be empty");
219         }
220
221         if (StringUtils.isNotBlank(version)) {
222             if (!RegExpTestUtil.versionRegExpTest(version)) {
223                 throw new ExtendedNotSupportedException(
224                         "update MicroService status FAIL:version is not a valid  format");
225             }
226         }
227         
228         if(!"0".equals(status) && !"2".equals(status) && !"1".equals(status)){
229
230             throw new ExtendedNotSupportedException("update MicroService status FAIL:status is wrong");
231         }
232         
233         
234         try {
235
236             MicroServiceDB.getInstance().updateMicroServiceStatus(serviceName, version, status);
237
238             MicroServiceFullInfo newMicroServiceInfo =
239                     MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,"");
240             
241             // Notify the listeners
242             MicroServiceDB.getInstance().noticeUpdateStatusListener(newMicroServiceInfo, status);
243
244
245             return newMicroServiceInfo;
246         } catch (NullPointerException e) {
247             throw new ExtendedNotFoundException(e.getMessage());
248         } catch (Exception e) {
249             LOGGER.error("update MicroServiceNode throw exception", e);
250             throw new ExtendedInternalServerErrorException(e.getMessage());
251         }
252  
253
254     }
255
256
257     public synchronized MicroServiceFullInfo saveMicroServiceInstance(
258             MicroServiceInfo microServiceInfo, boolean createOrUpdate,String requestIP,String serverPort) {
259         // 保存数据格式判断
260
261         if (StringUtils.isBlank(microServiceInfo.getServiceName())
262                 || StringUtils.isBlank(microServiceInfo.getProtocol())
263                 || microServiceInfo.getNodes().size() == 0) {
264             throw new ExtendedNotSupportedException(
265                     "register MicroServiceInfo FAIL: Some required fields are empty");
266         }
267
268         for (Node node : microServiceInfo.getNodes()) {
269          
270             if(node.getIp()==null || node.getIp().isEmpty()){
271                 node.setIp(requestIP);
272             }
273             else if (!RegExpTestUtil.ipRegExpTest(node.getIp())) {
274                 throw new ExtendedNotSupportedException("register MicroServiceInfo FAIL:IP("
275                         + node.getIp() + ")is not a valid ip address");
276             }
277             
278             if (!RegExpTestUtil.portRegExpTest(node.getPort())) {
279                 throw new ExtendedNotSupportedException("register MicroServiceInfo FAIL:Port("
280                         + node.getPort() + ")is not a valid Port address");
281             }
282         }
283
284         if (StringUtils.isNotBlank(microServiceInfo.getVersion())) {
285             if (!RegExpTestUtil.versionRegExpTest(microServiceInfo.getVersion())) {
286                 throw new ExtendedNotSupportedException(
287                         "register MicroServiceInfo FAIL:version is not a valid  format");
288
289             }
290         }
291
292         if (StringUtils.isNotBlank(microServiceInfo.getUrl().trim())) {
293             if (!RegExpTestUtil.urlRegExpTest(microServiceInfo.getUrl())) {
294                 throw new ExtendedNotSupportedException(
295                         "register MicroServiceInfo FAIL:url is not a valid format(url must be begin with /)");
296
297             }
298         }
299
300
301         if (RouteUtil.PROTOCOL_LIST.indexOf(microServiceInfo.getProtocol().trim()) == -1) {
302             throw new ExtendedNotSupportedException(
303                     "register MicroServiceInfo FAIL:Protocol is wrong,value range:("
304                             + RouteUtil.PROTOCOL_LIST + ")");
305         }
306
307         MicroServiceFullInfo existingMicroServiceInfo;
308         try {
309             //To determine whether a service already exists
310             existingMicroServiceInfo =
311                     MicroServiceDB.getInstance().getMicroServiceInstance(
312                             microServiceInfo.getServiceName().trim(), microServiceInfo.getVersion().trim(),serverPort);
313
314             MicroServiceFullInfo newMicroServiceInfo ;
315             if (existingMicroServiceInfo != null) {
316                 //a service already exists
317
318                 if (!existingMicroServiceInfo.getProtocol().equals(microServiceInfo.getProtocol())) {
319                     throw new ExtendedNotSupportedException(
320                             "MicroServiceInfo with different protocols and same serviceName is already existing");
321                 }
322
323                 if (createOrUpdate == false) {
324                     //After the first remove added
325                     MicroServiceDB.getInstance().deleteMicroService(
326                             microServiceInfo.getServiceName(), microServiceInfo.getVersion(),serverPort);
327
328                     MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,serverPort);
329          
330                 } else {
331                     //Add the original record and save directly
332                     MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,serverPort);
333                 }
334                 
335                 newMicroServiceInfo =
336                         MicroServiceDB.getInstance().getMicroServiceInstance(
337                                 microServiceInfo.getServiceName(), microServiceInfo.getVersion(),serverPort);
338
339                 //Notify the listeners
340                 MicroServiceDB.getInstance().noticeUpdateApiListener(microServiceInfo.getServiceName(),microServiceInfo.getVersion(),newMicroServiceInfo,serverPort);
341
342             } else {
343                 //Save the new record
344                 MicroServiceDB.getInstance().saveMicroServiceInfo2Redis(microServiceInfo,serverPort);
345                 //Notify the listeners
346                 MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "ADD",serverPort);
347                 newMicroServiceInfo =
348                         MicroServiceDB.getInstance().getMicroServiceInstance(
349                                 microServiceInfo.getServiceName(), microServiceInfo.getVersion(),serverPort);
350             }
351
352   
353
354             return newMicroServiceInfo;
355
356         } catch (ExtendedNotSupportedException e) {
357             throw e;
358         } catch (Exception e) {
359             throw new ExtendedInternalServerErrorException(e.getMessage());
360         }
361
362     }
363     
364     
365     public synchronized void deleteMicroService(String serviceName, String version) {
366         if("null".equals(version)) {
367             version="";
368         }
369         serviceName=serviceName.replace("*", "/");
370         
371         if (StringUtils.isBlank(serviceName)) {
372             throw new ExtendedNotSupportedException(
373                     "delete MicroServiceInfo FAIL:serviceName  can't be empty");
374         }
375
376         if (StringUtils.isNotBlank(version)) {
377             if (!RegExpTestUtil.versionRegExpTest(version)) {
378                 throw new ExtendedNotSupportedException(
379                         "delete MicroServiceInfo FAIL:version is not a valid  format");
380
381             }
382         }
383
384         try {
385
386             MicroServiceFullInfo microServiceInfo =
387                     MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,"");
388
389             if (microServiceInfo == null) {
390                 LOGGER.warn("serviceName-"+ serviceName + ",version-" + version + " not fond ");
391                 return;
392             }
393
394             MicroServiceDB.getInstance().deleteMicroService(serviceName, version,"");
395             //Notify the listeners
396             MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE","");
397         
398         } catch (Exception e) {
399             LOGGER.error("delete MicroServiceInfo throw exception", e);
400             throw new ExtendedInternalServerErrorException(e.getMessage());
401
402         }
403         
404         LOGGER.info("delete MicroServiceInfo success:serviceName-"
405                 + serviceName + ",version-" + version );
406
407     }
408
409
410     public synchronized void deleteMicroService(String serviceName, String version,String serverPort) {
411         if("null".equals(version)) {
412             version="";
413         }
414         serviceName=serviceName.replace("*", "/");
415         
416         if (StringUtils.isBlank(serviceName)) {
417             throw new ExtendedNotSupportedException(
418                     "delete MicroServiceInfo FAIL:serviceName  can't be empty");
419         }
420
421         if (StringUtils.isNotBlank(version)) {
422             if (!RegExpTestUtil.versionRegExpTest(version)) {
423                 throw new ExtendedNotSupportedException(
424                         "delete MicroServiceInfo FAIL:version is not a valid  format");
425
426             }
427         }
428
429         try {
430
431             MicroServiceFullInfo microServiceInfo =
432                     MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,serverPort);
433
434             if (microServiceInfo == null) {
435                 throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL:serviceName-"
436                         + serviceName + ",version-" + version + " not fond ");
437             }
438
439             MicroServiceDB.getInstance().deleteMicroService(serviceName, version,serverPort);
440             //Notify the listeners
441             MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE",serverPort);
442         } catch (ExtendedNotFoundException e) {
443             throw e;
444         } catch (Exception e) {
445             LOGGER.error("delete MicroServiceInfo throw exception", e);
446             throw new ExtendedInternalServerErrorException(e.getMessage());
447
448         }
449         
450         LOGGER.info("delete MicroServiceInfo success:serviceName-"
451                 + serviceName + ",version-" + version );
452
453     }
454
455     public synchronized void deleteMicroServiceInstance(String serviceName, String version,
456             String ip,String port) {
457         if("null".equals(version)) {
458             version="";
459         }
460         serviceName=serviceName.replace("*", "/");
461         
462         if (StringUtils.isBlank(serviceName)) {
463             throw new ExtendedNotSupportedException(
464                     "delete MicroServiceInfo FAIL:serviceName  can't be empty");
465         }
466
467         if (StringUtils.isNotBlank(version)) {
468             if (!RegExpTestUtil.versionRegExpTest(version)) {
469                 throw new ExtendedNotSupportedException(
470                         "delete MicroServiceInfo FAIL:version is not a valid  format");
471             }
472         }
473
474         if (!RegExpTestUtil.ipRegExpTest(ip)) {
475             throw new ExtendedNotSupportedException("delete MicroServiceInfo FAIL:IP(" + ip
476                     + ")is not a valid IP address");
477         }
478         
479         if (!RegExpTestUtil.portRegExpTest(port)) {
480             throw new ExtendedNotSupportedException("delete MicroServiceInfo FAIL:Port(" + port
481                     + ")is not a valid Port address");
482         }
483
484
485         try {
486             MicroServiceFullInfo microServiceInfo =
487                     MicroServiceDB.getInstance().getMicroServiceInstance(serviceName, version,"");
488
489             if (microServiceInfo == null) {
490                 throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL:serviceName-"
491                         + serviceName + ",version-" + version + " not fond ");
492             }
493
494             Set<NodeInfo> nodes = microServiceInfo.getNodes();
495
496             boolean ifFindBNode = false;
497
498             for (Node node : nodes) {
499                 if (node.getIp().equals(ip) && node.getPort().equals(port)) {
500                     ifFindBNode = true;
501                     nodes.remove(node);
502
503                     if (nodes.isEmpty()) {
504                         //delete MicroService
505                         MicroServiceDB.getInstance().deleteMicroService(serviceName, version,"");
506                         //Notify the listeners
507                         MicroServiceDB.getInstance().noticeApiListener(microServiceInfo, "DELETE","");
508                     } else {
509                         //delete Node
510                         MicroServiceDB.getInstance().deleteNode(serviceName, version, ip,port);
511                         MicroServiceDB.getInstance().noticeUpdateApiListener(serviceName, version,microServiceInfo,"");
512                     }
513
514                     break;
515                 }
516             }
517
518             if (!ifFindBNode) {
519                 throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL: node-" + ip+":"+port
520                         + " not fond ");
521             }
522
523
524         } catch (ExtendedNotFoundException e) {
525             throw e;
526         } catch (Exception e) {
527             LOGGER.error("deleteApiRoute throw exception", e);
528             throw new ExtendedInternalServerErrorException(e.getMessage());
529
530         }
531
532     }
533
534
535 }