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