d94c09edf09333ef241ab15132cf826616118768
[msb/discovery.git] / sdclient / discovery-service / src / main / java / org / onap / msb / sdclient / wrapper / ConsulServiceWrapper.java
1 /**
2  * Copyright 2016-2017 ZTE, Inc. and others.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 package org.onap.msb.sdclient.wrapper;
15
16 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22
23 import org.apache.commons.lang3.StringUtils;
24 import org.onap.msb.sdclient.core.AgentService;
25 import org.onap.msb.sdclient.core.CatalogService;
26 import org.onap.msb.sdclient.core.Check;
27 import org.onap.msb.sdclient.core.ConsulResponse;
28 import org.onap.msb.sdclient.core.HealthService;
29 import org.onap.msb.sdclient.core.HealthService.Service;
30 import org.onap.msb.sdclient.core.KeyVaulePair;
31 import org.onap.msb.sdclient.core.MicroServiceFullInfo;
32 import org.onap.msb.sdclient.core.MicroServiceInfo;
33 import org.onap.msb.sdclient.core.Node;
34 import org.onap.msb.sdclient.core.NodeAddress;
35 import org.onap.msb.sdclient.core.NodeInfo;
36 import org.onap.msb.sdclient.core.exception.ExtendedInternalServerErrorException;
37 import org.onap.msb.sdclient.core.exception.ExtendedNotFoundException;
38 import org.onap.msb.sdclient.core.exception.UnprocessableEntityException;
39 import org.onap.msb.sdclient.wrapper.util.ConfigUtil;
40 import org.onap.msb.sdclient.wrapper.util.DiscoverUtil;
41 import org.onap.msb.sdclient.wrapper.util.HttpClientUtil;
42 import org.onap.msb.sdclient.wrapper.util.JacksonJsonUtil;
43 import org.onap.msb.sdclient.wrapper.util.RegExpTestUtil;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 import com.fasterxml.jackson.core.type.TypeReference;
48
49 public class ConsulServiceWrapper {
50
51
52     private static ConsulServiceWrapper instance = new ConsulServiceWrapper();
53
54
55     private ConsulServiceWrapper() {}
56
57     public static ConsulServiceWrapper getInstance() {
58         return instance;
59     }
60
61     private static final Logger LOGGER = LoggerFactory.getLogger(ConsulServiceWrapper.class);
62
63     /**
64      * Title: getAllMicroServiceInstances Description: 获取全部服务
65      * 
66      * @return
67      * @see com.zte.ums.nfv.eco.hsif.msb.core.IMSBService#getAllMicroServiceInstances()
68      */
69     public List<MicroServiceFullInfo> getAllMicroServiceInstances() {
70
71         String consulServiceUrl =
72                         (new StringBuilder().append("http://").append(ConfigUtil.getInstance().getConsulAddress())
73                                         .append(DiscoverUtil.CONSUL_CATALOG_URL).append("/services")).toString();
74
75         String resultJson = HttpClientUtil.httpGet(consulServiceUrl);
76         Map<String, String[]> catalogServiceMap = (Map<String, String[]>) JacksonJsonUtil.jsonToMapBean(resultJson);
77
78         List<MicroServiceFullInfo> microServiceFullInfoArray = new ArrayList<MicroServiceFullInfo>();
79
80         if (catalogServiceMap.isEmpty()) {
81             return microServiceFullInfoArray;
82         }
83
84         for (Map.Entry<String, String[]> entry : catalogServiceMap.entrySet()) {
85             Set<String> versionSet = new HashSet<String>();
86
87             Set<String> nsSet = new HashSet<String>();
88             nsSet.add("");
89
90             String consul_serviceName = entry.getKey().toString();
91             String[] tagList = entry.getValue();
92
93             for (String tag : tagList) {
94
95                 if (tag.startsWith("\"base\"")) {
96                     String ms_base_json = tag.split("\"base\":")[1];
97
98                     try {
99                         Map<String, String> baseMap =
100                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
101                         if (baseMap.get("version") != null) {
102                             versionSet.add(baseMap.get("version"));
103                         } else {
104                             versionSet.add("");
105                         }
106                     } catch (Exception e) {
107                         LOGGER.error(e.getMessage());
108                     }
109
110                     continue;
111
112                 }
113
114                 if (tag.startsWith("\"ns\"")) {
115                     String ms_ns_json = tag.split("\"ns\":")[1];
116
117                     try {
118                         Map<String, String> namespaceMap =
119                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_ns_json, Map.class);
120                         if (namespaceMap.get("namespace") != null) {
121                             nsSet.add(namespaceMap.get("namespace"));
122                         } else {
123                             nsSet.add("");
124                         }
125
126                         continue;
127
128                     } catch (Exception e) {
129                         // TODO Auto-generated catch block
130                         LOGGER.error(e.getMessage());
131                     }
132
133                     continue;
134
135                 }
136
137
138             }
139
140             for (String ms_version : versionSet) {
141                 for (String ns : nsSet) {
142                     MicroServiceFullInfo microServiceFullInfo =
143                                     getMicroServiceInstanceForAll(consul_serviceName, ms_version, ns);
144                     if (microServiceFullInfo != null && !"consul".equals(microServiceFullInfo.getServiceName())) {
145
146                         microServiceFullInfoArray.add(microServiceFullInfo);
147                     }
148                 }
149             }
150
151
152         }
153
154
155         return microServiceFullInfoArray;
156     }
157
158
159
160     /**
161      * @Title getMicroServiceInstanceForAll
162      * @Description TODO(通过列表遍历获取单个服务信息)
163      * @param consul_serviceName
164      * @param version
165      * @param namespace
166      * @return
167      * @return MicroServiceFullInfo
168      */
169     public MicroServiceFullInfo getMicroServiceInstanceForAll(String consul_serviceName, String version,
170                     String namespace) {
171
172         try {
173             ConsulResponse consulResponse = getHealthServices(consul_serviceName, false, "", "");
174             if (consulResponse == null) {
175                 LOGGER.error("microservice not found: serviceName-" + consul_serviceName + ", namespace-" + namespace);
176                 return null;
177             }
178
179             String serviceName = consul_serviceName;
180             // Remove version and namespace from consul service name
181             // Consul_serviceName Format: serviceName-version-namespace
182             if (StringUtils.isNotBlank(version) && StringUtils.isNotBlank(namespace)) {
183                 if (consul_serviceName.endsWith("-" + version + "-" + namespace)) {
184                     serviceName = consul_serviceName.substring(0,
185                                     consul_serviceName.length() - version.length() - namespace.length() - 2);
186                 }
187             } else if (StringUtils.isNotBlank(version)) {
188                 if (consul_serviceName.endsWith("-" + version)) {
189                     serviceName = consul_serviceName.substring(0, consul_serviceName.length() - version.length() - 1);
190                 }
191             } else if (StringUtils.isNotBlank(namespace)) {
192                 if (consul_serviceName.endsWith("-" + namespace)) {
193                     serviceName = consul_serviceName.substring(0, consul_serviceName.length() - namespace.length() - 1);
194                 }
195             }
196
197
198             ConsulResponse serviceResponse =
199                             getMicroServiceInfo(consulResponse, serviceName, version, false, "", namespace);
200             return (MicroServiceFullInfo) serviceResponse.getResponse();
201         } catch (Exception e) {
202             if (StringUtils.isNotBlank(namespace)) {
203                 LOGGER.error("get service List have error:serviceName[" + consul_serviceName + "],version[" + version
204                                 + "],namespace[" + namespace + "]:" + e.getMessage());
205             }
206         }
207
208         return null;
209     }
210
211
212     /**
213      * @Title getMicroServiceInstance
214      * @Description TODO(通过Rest接口获取单个服务信息)
215      * @param serviceName
216      * @param version
217      * @param ifPassStatus
218      * @param wait
219      * @param index
220      * @param labels
221      * @param namespace
222      * @return
223      * @return ConsulResponse
224      */
225     public ConsulResponse getMicroServiceInstance(String serviceName, String version, boolean ifPassStatus, String wait,
226                     String index, String labels, String namespace) {
227
228         if ("null".equals(version)) {
229             version = "";
230         }
231
232
233         checkServiceNameAndVersion(serviceName, version);
234
235         if (!RegExpTestUtil.labelRegExpTest(labels)) {
236             throw new UnprocessableEntityException(
237                             "get MicroServiceInfo FAIL: The label query parameter format is wrong (key:value)");
238         }
239
240         String consul_serviceName = getServiceName4Consul(serviceName, version, namespace);
241
242         ConsulResponse consulResponse = getHealthServices(consul_serviceName, ifPassStatus, wait, index);
243         if (consulResponse == null) {
244             String errInfo = "microservice not found: serviceName-" + serviceName + ", namespace-" + namespace;
245             throw new ExtendedNotFoundException(errInfo);
246         }
247
248         return getMicroServiceInfo(consulResponse, serviceName, version, ifPassStatus, labels, namespace);
249
250     }
251
252
253
254     /**
255      * Title: getMicroServiceInstance Description:获取指定服务信息
256      * 
257      * @param serviceName
258      * @param version
259      * @return
260      * @see com.zte.ums.nfv.eco.hsif.msb.core.IMSBService#getMicroServiceInstance(java.lang.String,
261      *      java.lang.String)
262      */
263
264     public ConsulResponse getMicroServiceInfo(ConsulResponse consulResponse, String serviceName, String version,
265                     boolean ifPassStatus, String labels, String namespace) {
266         // TODO Auto-generated method stub
267
268
269
270         String resultJson = (String) consulResponse.getResponse();
271         List<HealthService> healthServiceList =
272                         JacksonJsonUtil.jsonToListBean(resultJson, new TypeReference<List<HealthService>>() {});
273
274
275         if (healthServiceList == null || healthServiceList.size() == 0) {
276             String errInfo = "microservice not found: serviceName-" + serviceName + ", namespace-" + namespace;
277             throw new ExtendedNotFoundException(errInfo);
278
279         }
280
281         try {
282
283             // label query,format key:value|value2,key2:value2
284             boolean islabelQuery = false;
285             Map<String, String> query_labelMap = new HashMap<String, String>();
286             if (StringUtils.isNotBlank(labels)) {
287                 islabelQuery = true;
288                 String[] routeLabels = StringUtils.split(labels, ",");
289
290                 for (int i = 0; i < routeLabels.length; i++) {
291                     String[] labelArray = StringUtils.split(routeLabels[i], ":");
292                     query_labelMap.put(labelArray[0], labelArray[1]);
293                 }
294             }
295
296
297             MicroServiceFullInfo microServiceInfo = new MicroServiceFullInfo();
298             Set<NodeInfo> nodes = new HashSet<NodeInfo>();
299             Set<String> serviceLabels = new HashSet<String>();
300             Set<KeyVaulePair> serviceMetadatas = new HashSet<KeyVaulePair>();
301             Set<String> serviceNetworkPlane = new HashSet<String>();
302             String nodeNamespace = "";
303
304
305
306             for (HealthService healthService : healthServiceList) {
307                 Service service = healthService.getService();
308                 List<String> tagList = service.getTags();
309
310                 String ms_url = "", ms_version = "", ms_protocol = "", ms_status = "", ms_publish_port = "",
311                                 ms_is_manual = "", ms_visualRange = "1", ms_network_plane_type = "", ms_lb_policy = "",
312                                 ms_host = "", ms_path = "", ms_enable_ssl = "";
313                 List<KeyVaulePair> ms_metadata = new ArrayList<KeyVaulePair>();
314
315                 List<String> nodeLabels = new ArrayList<String>();
316                 Map<String, String> labelMap = new HashMap<String, String>();
317
318                 NodeInfo node = new NodeInfo();
319
320                 node.setIp(service.getAddress());
321                 node.setPort(String.valueOf(service.getPort()));
322                 node.setNodeId(service.getId());
323
324
325
326                 try {
327
328                     for (String tag : tagList) {
329
330
331                         if (tag.startsWith("\"base\"")) {
332                             String ms_base_json = tag.split("\"base\":")[1];
333
334                             Map<String, String> baseMap =
335                                             (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
336                             ms_url = (baseMap.get("url") == null ? "" : baseMap.get("url"));
337                             ms_version = (baseMap.get("version") == null ? "" : baseMap.get("version"));
338                             ms_protocol = (baseMap.get("protocol") == null ? "" : baseMap.get("protocol"));
339                             ms_status = (baseMap.get("status") == null ? "1" : baseMap.get("status"));
340
341                             if (baseMap.get("enable_ssl") != null) {
342                                 ms_enable_ssl = (baseMap.get("enable_ssl"));
343                             }
344                             if (baseMap.get("publish_port") != null) {
345                                 ms_publish_port = (baseMap.get("publish_port"));
346                             }
347
348                             if (baseMap.get("is_manual") != null) {
349                                 ms_is_manual = baseMap.get("is_manual");
350                             }
351
352                             if (baseMap.get("ha_role") != null) {
353                                 node.setHa_role(baseMap.get("ha_role"));
354                             }
355
356                             if (baseMap.get("host") != null) {
357                                 ms_host = baseMap.get("host");
358                             }
359
360                             if (baseMap.get("path") != null) {
361                                 ms_path = baseMap.get("path");
362                             }
363
364                             continue;
365                         }
366
367                         if (tag.startsWith("\"labels\"")) {
368                             String ms_labels_json = "{" + tag.split("\"labels\":\\{")[1];
369                             labelMap = (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_labels_json, Map.class);
370
371
372
373                             for (Map.Entry<String, String> labelEntry : labelMap.entrySet()) {
374                                 if ("visualRange".equals(labelEntry.getKey())) {
375                                     ms_visualRange = labelEntry.getValue();
376                                 } else if ("network_plane_type".equals(labelEntry.getKey())) {
377                                     ms_network_plane_type = labelEntry.getValue();
378                                 } else {
379                                     nodeLabels.add(labelEntry.getKey() + ":" + labelEntry.getValue());
380                                 }
381
382                             }
383
384
385                             continue;
386                         }
387
388                         if (tag.startsWith("\"ns\"")) {
389                             String ms_namespace_json = tag.split("\"ns\":")[1];
390                             Map<String, String> namespaceMap = (Map<String, String>) JacksonJsonUtil
391                                             .jsonToBean(ms_namespace_json, Map.class);
392
393                             if (namespaceMap.get("namespace") != null) {
394                                 nodeNamespace = namespaceMap.get("namespace");
395                             } else {
396                                 nodeNamespace = "";
397                             }
398
399                             continue;
400                         }
401
402                         if (tag.startsWith("\"lb\"")) {
403                             String ms_lb_json = tag.split("\"lb\":")[1];
404                             Map<String, String> lbMap =
405                                             (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_lb_json, Map.class);
406
407                             if (lbMap.get("lb_policy") != null) {
408                                 ms_lb_policy = lbMap.get("lb_policy");
409                                 if (ms_lb_policy.startsWith("hash") || ms_lb_policy.equals("ip_hash")) {
410                                     ms_lb_policy = "ip_hash";
411                                 }
412
413                             }
414
415                             if (lbMap.get("lb_server_params") != null) {
416                                 node.setLb_server_params(lbMap.get("lb_server_params").replace(" ", ","));
417                             }
418
419                             continue;
420                         }
421
422                         if (tag.startsWith("\"checks\"")) {
423                             String ms_check_json = tag.split("\"checks\":")[1];
424                             Map<String, String> checkMap =
425                                             (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_check_json, Map.class);
426
427
428                             // 自动注册健康检查
429                             if (StringUtils.isNotBlank(checkMap.get("ttl"))) {
430                                 node.setCheckType("TTL");
431                                 node.setTtl(checkMap.get("ttl"));
432                             } else if (StringUtils.isNotBlank(checkMap.get("http"))) {
433                                 node.setCheckType("HTTP");
434                                 node.setCheckUrl(checkMap.get("http"));
435                                 if (checkMap.get("interval") != null)
436                                     node.setCheckInterval(checkMap.get("interval"));
437                                 if (checkMap.get("timeout") != null)
438                                     node.setCheckTimeOut(checkMap.get("timeout"));
439                             } else if (StringUtils.isNotBlank(checkMap.get("tcp"))) {
440                                 node.setCheckType("TCP");
441                                 node.setCheckUrl(checkMap.get("tcp"));
442                                 if (checkMap.get("interval") != null)
443                                     node.setCheckInterval(checkMap.get("interval"));
444                                 if (checkMap.get("timeout") != null)
445                                     node.setCheckTimeOut(checkMap.get("timeout"));
446                             }
447
448                             continue;
449                         }
450
451                         if (tag.startsWith("\"metadata\"")) {
452                             String ms_metadata_json = "{" + tag.split("\"metadata\":\\{")[1];
453                             Map<String, String> metadataMap = (Map<String, String>) JacksonJsonUtil
454                                             .jsonToBean(ms_metadata_json, Map.class);
455
456
457
458                             for (Map.Entry<String, String> entry : metadataMap.entrySet()) {
459                                 KeyVaulePair keyVaulePair = new KeyVaulePair();
460                                 keyVaulePair.setKey(entry.getKey());
461                                 keyVaulePair.setValue(entry.getValue());
462                                 ms_metadata.add(keyVaulePair);
463                             }
464
465                             continue;
466                         }
467
468
469
470                     }
471
472                 } catch (Exception e) {
473                     LOGGER.error(serviceName + " read tag  throw exception", e);
474                 }
475
476                 // 健康检查信息
477                 List<Check> checks = healthService.getChecks();
478                 node.setStatus("passing");
479                 for (Check check : checks) {
480                     if (!"passing".equals(check.getStatus())) {
481                         node.setStatus(check.getStatus());
482                         break;
483                     }
484                 }
485
486                 if (!ms_version.equals(version)) {
487                     continue;
488                 }
489
490                 // namespace过滤
491                 if (!namespace.equals(nodeNamespace)) {
492                     continue;
493                 }
494
495                 // 标签过滤
496                 if (islabelQuery) {
497                     boolean ifMatchLabel = false;
498                     for (Map.Entry<String, String> query_entry : query_labelMap.entrySet()) {
499                         String key = query_entry.getKey();
500                         String value = query_entry.getValue();
501                         if (StringUtils.isBlank(labelMap.get(key))) {
502                             continue;
503                         }
504
505                         String[] queryTagArray = StringUtils.split(value, "|");
506                         String[] serviceTagArray = StringUtils.split(labelMap.get(key), "|");
507                         if (DiscoverUtil.contain(queryTagArray, serviceTagArray)) {
508                             ifMatchLabel = true;
509                             break;
510                         }
511
512                     }
513
514                     if (!ifMatchLabel) {
515                         continue;
516                     }
517                 }
518
519
520                 nodes.add(node);
521                 serviceLabels.addAll(nodeLabels);
522                 serviceMetadatas.addAll(ms_metadata);
523
524                 String[] network_plane_array = StringUtils.split(ms_network_plane_type, "|");
525                 for (int i = 0; i < network_plane_array.length; i++) {
526                     serviceNetworkPlane.add(network_plane_array[i]);
527                 }
528
529
530
531                 microServiceInfo.setServiceName(serviceName);
532                 microServiceInfo.setUrl(ms_url);
533                 microServiceInfo.setVersion(ms_version);
534                 microServiceInfo.setProtocol(ms_protocol);
535                 microServiceInfo.setStatus(ms_status);
536                 microServiceInfo.setPublish_port(ms_publish_port);
537                 microServiceInfo.setIs_manual(Boolean.parseBoolean(ms_is_manual));
538                 microServiceInfo.setVisualRange(ms_visualRange);
539
540                 microServiceInfo.setLb_policy(ms_lb_policy);
541                 microServiceInfo.setNamespace(namespace);
542                 microServiceInfo.setHost(ms_host);
543                 microServiceInfo.setPath(ms_path);
544                 microServiceInfo.setEnable_ssl(Boolean.parseBoolean(ms_enable_ssl));
545             }
546
547
548             if (nodes.isEmpty()) {
549
550
551                 String errInfo = "microservice not found: serviceName-" + serviceName + ",version-" + version
552                                 + ",namespace-" + namespace + ",labels-" + labels;
553                 throw new ExtendedNotFoundException(errInfo);
554
555             }
556
557
558
559             microServiceInfo.setLabels(new ArrayList<String>(serviceLabels));
560             microServiceInfo.setMetadata(new ArrayList<KeyVaulePair>(serviceMetadatas));
561             microServiceInfo.setNodes(nodes);
562             microServiceInfo.setNetwork_plane_type(StringUtils.join(serviceNetworkPlane.toArray(), "|"));
563
564
565
566             return new ConsulResponse(microServiceInfo, consulResponse.getIndex());
567
568
569         } catch (ExtendedNotFoundException e) {
570             throw e;
571         } catch (Exception e) {
572             throw new ExtendedInternalServerErrorException(e.getMessage());
573         }
574
575
576     }
577
578
579
580     public MicroServiceFullInfo updateMicroServiceInstance(String serviceName, String version, String namespace,
581                     MicroServiceInfo microServiceInfo, String requestIP, boolean is_manual) {
582         // 数据格式效验
583         checkMicroServiceInfo(microServiceInfo);
584         deleteMicroService(serviceName, version, namespace);
585         return saveMicroServiceInstance(microServiceInfo, true, requestIP, is_manual);
586     }
587
588     /**
589      * Title: saveMicroServiceInstance Description: 保存服务信息
590      * 
591      * @param microServiceInfo
592      * @param createOrUpdate true:添加或追加更新 false:覆盖
593      * @param requestIP 访问请求IP地址
594      * @return
595      * @see com.zte.ums.nfv.eco.hsif.msb.core.IMSBService#saveMicroServiceInstance(org.onap.msb.sdclient.core.MicroServiceInfo,
596      *      boolean, java.lang.String)
597      */
598     public MicroServiceFullInfo saveMicroServiceInstance(MicroServiceInfo microServiceInfo, boolean createOrUpdate,
599                     String requestIP, boolean is_manual) {
600
601         // 数据格式效验
602         checkMicroServiceInfo(microServiceInfo);
603
604         String serviceName = microServiceInfo.getServiceName().trim();
605
606         if (createOrUpdate == false) {
607             // 覆盖原记录,先删除后添加
608             try {
609                 deleteMicroService(microServiceInfo.getServiceName(), microServiceInfo.getVersion(),
610                                 microServiceInfo.getNamespace());
611             } catch (ExtendedNotFoundException e) {
612                 String errInfo = "microservice not found: serviceName-" + microServiceInfo.getServiceName()
613                                 + ",version-" + microServiceInfo.getVersion() + " ,namespace-"
614                                 + microServiceInfo.getNamespace();
615                 LOGGER.warn(errInfo);
616             }
617
618
619
620         }
621
622         Set<Node> nodes = microServiceInfo.getNodes();
623         String[] visualRangeArray = StringUtils.split(microServiceInfo.getVisualRange(), "|");
624
625         try {
626
627             for (Node node : nodes) {
628                 AgentService agentService = new AgentService();
629
630                 if (StringUtils.isBlank(node.getIp())) {
631                     node.setIp(requestIP);
632                 }
633
634                 String serverId = microServiceInfo.getNamespace() + "_" + microServiceInfo.getVersion() + "_"
635                                 + serviceName + "_" + node.getIp() + "_" + node.getPort();
636
637
638                 List<String> tags = new ArrayList<String>();
639
640                 Map<String, String> baseMap = new HashMap<String, String>();
641                 Map<String, String> lbMap = new HashMap<String, String>();
642                 Map<String, String> labelMap = new HashMap<String, String>();
643                 Map<String, String> metadataMap = new HashMap<String, String>();
644                 Map<String, String> checkMap = new HashMap<String, String>();
645                 Map<String, String> nsMap = new HashMap<String, String>();
646                 // Map<String, String> nodeMap = new HashMap<String, String>();
647
648                 baseMap.put("url", microServiceInfo.getUrl());
649                 baseMap.put("protocol", microServiceInfo.getProtocol());
650                 baseMap.put("version", microServiceInfo.getVersion());
651
652                 baseMap.put("status", "1");
653                 baseMap.put("is_manual", Boolean.toString(is_manual));
654                 baseMap.put("enable_ssl", Boolean.toString(microServiceInfo.isEnable_ssl()));
655
656                 // TCP和UDP协议保存 nginx端口和负载均衡策略
657                 if (StringUtils.isNotBlank(microServiceInfo.getPublish_port())) {
658                     baseMap.put("publish_port", microServiceInfo.getPublish_port());
659                 }
660                 String lb_policy = microServiceInfo.getLb_policy();
661
662                 // 保存服务的负载均衡策略
663                 if (StringUtils.isNotBlank(lb_policy)) {
664                     switch (lb_policy) {
665                         case "round-robin":
666                             break;
667                         case "ip_hash":
668                             if ("TCP".equals(microServiceInfo.getProtocol())
669                                             || "UDP".equals(microServiceInfo.getProtocol())) {
670                                 lbMap.put("lb_policy", "hash $remote_addr");
671                             } else {
672                                 lbMap.put("lb_policy", "ip_hash");
673                             }
674                             break;
675                         default:
676                             lbMap.put("lb_policy", lb_policy);
677                             break;
678                     }
679
680                 }
681
682                 if (StringUtils.isNotBlank(node.getLb_server_params())) {
683                     lbMap.put("lb_server_params", node.getLb_server_params().trim().replace(",", " "));
684
685                 }
686
687                 if (StringUtils.isNotBlank(node.getHa_role())) {
688                     baseMap.put("ha_role", node.getHa_role());
689                 }
690
691                 if (StringUtils.isNotBlank(microServiceInfo.getHost())) {
692                     baseMap.put("host", microServiceInfo.getHost().toLowerCase());
693                 }
694
695                 if (StringUtils.isNotBlank(microServiceInfo.getPath())) {
696                     baseMap.put("path", microServiceInfo.getPath());
697                 }
698
699                 // 保存健康检查参数
700                 if (StringUtils.isNotBlank(node.getCheckType())) {
701
702                     AgentService.Check check = agentService.createCheck();
703
704                     if ("TTL".equals(node.getCheckType())) {
705                         check.setTtl(node.getTtl());
706                         checkMap.put("ttl", node.getTtl());
707
708                     } else if ("HTTP".equals(node.getCheckType())) {
709                         check.setInterval(node.getCheckInterval());
710                         check.setHttp(node.getCheckUrl());
711                         check.setTimeout(node.getCheckTimeOut());
712
713                         checkMap.put("http", node.getCheckUrl());
714                         checkMap.put("interval", node.getCheckInterval());
715                         checkMap.put("timeout", node.getCheckTimeOut());
716                     } else if ("TCP".equals(node.getCheckType())) {
717                         check.setInterval(node.getCheckInterval());
718                         check.setTcp(node.getCheckUrl());
719                         check.setTimeout(node.getCheckTimeOut());
720
721                         checkMap.put("tcp", node.getCheckUrl());
722                         checkMap.put("interval", node.getCheckInterval());
723                         checkMap.put("timeout", node.getCheckTimeOut());
724                     }
725
726                     agentService.setCheck(check);
727                 }
728
729
730                 List<KeyVaulePair> keyVaulePairs = microServiceInfo.getMetadata();
731
732                 if (keyVaulePairs != null && keyVaulePairs.size() > 0) {
733                     for (KeyVaulePair keyVaulePair : keyVaulePairs) {
734                         metadataMap.put(keyVaulePair.getKey(), keyVaulePair.getValue());
735                     }
736                 }
737
738                 // 同步过滤参数组合为json格式存储
739                 labelMap.put("visualRange", StringUtils.join(visualRangeArray, "|"));
740
741                 if (StringUtils.isNotBlank(microServiceInfo.getNetwork_plane_type())) {
742                     labelMap.put("network_plane_type", microServiceInfo.getNetwork_plane_type());
743                 }
744                 if (microServiceInfo.getLabels() != null) {
745                     for (String label : microServiceInfo.getLabels()) {
746                         String[] labelArray = StringUtils.split(label, ":");
747                         if (labelArray.length == 2) {
748                             labelMap.put(labelArray[0], labelArray[1]);
749                         }
750                     }
751                 }
752
753                 if (StringUtils.isNotBlank(microServiceInfo.getNamespace())) {
754                     nsMap.put("namespace", microServiceInfo.getNamespace());
755                 }
756
757
758
759                 tags.add("\"base\":" + JacksonJsonUtil.beanToJson(baseMap));
760                 if (!lbMap.isEmpty())
761                     tags.add("\"lb\":" + JacksonJsonUtil.beanToJson(lbMap));
762                 if (!checkMap.isEmpty())
763                     tags.add("\"checks\":" + JacksonJsonUtil.beanToJson(checkMap));
764                 if (!labelMap.isEmpty())
765                     tags.add("\"labels\":" + JacksonJsonUtil.beanToJson(labelMap));
766                 if (!metadataMap.isEmpty())
767                     tags.add("\"metadata\":" + JacksonJsonUtil.beanToJson(metadataMap));
768                 if (!nsMap.isEmpty())
769                     tags.add("\"ns\":" + JacksonJsonUtil.beanToJson(nsMap));
770
771                 agentService.setTags(tags);
772
773                 agentService.setAddress(node.getIp());
774                 agentService.setId(serverId);
775                 agentService.setPort(Integer.parseInt(node.getPort()));
776
777                 String consul_serviceName = getServiceName4Consul(serviceName, microServiceInfo.getVersion(),
778                                 microServiceInfo.getNamespace());
779
780
781                 agentService.setName(consul_serviceName);
782
783                 int registerResult;
784                 if (DiscoverUtil.CONSUL_REGISTER_MODE.equals(ConfigUtil.getInstance().getConsulRegisterMode())) {
785                     registerResult = ConsulCatalogServiceWrapper.getInstance().saveService(agentService);
786                 } else {
787                     registerResult = ConsulAgentServiceWrapper.getInstance().saveService(agentService);
788                 }
789
790                 if (registerResult != 200) {
791                     throw new Exception("register consul service fail:" + registerResult);
792                 }
793
794
795
796             }
797
798             LOGGER.info("save microservice success: serviceName-" + microServiceInfo.getServiceName() + ",version-"
799                             + microServiceInfo.getVersion() + " ,namespace-" + microServiceInfo.getNamespace());
800
801             return getMicroServiceInstance(serviceName, microServiceInfo.getVersion(), microServiceInfo.getNamespace());
802
803
804         } catch (ExtendedNotFoundException e) {
805             throw e;
806         } catch (Exception e) {
807             LOGGER.error("register consul service throw exception", e);
808             throw new ExtendedInternalServerErrorException(e.getMessage());
809
810         }
811
812
813
814     }
815
816     public MicroServiceFullInfo getMicroServiceInstance(String serviceName, String version, String namespace) {
817         ConsulResponse serviceResponse = getMicroServiceInstance(serviceName, version, false, "", "", "", namespace);
818         return (MicroServiceFullInfo) serviceResponse.getResponse();
819     }
820
821
822     /**
823      * Title: deleteMicroService Description: 删除服务信息
824      * 
825      * @param serviceName
826      * @param version
827      * @see com.zte.ums.nfv.eco.hsif.msb.core.IMSBService#deleteMicroService(java.lang.String,
828      *      java.lang.String)
829      */
830     public void deleteMicroService(String serviceName, String version, String namespace) {
831
832
833         if ("null".equals(version)) {
834             version = "";
835         }
836
837         checkServiceNameAndVersion(serviceName, version);
838
839
840         String consul_serviceName = getServiceName4Consul(serviceName, version, namespace);
841
842         List<CatalogService> catalogServiceList = getConsulServices(consul_serviceName, version);
843
844
845         if (catalogServiceList == null || catalogServiceList.size() == 0) {
846             String errInfo = "microservice not found: serviceName-" + serviceName + ",version-" + version
847                             + " ,namespace-" + namespace;
848             throw new ExtendedNotFoundException(errInfo);
849
850         }
851
852         boolean ifFindServiceForNS = false;
853
854         for (CatalogService catalogService : catalogServiceList) {
855
856             List<String> tagList = catalogService.getServiceTags();
857             String serviceNamespace = "", serviceVersion = "";
858             try {
859
860                 for (String tag : tagList) {
861
862                     if (tag.startsWith("\"ns\"")) {
863                         String ms_ns_json = tag.split("\"ns\":")[1];
864
865
866                         Map<String, String> nsMap =
867                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_ns_json, Map.class);
868                         if (nsMap.get("namespace") != null) {
869                             serviceNamespace = nsMap.get("namespace");
870                         }
871
872                         continue;
873                     }
874
875                     if (tag.startsWith("\"base\"")) {
876                         String ms_base_json = tag.split("\"base\":")[1];
877
878
879                         Map<String, String> baseMap =
880                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
881                         if (baseMap.get("version") != null) {
882                             serviceVersion = baseMap.get("version");
883                         }
884
885
886                         continue;
887
888                     }
889
890                 }
891
892             } catch (Exception e) {
893                 LOGGER.error(serviceName + " read tag  throw exception", e);
894             }
895
896             if (!serviceNamespace.equals(namespace)) {
897                 continue;
898             }
899
900             if (!serviceVersion.equals(version)) {
901                 continue;
902             }
903             ifFindServiceForNS = true;
904             String serviceID = catalogService.getServiceId();
905             try {
906
907                 int delResult;
908                 if (DiscoverUtil.CONSUL_REGISTER_MODE.equals(ConfigUtil.getInstance().getConsulRegisterMode())) {
909                     delResult = ConsulCatalogServiceWrapper.getInstance().deleteService(serviceID);
910                 } else {
911                     delResult = ConsulAgentServiceWrapper.getInstance().deleteService(serviceID);
912                 }
913
914                 if (delResult != 200) {
915                     throw new Exception("delete consul service fail:" + delResult);
916                 }
917
918
919             } catch (Exception e) {
920                 LOGGER.error("delete consul service throw exception", e);
921                 throw new ExtendedInternalServerErrorException(e.getMessage());
922
923             }
924
925         }
926
927
928         if (!ifFindServiceForNS) {
929             String errInfo = "microservice not found: serviceName-" + serviceName + ",version-" + version
930                             + ",namespace-" + namespace;
931             throw new ExtendedNotFoundException(errInfo);
932         }
933
934         LOGGER.info("microservice delete success: serviceName-" + serviceName + ",version-" + version + ",namespace-"
935                         + namespace);
936
937     }
938
939     /**
940      * Title: deleteMicroServiceInstance Description: 刪除服务的节点信息
941      * 
942      * @param serviceName
943      * @param version
944      * @param ip
945      * @param port
946      * @see com.zte.ums.nfv.eco.hsif.msb.core.IMSBService#deleteMicroServiceInstance(java.lang.String,
947      *      java.lang.String, java.lang.String, java.lang.String)
948      */
949     public void deleteMicroServiceInstance(String serviceName, String version, String namespace, String ip,
950                     String port) {
951         if ("null".equals(version)) {
952             version = "";
953         }
954
955         checkServiceNameAndVersion(serviceName, version);
956
957
958         if (!RegExpTestUtil.ipRegExpTest(ip)) {
959             throw new UnprocessableEntityException(
960                             "delete MicroServiceInfo FAIL:IP(" + ip + ")is not a valid IP address");
961         }
962
963         if (!RegExpTestUtil.portRegExpTest(port)) {
964             throw new UnprocessableEntityException(
965                             "delete MicroServiceInfo FAIL:Port(" + port + ")is not a valid Port address");
966         }
967
968         String consul_serviceName = getServiceName4Consul(serviceName, version, namespace);
969
970         List<CatalogService> catalogServiceList = getConsulServices(consul_serviceName, version);
971
972
973         if (catalogServiceList == null || catalogServiceList.size() == 0) {
974             String errInfo = "microservice not found: serviceName-" + serviceName + ",version-" + version;
975             LOGGER.warn(errInfo);
976             throw new ExtendedNotFoundException(errInfo);
977
978         }
979
980         String node = "", serviceID = "";
981         boolean ifFindBNode = false;
982
983
984         for (CatalogService catalogService : catalogServiceList) {
985
986             String serviceAddress = catalogService.getServiceAddress();
987             String servicePort = String.valueOf(catalogService.getServicePort());
988
989
990
991             List<String> tagList = catalogService.getServiceTags();
992             String ms_version = "", ms_namespace = "";
993             try {
994
995                 for (String tag : tagList) {
996
997                     if (tag.startsWith("\"base\"")) {
998                         String ms_base_json = tag.split("\"base\":")[1];
999
1000
1001
1002                         Map<String, String> baseMap =
1003                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
1004                         if (baseMap.get("version") != null) {
1005                             ms_version = baseMap.get("version");
1006                         }
1007
1008
1009                     }
1010
1011                     if (tag.startsWith("\"ns\"")) {
1012                         String ms_ns_json = tag.split("\"ns\":")[1];
1013
1014
1015
1016                         Map<String, String> nsMap =
1017                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_ns_json, Map.class);
1018                         if (nsMap.get("namespace") != null) {
1019                             ms_namespace = nsMap.get("namespace");
1020                         }
1021
1022
1023                     }
1024                 }
1025
1026             } catch (Exception e) {
1027                 LOGGER.error(serviceName + " read tag  throw exception", e);
1028             }
1029             if (serviceAddress.equals(ip) && servicePort.equals(port) && ms_version.equals(version)
1030                             && ms_namespace.equals(namespace)) {
1031                 node = catalogService.getNode();
1032                 serviceID = catalogService.getServiceId();
1033                 ifFindBNode = true;
1034                 break;
1035             }
1036
1037
1038         }
1039
1040         if (!ifFindBNode) {
1041             throw new ExtendedNotFoundException("delete MicroServiceInfo FAIL: node-" + ip + ":" + port + " namespace-"
1042                             + namespace + " not found ");
1043         }
1044
1045
1046
1047         try {
1048             int delResult;
1049             if (DiscoverUtil.CONSUL_REGISTER_MODE.equals(ConfigUtil.getInstance().getConsulRegisterMode())) {
1050                 delResult = ConsulCatalogServiceWrapper.getInstance().deleteService(serviceID);
1051             } else {
1052                 delResult = ConsulAgentServiceWrapper.getInstance().deleteService(serviceID);
1053             }
1054
1055             if (delResult != 200) {
1056                 throw new Exception("delete consul service fail:" + delResult);
1057             }
1058
1059
1060         } catch (Exception e) {
1061             LOGGER.error("delete consul service throw exception", e);
1062             throw new ExtendedInternalServerErrorException(e.getMessage());
1063
1064         }
1065
1066     }
1067
1068     /**
1069      * @Title getConsulServices
1070      * @Description TODO(通过方法:根据服务名\版本号获取consul服务信息)
1071      * @param serviceName
1072      * @return
1073      * @return List<CatalogService>
1074      */
1075     private List<CatalogService> getConsulServices(String serviceName, String version) {
1076         // serviceName = serviceName.replace("/", "*");
1077         String consulServiceUrl = (new StringBuilder().append("http://")
1078                         .append(ConfigUtil.getInstance().getConsulAddress()).append(DiscoverUtil.CONSUL_CATALOG_URL)
1079                         .append("/service/").append(serviceName)).toString();
1080
1081         String resultJson = HttpClientUtil.httpGet(consulServiceUrl);
1082         List<CatalogService> catalogServiceList = (List<CatalogService>) JacksonJsonUtil.jsonToListBean(resultJson);
1083
1084         for (CatalogService catalogService : catalogServiceList) {
1085
1086
1087             List<String> tagList = catalogService.getServiceTags();
1088             String ms_version = "";
1089             try {
1090                 for (String tag : tagList) {
1091
1092                     if (tag.startsWith("\"base\"")) {
1093                         String ms_base_json = tag.split("\"base\":")[1];
1094
1095
1096                         Map<String, String> baseMap =
1097                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
1098                         if (baseMap.get("version") != null) {
1099                             ms_version = baseMap.get("version");
1100                         }
1101
1102                         break;
1103
1104                     }
1105                 }
1106             } catch (Exception e) {
1107                 LOGGER.error(serviceName + " read tag  throw exception", e);
1108             }
1109             if (!ms_version.equals(version)) {
1110                 catalogServiceList.remove(catalogService);
1111                 break;
1112             }
1113
1114
1115         }
1116         return catalogServiceList;
1117     }
1118
1119     /**
1120      * @Title getHealthServices
1121      * @Description TODO(通过方法:根据服务名获取consul服务健康检查信息)
1122      * @param serviceName
1123      * @return List<HealthService>
1124      */
1125     private ConsulResponse getHealthServices(String serviceName, boolean ifPassStatus, String wait, String index) {
1126         // serviceName = serviceName.replace("/", "*");
1127         StringBuilder healthServiceUrlBuilder =
1128                         new StringBuilder().append("http://").append(ConfigUtil.getInstance().getConsulAddress())
1129                                         .append(DiscoverUtil.CONSUL_HEALTH_URL).append(serviceName);
1130
1131         if (ifPassStatus) {
1132             healthServiceUrlBuilder.append("?passing");
1133         }
1134
1135         if (StringUtils.isNotBlank(wait) && StringUtils.isNotBlank(index)) {
1136             if (ifPassStatus) {
1137                 healthServiceUrlBuilder.append("&wait=").append(wait).append("&index=").append(index);
1138             } else {
1139                 healthServiceUrlBuilder.append("?wait=").append(wait).append("&index=").append(index);
1140             }
1141         }
1142
1143         return HttpClientUtil.httpWaitGet(healthServiceUrlBuilder.toString());
1144
1145     }
1146
1147
1148
1149     public void healthCheckbyTTL(String serviceName, String version, String namespace, NodeAddress checkNode) {
1150         // TODO Auto-generated method stub
1151         if ("null".equals(version)) {
1152             version = "";
1153         }
1154
1155         checkServiceNameAndVersion(serviceName, version);
1156
1157
1158         if (!RegExpTestUtil.ipRegExpTest(checkNode.getIp())) {
1159             throw new UnprocessableEntityException(
1160                             "healthCheck by TTL FAIL:IP(" + checkNode.getIp() + ")is not a valid IP address");
1161         }
1162
1163         if (!RegExpTestUtil.portRegExpTest(checkNode.getPort())) {
1164             throw new UnprocessableEntityException(
1165                             "healthCheck by TTL FAIL:Port(" + checkNode.getPort() + ")is not a valid Port address");
1166         }
1167
1168         String consul_serviceName = getServiceName4Consul(serviceName, version, namespace);
1169
1170         List<CatalogService> catalogServiceList = getConsulServices(consul_serviceName, version);
1171
1172
1173         if (catalogServiceList == null || catalogServiceList.size() == 0) {
1174             String errInfo = "microservice not found: serviceName-" + serviceName + ",version-" + version;
1175             LOGGER.warn(errInfo);
1176             throw new ExtendedNotFoundException(errInfo);
1177
1178         }
1179
1180
1181         boolean ifFindBNode = false;
1182
1183
1184         for (CatalogService catalogService : catalogServiceList) {
1185
1186             String serviceAddress = catalogService.getServiceAddress();
1187             String servicePort = String.valueOf(catalogService.getServicePort());
1188             boolean ifttlCheck = false;
1189
1190
1191             List<String> tagList = catalogService.getServiceTags();
1192             String ms_version = "", ms_namespace = "";
1193             try {
1194
1195                 for (String tag : tagList) {
1196
1197                     if (tag.startsWith("\"base\"")) {
1198                         String ms_base_json = tag.split("\"base\":")[1];
1199
1200                         Map<String, String> baseMap =
1201                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
1202                         if (baseMap.get("version") != null) {
1203                             ms_version = baseMap.get("version");
1204                         }
1205                     }
1206
1207                     if (tag.startsWith("\"ns\"")) {
1208                         String ms_ns_json = tag.split("\"ns\":")[1];
1209
1210                         Map<String, String> nsMap =
1211                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_ns_json, Map.class);
1212                         if (nsMap.get("namespace") != null) {
1213                             ms_namespace = nsMap.get("namespace");
1214                         }
1215                     }
1216
1217
1218                     if (tag.startsWith("\"checks\"")) {
1219                         String ms_check_json = tag.split("\"checks\":")[1];
1220                         Map<String, String> checkMap =
1221                                         (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_check_json, Map.class);
1222
1223                         // 自动注册健康检查
1224                         if (StringUtils.isNotBlank(checkMap.get("ttl"))) {
1225                             ifttlCheck = true;
1226                         }
1227                     }
1228                 }
1229
1230             } catch (Exception e) {
1231                 LOGGER.error(serviceName + " read tag  throw exception", e);
1232             }
1233
1234
1235
1236             if (serviceAddress.equals(checkNode.getIp()) && servicePort.equals(checkNode.getPort())
1237                             && ms_version.equals(version) && ms_namespace.equals(namespace)) {
1238                 if (!ifttlCheck) {
1239                     throw new ExtendedNotFoundException(
1240                                     "healthCheck by TTL FAIL: Service is not enabled TTL health check ");
1241                 }
1242                 ifFindBNode = true;
1243                 break;
1244             }
1245
1246
1247         }
1248
1249
1250
1251         if (!ifFindBNode) {
1252             throw new ExtendedNotFoundException("healthCheck by TTL FAIL: node-" + checkNode.getIp() + ":"
1253                             + checkNode.getPort() + " namespace-" + namespace + " not found ");
1254         }
1255
1256
1257
1258         try {
1259             String checkID = (new StringBuilder().append("service:").append(namespace).append("_").append(serviceName)
1260                             .append("_").append(checkNode.getIp()).append("_").append(checkNode.getPort())).toString();
1261
1262             String consulServiceUrl =
1263                             (new StringBuilder().append("http://").append(ConfigUtil.getInstance().getConsulAddress())
1264                                             .append(DiscoverUtil.CONSUL_AGENT_TTL_URL).append(checkID)).toString();
1265
1266             String result = HttpClientUtil.httpGet(consulServiceUrl);
1267             if ("CheckID does not have associated TTL".equals(result)) {
1268                 throw new ExtendedNotFoundException(
1269                                 "healthCheck by TTL FAIL: Service is not enabled TTL health check ");
1270             }
1271
1272         } catch (ExtendedInternalServerErrorException e) {
1273             throw e;
1274         } catch (Exception e) {
1275             throw new ExtendedInternalServerErrorException("healthCheck by TTL FAIL:" + e.getMessage());
1276         }
1277
1278
1279
1280     }
1281
1282     // public MicroServiceFullInfo getApigatewayServiceInfo4Host(String namespace){
1283     // return getMicroServiceInstance(DiscoverUtil.APIGATEWAY_SERVINCE, "v1", namespace);
1284     // }
1285     //
1286
1287
1288
1289     public List<MicroServiceFullInfo> getMicroServiceForNodes(String serviceName, String version, boolean ifPassStatus,
1290                     String labels, String namespace) {
1291         // TODO Auto-generated method stub
1292         if ("null".equals(version)) {
1293             version = "";
1294         }
1295
1296         checkServiceNameAndVersion(serviceName, version);
1297
1298         if (!RegExpTestUtil.labelRegExpTest(labels)) {
1299             throw new UnprocessableEntityException(
1300                             "get MicroServiceInfo FAIL: The label query parameter format is wrong (key:value)");
1301         }
1302
1303
1304         String consul_serviceName = getServiceName4Consul(serviceName, version, namespace);
1305
1306         ConsulResponse consulResponse = getHealthServices(consul_serviceName, ifPassStatus, "", "");
1307         if (consulResponse == null) {
1308             String errInfo = "microservice not found: serviceName-" + serviceName;
1309             throw new ExtendedNotFoundException(errInfo);
1310         }
1311         String resultJson = (String) consulResponse.getResponse();
1312         List<HealthService> healthServiceList =
1313                         JacksonJsonUtil.jsonToListBean(resultJson, new TypeReference<List<HealthService>>() {});
1314
1315
1316         if (healthServiceList == null || healthServiceList.size() == 0) {
1317             String errInfo = "microservice not found: serviceName-" + serviceName;
1318             throw new ExtendedNotFoundException(errInfo);
1319         }
1320
1321         try {
1322
1323             // label query,format key:value|value2,key2:value2
1324             boolean islabelQuery = false;
1325             Map<String, String> query_labelMap = new HashMap<String, String>();
1326             if (StringUtils.isNotBlank(labels)) {
1327                 islabelQuery = true;
1328                 String[] routeLabels = StringUtils.split(labels, ",");
1329
1330                 for (int i = 0; i < routeLabels.length; i++) {
1331                     String[] labelArray = StringUtils.split(routeLabels[i], ":");
1332                     query_labelMap.put(labelArray[0], labelArray[1]);
1333                 }
1334             }
1335
1336             List<MicroServiceFullInfo> microServiceInfoList = new ArrayList<MicroServiceFullInfo>();
1337
1338
1339
1340             for (HealthService healthService : healthServiceList) {
1341
1342                 Set<NodeInfo> nodes = new HashSet<NodeInfo>();
1343                 Set<String> serviceLabels = new HashSet<String>();
1344                 String nodeNamespace = "";
1345                 MicroServiceFullInfo microServiceInfo = new MicroServiceFullInfo();
1346
1347                 Service service = healthService.getService();
1348                 List<String> tagList = service.getTags();
1349
1350                 String ms_url = "", ms_version = "", ms_protocol = "", ms_status = "", ms_publish_port = "",
1351                                 ms_is_manual = "", ms_visualRange = "1", ms_network_plane_type = "", ms_lb_policy = "",
1352                                 ms_host = "", ms_path = "", ms_enable_ssl = "";
1353                 List<KeyVaulePair> ms_metadata = new ArrayList<KeyVaulePair>();
1354
1355                 List<String> nodeLabels = new ArrayList<String>();
1356                 Map<String, String> labelMap = new HashMap<String, String>();
1357
1358                 NodeInfo node = new NodeInfo();
1359
1360                 node.setIp(service.getAddress());
1361                 node.setPort(String.valueOf(service.getPort()));
1362                 node.setNodeId(service.getId());
1363
1364
1365
1366                 try {
1367
1368                     for (String tag : tagList) {
1369
1370
1371                         if (tag.startsWith("\"base\"")) {
1372                             String ms_base_json = tag.split("\"base\":")[1];
1373
1374                             Map<String, String> baseMap =
1375                                             (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_base_json, Map.class);
1376                             ms_url = (baseMap.get("url") == null ? "" : baseMap.get("url"));
1377                             ms_version = (baseMap.get("version") == null ? "" : baseMap.get("version"));
1378                             ms_protocol = (baseMap.get("protocol") == null ? "" : baseMap.get("protocol"));
1379                             ms_status = (baseMap.get("status") == null ? "1" : baseMap.get("status"));
1380
1381                             if (baseMap.get("publish_port") != null) {
1382                                 ms_publish_port = (baseMap.get("publish_port"));
1383                             }
1384
1385                             if (baseMap.get("is_manual") != null) {
1386                                 ms_is_manual = baseMap.get("is_manual");
1387
1388                             }
1389
1390                             if (baseMap.get("ha_role") != null) {
1391                                 node.setHa_role(baseMap.get("ha_role"));
1392                             }
1393
1394                             if (baseMap.get("host") != null) {
1395                                 ms_host = baseMap.get("host");
1396                             }
1397
1398                             if (baseMap.get("path") != null) {
1399                                 ms_path = baseMap.get("path");
1400                             }
1401
1402                             if (baseMap.get("enable_ssl") != null) {
1403                                 ms_publish_port = (baseMap.get("enable_ssl"));
1404                             }
1405
1406                             continue;
1407                         }
1408
1409                         if (tag.startsWith("\"labels\"")) {
1410                             String ms_labels_json = "{" + tag.split("\"labels\":\\{")[1];
1411                             labelMap = (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_labels_json, Map.class);
1412
1413
1414
1415                             for (Map.Entry<String, String> labelEntry : labelMap.entrySet()) {
1416                                 if ("visualRange".equals(labelEntry.getKey())) {
1417                                     ms_visualRange = labelEntry.getValue();
1418                                 } else if ("network_plane_type".equals(labelEntry.getKey())) {
1419                                     ms_network_plane_type = labelEntry.getValue();
1420                                 } else {
1421                                     nodeLabels.add(labelEntry.getKey() + ":" + labelEntry.getValue());
1422                                 }
1423
1424                             }
1425
1426
1427                             continue;
1428                         }
1429
1430                         if (tag.startsWith("\"ns\"")) {
1431                             String ms_namespace_json = tag.split("\"ns\":")[1];
1432                             Map<String, String> namespaceMap = (Map<String, String>) JacksonJsonUtil
1433                                             .jsonToBean(ms_namespace_json, Map.class);
1434
1435                             if (namespaceMap.get("namespace") != null) {
1436                                 nodeNamespace = namespaceMap.get("namespace");
1437                             } else {
1438                                 nodeNamespace = "";
1439                             }
1440
1441                             continue;
1442                         }
1443
1444                         if (tag.startsWith("\"lb\"")) {
1445                             String ms_lb_json = tag.split("\"lb\":")[1];
1446                             Map<String, String> lbMap =
1447                                             (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_lb_json, Map.class);
1448
1449                             if (lbMap.get("lb_policy") != null) {
1450                                 ms_lb_policy = lbMap.get("lb_policy");
1451                                 if (ms_lb_policy.startsWith("hash") || ms_lb_policy.equals("ip_hash")) {
1452                                     ms_lb_policy = "ip_hash";
1453                                 }
1454
1455                             }
1456
1457                             if (lbMap.get("lb_server_params") != null) {
1458                                 node.setLb_server_params(lbMap.get("lb_server_params").replace(" ", ","));
1459                             }
1460
1461                             continue;
1462                         }
1463
1464                         if (tag.startsWith("\"checks\"")) {
1465                             String ms_check_json = tag.split("\"checks\":")[1];
1466                             Map<String, String> checkMap =
1467                                             (Map<String, String>) JacksonJsonUtil.jsonToBean(ms_check_json, Map.class);
1468
1469
1470                             // 自动注册健康检查
1471                             if (StringUtils.isNotBlank(checkMap.get("ttl"))) {
1472                                 node.setCheckType("TTL");
1473                                 node.setTtl(checkMap.get("ttl"));
1474                             } else if (StringUtils.isNotBlank(checkMap.get("http"))) {
1475                                 node.setCheckType("HTTP");
1476                                 node.setCheckUrl(checkMap.get("http"));
1477                                 if (checkMap.get("interval") != null)
1478                                     node.setCheckInterval(checkMap.get("interval"));
1479                                 if (checkMap.get("timeout") != null)
1480                                     node.setCheckTimeOut(checkMap.get("timeout"));
1481                             } else if (StringUtils.isNotBlank(checkMap.get("tcp"))) {
1482                                 node.setCheckType("TCP");
1483                                 node.setCheckUrl(checkMap.get("tcp"));
1484                                 if (checkMap.get("interval") != null)
1485                                     node.setCheckInterval(checkMap.get("interval"));
1486                                 if (checkMap.get("timeout") != null)
1487                                     node.setCheckTimeOut(checkMap.get("timeout"));
1488                             }
1489
1490                             continue;
1491                         }
1492
1493                         if (tag.startsWith("\"metadata\"")) {
1494                             String ms_metadata_json = "{" + tag.split("\"metadata\":\\{")[1];
1495                             Map<String, String> metadataMap = (Map<String, String>) JacksonJsonUtil
1496                                             .jsonToBean(ms_metadata_json, Map.class);
1497
1498
1499
1500                             for (Map.Entry<String, String> entry : metadataMap.entrySet()) {
1501                                 KeyVaulePair keyVaulePair = new KeyVaulePair();
1502                                 keyVaulePair.setKey(entry.getKey());
1503                                 keyVaulePair.setValue(entry.getValue());
1504                                 ms_metadata.add(keyVaulePair);
1505                             }
1506
1507                             continue;
1508                         }
1509
1510
1511
1512                     }
1513
1514                 } catch (Exception e) {
1515                     LOGGER.error(serviceName + " read tag  throw exception", e);
1516                 }
1517
1518                 // 健康检查信息
1519                 List<Check> checks = healthService.getChecks();
1520                 node.setStatus("passing");
1521                 for (Check check : checks) {
1522                     if (!"passing".equals(check.getStatus())) {
1523                         node.setStatus(check.getStatus());
1524                         break;
1525                     }
1526                 }
1527
1528                 if (!ms_version.equals(version)) {
1529                     continue;
1530                 }
1531
1532                 // namespace过滤
1533                 if (!namespace.equals(nodeNamespace)) {
1534                     continue;
1535                 }
1536
1537                 // 标签过滤
1538                 if (islabelQuery) {
1539                     boolean ifMatchLabel = false;
1540                     for (Map.Entry<String, String> query_entry : query_labelMap.entrySet()) {
1541                         String key = query_entry.getKey();
1542                         String value = query_entry.getValue();
1543                         if (StringUtils.isBlank(labelMap.get(key))) {
1544                             continue;
1545                         }
1546
1547                         String[] queryTagArray = StringUtils.split(value, "|");
1548                         String[] serviceTagArray = StringUtils.split(labelMap.get(key), "|");
1549                         if (DiscoverUtil.contain(queryTagArray, serviceTagArray)) {
1550                             ifMatchLabel = true;
1551                             break;
1552                         }
1553
1554                     }
1555
1556                     if (!ifMatchLabel) {
1557                         continue;
1558                     }
1559                 }
1560
1561
1562                 nodes.add(node);
1563                 serviceLabels.addAll(nodeLabels);
1564
1565                 microServiceInfo.setServiceName(serviceName);
1566                 microServiceInfo.setUrl(ms_url);
1567                 microServiceInfo.setVersion(ms_version);
1568                 microServiceInfo.setProtocol(ms_protocol);
1569                 microServiceInfo.setStatus(null);
1570                 microServiceInfo.setPublish_port(ms_publish_port);
1571                 microServiceInfo.setIs_manual(Boolean.parseBoolean(ms_is_manual));
1572                 microServiceInfo.setVisualRange(ms_visualRange);
1573                 microServiceInfo.setNetwork_plane_type(ms_network_plane_type);
1574                 microServiceInfo.setLb_policy(ms_lb_policy);
1575                 microServiceInfo.setHost(ms_host);
1576                 microServiceInfo.setPath(ms_path);
1577                 microServiceInfo.setEnable_ssl(Boolean.parseBoolean(ms_enable_ssl));
1578
1579                 microServiceInfo.setMetadata(ms_metadata);
1580                 microServiceInfo.setNamespace(namespace);
1581                 microServiceInfo.setLabels(new ArrayList<String>(serviceLabels));
1582                 microServiceInfo.setNodes(nodes);
1583
1584                 microServiceInfoList.add(microServiceInfo);
1585             }
1586
1587
1588
1589             if (microServiceInfoList.size() == 0) {
1590                 String errInfo = "microservice not found: serviceName-" + serviceName + ",version-" + version
1591                                 + ",namespace-" + namespace + ",labels-" + labels;
1592                 throw new ExtendedNotFoundException(errInfo);
1593             }
1594
1595
1596
1597             return microServiceInfoList;
1598
1599
1600         } catch (ExtendedNotFoundException e) {
1601             throw e;
1602         } catch (Exception e) {
1603             throw new ExtendedInternalServerErrorException(e.getMessage());
1604         }
1605     }
1606
1607
1608     private String getServiceName4Consul(String serviceName, String version, String namespace) {
1609         String consul_serviceName = serviceName;
1610
1611         if (StringUtils.isNotBlank(version)) {
1612             consul_serviceName = consul_serviceName + "-" + version;
1613         }
1614
1615         if (StringUtils.isNotBlank(namespace)) {
1616             consul_serviceName = consul_serviceName + "-" + namespace;
1617         }
1618
1619         return consul_serviceName;
1620     }
1621
1622
1623
1624     private void checkMicroServiceInfo(MicroServiceInfo microServiceInfo) {
1625
1626         if (StringUtils.isBlank(microServiceInfo.getServiceName())
1627                         || StringUtils.isBlank(microServiceInfo.getProtocol())) {
1628             throw new UnprocessableEntityException("register MicroServiceInfo FAIL: Some required fields are empty");
1629         }
1630
1631         if (microServiceInfo.getNodes() == null || microServiceInfo.getNodes().size() == 0) {
1632             throw new UnprocessableEntityException("register MicroServiceInfo FAIL: Nodes fields are empty");
1633         }
1634
1635         if (!RegExpTestUtil.serviceNameRegExpTest(microServiceInfo.getServiceName().trim())) {
1636             throw new UnprocessableEntityException("register MicroServiceInfo FAIL:ServiceName("
1637                             + microServiceInfo.getServiceName() + ")  format error");
1638         }
1639
1640         if (StringUtils.isNotBlank(microServiceInfo.getHost())) {
1641             if (!RegExpTestUtil.serviceNameRegExpTest(microServiceInfo.getHost().trim())) {
1642                 throw new UnprocessableEntityException(
1643                                 "register MicroServiceInfo host (" + microServiceInfo.getHost() + ")  format error");
1644             }
1645         }
1646
1647         if (StringUtils.isNotBlank(microServiceInfo.getLb_policy())) {
1648             if (!DiscoverUtil.checkExist(DiscoverUtil.LB_POLICY_LIST, microServiceInfo.getLb_policy().trim(), ",")) {
1649                 throw new UnprocessableEntityException("register MicroServiceInfo FAIL:lb_policy is wrong,value range:("
1650                                 + DiscoverUtil.LB_POLICY_LIST + ")");
1651             }
1652
1653         }
1654
1655         if (StringUtils.isNotBlank(microServiceInfo.getVersion())) {
1656             if (!RegExpTestUtil.versionRegExpTest(microServiceInfo.getVersion())) {
1657                 throw new UnprocessableEntityException("register MicroServiceInfo FAIL:version is not a valid  format");
1658
1659             }
1660         }
1661
1662
1663
1664         if (StringUtils.isNotBlank(microServiceInfo.getUrl())) {
1665
1666             String url = microServiceInfo.getUrl();
1667             if (!"/".equals(url)) {
1668                 if (!url.startsWith("/")) {
1669                     url = "/" + url;
1670                     microServiceInfo.setUrl(url);
1671                 }
1672
1673                 if (url.endsWith("/")) {
1674                     url = url.substring(0, url.length() - 1);
1675                     microServiceInfo.setUrl(url);
1676                 }
1677             }
1678
1679             if (!RegExpTestUtil.urlRegExpTest(url)) {
1680                 throw new UnprocessableEntityException(
1681                                 "register MicroServiceInfo FAIL:url (" + url + ") is not a valid format");
1682             }
1683
1684         } else {
1685             microServiceInfo.setUrl("/");
1686         }
1687
1688
1689         if (StringUtils.isNotBlank(microServiceInfo.getPath())) {
1690
1691             String path = microServiceInfo.getPath();
1692             if (!"/".equals(path)) {
1693                 if (!path.startsWith("/")) {
1694                     path = "/" + path;
1695                     microServiceInfo.setPath(path);
1696                 }
1697
1698                 if (path.endsWith("/")) {
1699                     path = path.substring(0, path.length() - 1);
1700                     microServiceInfo.setPath(path);
1701                 }
1702             }
1703
1704             if (!RegExpTestUtil.urlRegExpTest(path)) {
1705                 throw new UnprocessableEntityException(
1706                                 "register MicroServiceInfo FAIL:path (" + path + ") is not a valid format");
1707
1708             }
1709
1710
1711
1712         }
1713
1714
1715         for (Node node : microServiceInfo.getNodes()) {
1716
1717             if (StringUtils.isNotBlank(node.getIp())) {
1718                 if (!RegExpTestUtil.ipRegExpTest(node.getIp())) {
1719                     throw new UnprocessableEntityException(
1720                                     "register MicroServiceInfo FAIL:IP(" + node.getIp() + ")is not a valid ip address");
1721                 }
1722             }
1723
1724             if (!RegExpTestUtil.portRegExpTest(node.getPort())) {
1725                 throw new UnprocessableEntityException("register MicroServiceInfo FAIL:Port(" + node.getPort()
1726                                 + ")is not a valid Port address");
1727             }
1728
1729
1730             if (StringUtils.isNotBlank(node.getLb_server_params())) {
1731                 try {
1732                     String[] lb_server_params_array = node.getLb_server_params().split(",");
1733                     for (int i = 0; i < lb_server_params_array.length; i++) {
1734                         String params = lb_server_params_array[i].split("=")[0];
1735                         if (!DiscoverUtil.checkExist(DiscoverUtil.LB_PARAMS_LIST, params, ",")) {
1736                             throw new UnprocessableEntityException(
1737                                             "register MicroServiceInfo FAIL:lb_server_params is wrong:"
1738                                                             + lb_server_params_array[i]);
1739                         }
1740                     }
1741                 } catch (Exception e) {
1742                     throw new UnprocessableEntityException(
1743                                     "register MicroServiceInfo FAIL:lb_server_params'format is wrong:"
1744                                                     + node.getLb_server_params());
1745                 }
1746
1747             }
1748
1749             if (StringUtils.isNotBlank(node.getCheckType())) {
1750                 if (!DiscoverUtil.checkExist(DiscoverUtil.CHECK_TYPE_LIST, node.getCheckType().trim(), ",")) {
1751                     throw new UnprocessableEntityException(
1752                                     "register MicroServiceInfo FAIL:checkType is wrong,value range:("
1753                                                     + DiscoverUtil.CHECK_TYPE_LIST + ")");
1754                 }
1755
1756
1757                 if ("HTTP".equals(node.getCheckType()) || "TCP".equals(node.getCheckType())) {
1758                     String checkUrl = node.getCheckUrl();
1759                     if (StringUtils.isBlank(checkUrl)) {
1760                         throw new UnprocessableEntityException(
1761                                         "register MicroServiceInfo FAIL:checkUrl field is empty");
1762                     }
1763
1764                     if ("HTTP".equals(node.getCheckType())) {
1765
1766
1767                         if (RegExpTestUtil.httpUrlRegExpTest(checkUrl)) {
1768                             if (!checkUrl.startsWith("http://")) {
1769                                 checkUrl = "http://" + checkUrl;
1770                                 node.setCheckUrl(checkUrl);
1771                             }
1772                         } else {
1773                             if (!checkUrl.startsWith("/")) {
1774                                 checkUrl = "/" + checkUrl;
1775                             }
1776                             checkUrl = "http://" + node.getIp() + ":" + node.getPort() + checkUrl;
1777                             node.setCheckUrl(checkUrl);
1778                         }
1779                     }
1780
1781
1782                 }
1783
1784             }
1785
1786             if (StringUtils.isNotBlank(node.getHa_role())) {
1787                 if (!DiscoverUtil.checkExist(DiscoverUtil.CHECK_HA_ROLE_LIST, node.getHa_role().trim(), ",")) {
1788                     throw new UnprocessableEntityException(
1789                                     "register MicroServiceInfo FAIL:ha_role is wrong,value range:("
1790                                                     + DiscoverUtil.CHECK_HA_ROLE_LIST + ")");
1791                 }
1792             }
1793
1794
1795         }
1796
1797
1798
1799         String[] visualRangeArray = StringUtils.split(microServiceInfo.getVisualRange(), "|");
1800         for (int i = 0; i < visualRangeArray.length; i++) {
1801             if (!DiscoverUtil.checkExist(DiscoverUtil.VISUAL_RANGE_LIST, visualRangeArray[i], ",")) {
1802                 throw new UnprocessableEntityException("register MicroServiceInfo FAIL:type is wrong,value range:("
1803                                 + DiscoverUtil.VISUAL_RANGE_LIST + ")");
1804             }
1805         }
1806
1807         microServiceInfo.setProtocol(microServiceInfo.getProtocol().toUpperCase());
1808         if (!DiscoverUtil.checkExist(DiscoverUtil.PROTOCOL_LIST, microServiceInfo.getProtocol().trim(), ",")) {
1809             throw new UnprocessableEntityException("register MicroServiceInfo FAIL:Protocol is wrong,value range:("
1810                             + DiscoverUtil.PROTOCOL_LIST + ")");
1811         }
1812
1813         if (microServiceInfo.getLabels() != null) {
1814             for (String label : microServiceInfo.getLabels()) {
1815                 if (!RegExpTestUtil.labelRegExpTest(label)) {
1816                     throw new UnprocessableEntityException("register MicroServiceInfo FAIL:label[" + label
1817                                     + "] is not a valid format(key:value)");
1818                 }
1819             }
1820         }
1821
1822
1823
1824         // 判断自定义发布端口
1825         if (StringUtils.isNotBlank(microServiceInfo.getPublish_port())) {
1826
1827             if (DiscoverUtil.checkExist(DiscoverUtil.HTTP_PROTOCOL, microServiceInfo.getProtocol())) {
1828
1829                 if (microServiceInfo.getPublish_port().contains("|")) {
1830
1831                     String[] publishPortArray = StringUtils.split(microServiceInfo.getPublish_port(), "|");
1832
1833                     int portNum = publishPortArray.length;
1834
1835                     // 判断端口格式
1836                     for (int i = 0; i < portNum; i++) {
1837                         if (!RegExpTestUtil.portRegExpTest(publishPortArray[i])) {
1838                             throw new UnprocessableEntityException("register MicroServiceInfo FAIL:Public Port("
1839                                             + publishPortArray[i] + ")is not a valid Port address");
1840                         }
1841                     }
1842
1843                     // 判断端口数量
1844                     if (portNum == 0 || portNum > 2) {
1845                         throw new UnprocessableEntityException(
1846                                         "register MicroServiceInfo FAIL:Public Port num is wrong:" + portNum);
1847                     } else if (portNum == 2) {
1848                         // 判断端口值是否一样
1849                         if (publishPortArray[0].equals(publishPortArray[1])) {
1850                             throw new UnprocessableEntityException(
1851                                             "register MicroServiceInfo FAIL:Two ports have the same value :"
1852                                                             + publishPortArray[0]);
1853                         }
1854                     } else if (portNum == 1) {
1855                         throw new UnprocessableEntityException(
1856                                         "register MicroServiceInfo FAIL:Two ports have one null value");
1857                     }
1858                 } else {
1859                     if (!RegExpTestUtil.portRegExpTest(microServiceInfo.getPublish_port())) {
1860                         throw new UnprocessableEntityException("register MicroServiceInfo FAIL:Public Port("
1861                                         + microServiceInfo.getPublish_port() + ")is not a valid Port address");
1862                     }
1863                 }
1864
1865             } else if ("TCP".equals(microServiceInfo.getProtocol()) || "UDP".equals(microServiceInfo.getProtocol())) {
1866                 if (!RegExpTestUtil.portRegExpTest(microServiceInfo.getPublish_port())) {
1867                     throw new UnprocessableEntityException("register MicroServiceInfo FAIL:Public Port("
1868                                     + microServiceInfo.getPublish_port() + ")is not a valid Port address");
1869                 }
1870
1871                 int tcpUdpPortRangeStart = Integer.parseInt(ConfigUtil.getInstance().getTcpudpPortRangeStart());
1872                 int tcpUdpPortRangeEnd = Integer.parseInt(ConfigUtil.getInstance().getTcpudpPortRangeEnd());
1873                 int iPublishPort = Integer.parseInt(microServiceInfo.getPublish_port());
1874
1875                 if (iPublishPort > tcpUdpPortRangeEnd || iPublishPort < tcpUdpPortRangeStart) {
1876                     throw new UnprocessableEntityException("register MicroServiceInfo FAIL:Public_Port Range ("
1877                                     + tcpUdpPortRangeStart + "-" + tcpUdpPortRangeEnd + ")");
1878                 }
1879
1880             } else {
1881                 microServiceInfo.setPublish_port("");
1882             }
1883
1884
1885
1886         }
1887
1888
1889
1890     }
1891
1892
1893     private void checkServiceNameAndVersion(String serviceName, String version) {
1894         if (StringUtils.isBlank(serviceName)) {
1895             throw new UnprocessableEntityException("check MicroServiceInfo FAIL:serviceName  can't be empty");
1896         }
1897
1898         if (!RegExpTestUtil.serviceNameRegExpTest(serviceName)) {
1899             throw new UnprocessableEntityException(
1900                             "check MicroServiceInfo FAIL:ServiceName(" + serviceName + ") format error");
1901         }
1902
1903         if (StringUtils.isNotBlank(version)) {
1904             if (!RegExpTestUtil.versionRegExpTest(version)) {
1905                 throw new UnprocessableEntityException("check MicroServiceInfo FAIL:version is not a valid  format");
1906             }
1907         }
1908     }
1909 }