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