remove not required docs and .readthedocs.yaml
[msb/discovery.git] / sdclient / discovery-service / src / main / java / org / onap / msb / sdclient / wrapper / PublishAddressWrapper.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 import java.util.concurrent.Callable;
23 import java.util.concurrent.ExecutionException;
24 import java.util.concurrent.ExecutorService;
25 import java.util.concurrent.Executors;
26 import java.util.concurrent.Future;
27 import java.util.concurrent.TimeUnit;
28 import java.util.concurrent.TimeoutException;
29
30 import org.apache.commons.lang3.StringUtils;
31 import org.onap.msb.sdclient.core.KeyVaulePair;
32 import org.onap.msb.sdclient.core.MicroServiceFullInfo;
33 import org.onap.msb.sdclient.core.NodeInfo;
34 import org.onap.msb.sdclient.core.PublishAddress;
35 import org.onap.msb.sdclient.core.PublishFullAddress;
36 import org.onap.msb.sdclient.core.exception.ExtendedNotFoundException;
37 import org.onap.msb.sdclient.core.exception.UnprocessableEntityException;
38 import org.onap.msb.sdclient.wrapper.util.DiscoverUtil;
39 import org.onap.msb.sdclient.wrapper.util.RegExpTestUtil;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 public class PublishAddressWrapper {
44
45     private static PublishAddressWrapper instance = new PublishAddressWrapper();
46
47
48     private PublishAddressWrapper() {}
49
50     public static PublishAddressWrapper getInstance() {
51         return instance;
52     }
53
54     private final String ROUTE_DEFAULT_WAY = "ip";
55
56     private final String ROUTE_IP = "ip";
57
58     private final String ROUTE_DOMAIN = "domain";
59
60     private final String ROUTE_DEFAULT_SUBDOMAIN = "openpalette.zte.com.cn";
61
62     private final String METADATA_ROUTE_WAY = "routeWay";
63
64     private final String METADATA_ROUTE_SUBDOMAIN = "routeSubdomain";
65
66
67
68     private static final Logger LOGGER = LoggerFactory.getLogger(PublishAddressWrapper.class);
69
70     public static volatile Map<String, List<MicroServiceFullInfo>> publishApigateWayList =
71                     new HashMap<String, List<MicroServiceFullInfo>>();
72
73     private ConsulClientApp consulClientApp;
74
75
76     ExecutorService exec = Executors.newCachedThreadPool();
77
78
79     public void setConsulClientApp(ConsulClientApp consulClientApp) {
80         this.consulClientApp = consulClientApp;
81     }
82
83
84
85     /**
86      * @Title getAllPublishaddress
87      * @Description TODO(get all publishaddresss list by service,rest-interface master methods)
88      * @param serviceName
89      * @param version
90      * @param namespace
91      * @param visualRange
92      * @return
93      * @return List<PublishFullAddress>
94      */
95     public Set<PublishFullAddress> getAllPublishaddress(String serviceName, String version, String namespace,
96                     String visualRange) {
97
98         if ("null".equals(version)) {
99             version = "";
100         }
101
102
103         // 1.Check input parameter format efficacy
104         checkServiceInputFormat(serviceName, version, visualRange);
105
106
107
108         // 2.get service Info
109         MicroServiceFullInfo serviceInfo =
110                         ConsulServiceWrapper.getInstance().getMicroServiceInstance(serviceName, version, namespace);
111
112         if (!DiscoverUtil.checkExist(DiscoverUtil.PUBLISH_PROTOCOL, serviceInfo.getProtocol())) {
113             throw new ExtendedNotFoundException("This service's Protocol (" + serviceInfo.getProtocol()
114                             + ") is not published to apigateway");
115         }
116
117         if ("TCP".equals(serviceInfo.getProtocol()) || "UDP".equals(serviceInfo.getProtocol())) {
118             if (StringUtils.isBlank(serviceInfo.getPublish_port())) {
119                 throw new ExtendedNotFoundException("This service's  Protocol (" + serviceInfo.getProtocol()
120                                 + ") is not published to apigateway");
121             }
122         }
123
124         Set<PublishFullAddress> publishFullAddressList = new HashSet<PublishFullAddress>();
125
126         // 3.get in-system apigateway publish address (visualRange=1)
127         if (DiscoverUtil.checkVisualRangeIn(visualRange)) {
128             Set<PublishFullAddress> publishFullAddressInList =
129                             getPublishFullAddress(namespace, DiscoverUtil.VISUAL_RANGE_IN, serviceInfo);
130             if (publishFullAddressInList != null && publishFullAddressInList.size() > 0) {
131                 publishFullAddressList.addAll(publishFullAddressInList);
132             }
133
134         }
135
136         // 4.get out-system apigateway publish address (visualRange=0)
137         if (DiscoverUtil.checkVisualRangeOut(visualRange)) {
138             Set<PublishFullAddress> publishFullAddressOutList =
139                             getPublishFullAddress(namespace, DiscoverUtil.VISUAL_RANGE_OUT, serviceInfo);
140             if (publishFullAddressOutList != null && publishFullAddressOutList.size() > 0) {
141                 publishFullAddressList.addAll(publishFullAddressOutList);
142             }
143         }
144
145         if (publishFullAddressList.size() > 0) {
146             return publishFullAddressList;
147         }
148
149         throw new ExtendedNotFoundException("This service's publish Address is not found");
150     }
151
152     /**
153      * @Title getApigatewayServiceInfo
154      * @Description TODO(get one apigatewayServiceInfo by namespace,rest-interface master methods)
155      * @param namespace
156      * @param visualRange
157      * @return
158      * @return List<MicroServiceFullInfo>
159      */
160     public Set<MicroServiceFullInfo> getApigatewayServiceInfo(String namespace, String visualRange) {
161
162         if (!DiscoverUtil.checkExist(DiscoverUtil.VISUAL_RANGE_LIST, visualRange, ",")) {
163             throw new UnprocessableEntityException("get ApigatewayServiceInfo FAIL:visualRange is wrong,value range:("
164                             + DiscoverUtil.VISUAL_RANGE_LIST + ")");
165         }
166
167         List<MicroServiceFullInfo> apigatewayList;
168
169         if (DiscoverUtil.checkVisualRangeIn(visualRange)) {
170             apigatewayList = getApiGateWayFromCache(DiscoverUtil.APIGATEWAY_SERVINCE, namespace);
171
172         } else {
173             apigatewayList = getApiGateWayFromCache(DiscoverUtil.ROUTER_SERVINCE, namespace);
174
175             if (apigatewayList != null) {
176                 if (StringUtils.isNotBlank(System.getenv("ROUTER_IP"))) {
177                     for (MicroServiceFullInfo routerInfo : apigatewayList) {
178                         for (NodeInfo node : routerInfo.getNodes()) {
179                             node.setIp(System.getenv("ROUTER_IP"));
180                         }
181
182                     }
183                 }
184             }
185         }
186
187
188         if (apigatewayList == null || apigatewayList.isEmpty()) {
189             throw new ExtendedNotFoundException("This service's  publish Address is not found");
190         } else {
191             Set<MicroServiceFullInfo> apigatewaySet = new HashSet<MicroServiceFullInfo>(apigatewayList);
192             return apigatewaySet;
193         }
194
195
196
197     }
198
199
200
201     /**
202      * @Title convert2PublishFullAddress
203      * @Description TODO(convert to PublishFullAddress from MicroServiceFullInfo )
204      * @param apigatewayInfo
205      * @param serviceInfo
206      * @return List<PublishFullAddress>
207      */
208     private List<PublishFullAddress> convert2PublishFullAddress(MicroServiceFullInfo apigatewayInfo,
209                     MicroServiceFullInfo serviceInfo) {
210
211         List<PublishFullAddress> publishFullAddressList = new ArrayList<PublishFullAddress>();
212
213
214
215         String routeWay = this.ROUTE_DEFAULT_WAY, routeSubdomain = this.ROUTE_DEFAULT_SUBDOMAIN;
216
217         List<KeyVaulePair> metadata = apigatewayInfo.getMetadata();
218         if (metadata != null) {
219
220             for (KeyVaulePair keyVaulePair : metadata) {
221                 if (this.METADATA_ROUTE_WAY.equals(keyVaulePair.getKey())) {
222                     routeWay = keyVaulePair.getValue();
223                 }
224                 if (this.METADATA_ROUTE_SUBDOMAIN.equals(keyVaulePair.getKey())) {
225                     routeSubdomain = keyVaulePair.getValue();
226                 }
227             }
228         }
229
230         NodeInfo apigatewayNode = (NodeInfo) apigatewayInfo.getNodes().toArray()[0];
231
232         String[] routeWays = StringUtils.split(routeWay, DiscoverUtil.SPLIT_LINE);
233         for (int i = 0; i < routeWays.length; i++) {
234             PublishFullAddress publishFullAddress = new PublishFullAddress();
235             // set service publish visualRange
236             publishFullAddress.setVisualRange(apigatewayInfo.getVisualRange());
237             if (this.ROUTE_IP.equals(routeWays[i])) {
238                 // ----routeWay:ip-----
239
240                 // set service publish ip
241                 publishFullAddress.setIp(apigatewayNode.getIp());
242                 if (DiscoverUtil.VISUAL_RANGE_OUT.equals(apigatewayInfo.getVisualRange())) {
243                     if (StringUtils.isNotBlank(System.getenv("ROUTER_IP"))) {
244                         publishFullAddress.setIp(System.getenv("ROUTER_IP"));
245                     }
246                 }
247
248
249
250                 // set service publish url
251                 publishFullAddress.setPublish_url(getPublishUrl4IP(serviceInfo));
252
253                 // set service port
254                 if (DiscoverUtil.VISUAL_RANGE_IN.equals(apigatewayInfo.getVisualRange())) {
255                     publishFullAddress.setPort(apigatewayNode.getPort());
256                     publishFullAddress.setPublish_protocol("http");
257                     publishFullAddressList.add(publishFullAddress);
258                 } else {
259
260                     String[] publishPorts = StringUtils.split(serviceInfo.getPublish_port(), DiscoverUtil.SPLIT_LINE);
261                     if (publishPorts.length == 2) {
262                         // multiPublishPort: https|http
263                         publishFullAddress.setPort(publishPorts[0]);
264                         publishFullAddress.setPublish_protocol("https");
265                         publishFullAddressList.add(publishFullAddress);
266
267
268                         PublishFullAddress publishFullAddress2 = new PublishFullAddress(publishFullAddress.getIp(),
269                                         publishPorts[1], publishFullAddress.getPublish_url(),
270                                         publishFullAddress.getVisualRange(), "http");
271                         publishFullAddressList.add(publishFullAddress2);
272
273                     } else {
274                         // single Port
275
276                         if (StringUtils.isNotBlank(serviceInfo.getPublish_port())) {
277                             publishFullAddress.setPort(serviceInfo.getPublish_port());
278                             publishFullAddress.setPublish_protocol("https");
279                         } else {
280                             publishFullAddress.setPort(apigatewayNode.getPort());
281                             publishFullAddress.setPublish_protocol("http");
282                         }
283
284                         if ("TCP".equals(serviceInfo.getProtocol()) || "UDP".equals(serviceInfo.getProtocol())) {
285                             publishFullAddress.setPublish_protocol(serviceInfo.getProtocol());
286                         }
287
288                         publishFullAddressList.add(publishFullAddress);
289
290                     }
291                 }
292
293
294             } else if (this.ROUTE_DOMAIN.equals(routeWays[i])) {
295                 // ----routeWay:domain-----
296
297                 // set service domain
298                 String host = getHost4Domain(serviceInfo);
299                 publishFullAddress.setDomain(host + "." + routeSubdomain);
300
301
302                 if ("TCP".equals(serviceInfo.getProtocol()) || "UDP".equals(serviceInfo.getProtocol())) {
303                     publishFullAddress.setPort(serviceInfo.getPublish_port());
304                     publishFullAddress.setPublish_protocol(serviceInfo.getProtocol());
305                 } else {
306                     publishFullAddress.setPublish_protocol("http");
307                     publishFullAddress.setPort(apigatewayNode.getPort());
308                 }
309
310                 // set service publish url
311                 publishFullAddress.setPublish_url(getPublishUrl4Domain(serviceInfo));
312
313
314                 publishFullAddressList.add(publishFullAddress);
315             }
316
317
318
319         }
320
321         return publishFullAddressList;
322     }
323
324
325     /**
326      * @Title getPublishFullAddress
327      * @Description TODO(get PublishFullAddress List for namespace and visualRange)
328      * @param namespace
329      * @param visualRange
330      * @param serviceInfo
331      * @return List<PublishFullAddress>
332      */
333     private Set<PublishFullAddress> getPublishFullAddress(String namespace, String visualRange,
334                     MicroServiceFullInfo serviceInfo) {
335
336         if (DiscoverUtil.checkVisualRangeIn(visualRange)) {
337             if (!DiscoverUtil.checkVisualRangeIn(serviceInfo.getVisualRange())) {
338                 return null;
339             }
340         } else {
341             if (!DiscoverUtil.checkVisualRangeOut(serviceInfo.getVisualRange())) {
342                 return null;
343             }
344         }
345
346
347         Set<PublishFullAddress> publishFullAddressList = new HashSet<PublishFullAddress>();
348         List<MicroServiceFullInfo> apigatewayList = getApigatewayInfo4Service(namespace, visualRange);
349         if (apigatewayList != null && !apigatewayList.isEmpty()) {
350             for (MicroServiceFullInfo apigatewayInfo : apigatewayList) {
351                 if (isPublish2apigateway(apigatewayInfo, serviceInfo)) {
352                     publishFullAddressList.addAll(convert2PublishFullAddress(apigatewayInfo, serviceInfo));
353                 }
354             }
355         }
356         return publishFullAddressList;
357     }
358
359
360
361     private String getHost4Domain(MicroServiceFullInfo serviceInfo) {
362         String host = "";
363         if (StringUtils.isNotBlank(serviceInfo.getHost())) {
364             host = serviceInfo.getHost();
365         } else {
366             if (StringUtils.isNotBlank(serviceInfo.getNamespace())) {
367                 host = serviceInfo.getServiceName() + DiscoverUtil.SERVICENAME_LINE_NAMESPACE
368                                 + serviceInfo.getNamespace();
369             } else {
370                 host = serviceInfo.getServiceName();
371             }
372         }
373
374         return host;
375     }
376
377     private String getPublishPort(MicroServiceFullInfo apigatewayInfo, MicroServiceFullInfo serviceInfo) {
378
379         NodeInfo node = (NodeInfo) apigatewayInfo.getNodes().toArray()[0];
380         String port = "";
381
382         if ("TCP".equals(serviceInfo.getProtocol()) || "UDP".equals(serviceInfo.getProtocol())) {
383             return serviceInfo.getPublish_port();
384         }
385
386         if (DiscoverUtil.VISUAL_RANGE_IN.equals(apigatewayInfo.getVisualRange())) {
387             port = node.getPort();
388         } else {
389             if (StringUtils.isNotBlank(serviceInfo.getPublish_port())) {
390                 port = serviceInfo.getPublish_port();
391             } else {
392                 port = node.getPort();
393             }
394         }
395
396         return port;
397
398     }
399
400
401
402     private String getPublishUrl4Domain(MicroServiceFullInfo serviceInfo) {
403         String publish_url = "/";
404         if (StringUtils.isNotBlank(serviceInfo.getPath()) && !"/".equals(serviceInfo.getPath())) {
405             publish_url = serviceInfo.getPath();
406         } else {
407             publish_url = serviceInfo.getUrl();
408         }
409         return publish_url;
410     }
411
412     private String getPublishUrl4IP(MicroServiceFullInfo serviceInfo) {
413
414         String publish_url = "/";
415         if (StringUtils.isNotBlank(serviceInfo.getPath()) && !"/".equals(serviceInfo.getPath())) {
416             publish_url = serviceInfo.getPath();
417         } else {
418             String versionUrl = "";
419             String serviceNameUrl = serviceInfo.getServiceName();
420
421             if (StringUtils.isNotBlank(serviceInfo.getVersion())) {
422                 versionUrl = "/" + serviceInfo.getVersion();
423             }
424             switch (serviceInfo.getProtocol()) {
425                 case "REST":
426                     publish_url = "/api/" + serviceNameUrl + versionUrl;
427                     break;
428                 case "UI":
429                     publish_url = "/iui/" + serviceNameUrl;
430                     break;
431                 case "HTTP":
432                     publish_url = "/" + serviceNameUrl + versionUrl;
433                     break;
434                 case "PORTAL":
435                     publish_url = "/" + serviceNameUrl + versionUrl;
436                     break;
437                 case "TCP":
438                     publish_url = serviceInfo.getUrl();
439                     break;
440                 case "UDP":
441                     publish_url = serviceInfo.getUrl();
442                     break;
443             }
444         }
445
446         return publish_url;
447     }
448
449
450     private void checkServiceInputFormat(String serviceName, String version, String visualRange) {
451         if (StringUtils.isBlank(serviceName)) {
452             throw new UnprocessableEntityException("serviceName  can't be empty");
453         }
454
455         if (!RegExpTestUtil.serviceNameRegExpTest(serviceName)) {
456             throw new UnprocessableEntityException(
457                             "get MicroServiceInfo FAIL:ServiceName(" + serviceName + ") format error");
458         }
459
460         if (StringUtils.isNotBlank(version)) {
461             if (!RegExpTestUtil.versionRegExpTest(version)) {
462                 throw new UnprocessableEntityException("version (" + version + ") is not a valid  format");
463             }
464         }
465
466         if (!DiscoverUtil.checkVisualRangeIn(visualRange) && !DiscoverUtil.checkVisualRangeOut(visualRange)) {
467             throw new UnprocessableEntityException("get ApigatewayServiceInfo FAIL:visualRange is wrong,value range:("
468                             + DiscoverUtil.VISUAL_RANGE_LIST + ")");
469         }
470     }
471
472
473     /**
474      * @Title getApigatewayInfo4Service
475      * @Description TODO(get apigatewayServiceInfo List by namespaces[all & service-namespace])
476      * @param namespace
477      * @param visualRange
478      * @return
479      * @return List<MicroServiceFullInfo>
480      */
481     private List<MicroServiceFullInfo> getApigatewayInfo4Service(String namespace, String visualRange) {
482
483         String apigatewayName;
484         if (DiscoverUtil.checkVisualRangeIn(visualRange)) {
485             apigatewayName = DiscoverUtil.APIGATEWAY_SERVINCE;
486         } else {
487             apigatewayName = DiscoverUtil.ROUTER_SERVINCE;
488         }
489
490
491         String apigateway_ns;
492         if (StringUtils.isBlank(namespace)) {
493             apigateway_ns = DiscoverUtil.APIGATEWAY_SERVINCE_DEFAULT;
494         } else {
495             apigateway_ns = namespace;
496         }
497
498         String[] apigateway_ns_array = {DiscoverUtil.APIGATEWAY_SERVINCE_ALL, apigateway_ns};
499         List<MicroServiceFullInfo> apigatewayList4Service = new ArrayList<MicroServiceFullInfo>();
500         for (int i = 0; i < apigateway_ns_array.length; i++) {
501             List<MicroServiceFullInfo> apigatewayList = getApiGateWayFromCache(apigatewayName, apigateway_ns_array[i]);
502             if (apigatewayList != null) {
503                 apigatewayList4Service.addAll(apigatewayList);
504             }
505         }
506
507         return apigatewayList4Service;
508
509     }
510
511
512     private boolean isPublish2apigateway(MicroServiceFullInfo apigatewayInfo, MicroServiceFullInfo serviceInfo) {
513         return isPublishByNetwork_plane_typeMatches(apigatewayInfo.getNetwork_plane_type(),
514                         serviceInfo.getNetwork_plane_type())
515                         && isPublishByRouteLabels(apigatewayInfo.getLabels(), serviceInfo.getLabels());
516     }
517
518     /**
519      * Determine whether the service needs to publish to apigateway TODO: according to the
520      * service_network_plane filter conditions
521      * 
522      * @param String
523      * @return
524      */
525
526     private boolean isPublishByNetwork_plane_typeMatches(String apigateway_network_plane,
527                     String service_network_plane) {
528
529         if (StringUtils.isBlank(apigateway_network_plane))
530             return true;
531         String[] routeNetwork_plane_typeArray = StringUtils.split(apigateway_network_plane, "|");
532         String[] serviceVisualRangeArray = StringUtils.split(service_network_plane, "|");
533         if (DiscoverUtil.contain(serviceVisualRangeArray, routeNetwork_plane_typeArray)) {
534             return true;
535         }
536
537         return false;
538     }
539
540
541     /**
542      * Determine whether the service needs to publish to apigateway TODO: according to the labels
543      * filter conditions
544      * 
545      * @param labelMap
546      * @return
547      */
548     private boolean isPublishByRouteLabels(List<String> apigatewayLabels, List<String> serviceLabels) {
549         if (apigatewayLabels == null || apigatewayLabels.isEmpty()) {
550             return true;
551         }
552
553         Map<String, String> apigateway_labelMap = new HashMap<String, String>();
554         Map<String, String> service_labelMap = new HashMap<String, String>();
555         for (String label : apigatewayLabels) {
556             String[] labelArray = label.split(":");
557             apigateway_labelMap.put(labelArray[0], labelArray[1]);
558         }
559
560         for (String label : serviceLabels) {
561             String[] labelArray = label.split(":");
562             service_labelMap.put(labelArray[0], labelArray[1]);
563         }
564
565         for (Map.Entry<String, String> entry : apigateway_labelMap.entrySet()) {
566             String key = entry.getKey();
567             String value = entry.getValue();
568
569             // Multiple values match
570             String[] routeLalelsArray = StringUtils.split(value, "|");
571             if (StringUtils.isBlank(service_labelMap.get(key))) {
572                 continue;
573             }
574
575             String[] serviceLabelsArray = StringUtils.split(service_labelMap.get(key), "|");
576
577             if (DiscoverUtil.contain(routeLalelsArray, serviceLabelsArray)) {
578                 return true;
579             }
580
581         }
582
583         return false;
584     }
585
586
587
588     private List<MicroServiceFullInfo> getApiGateWayFromCache(String apigatewayName, String apigatewayNamespace) {
589         String apigatewayConsulName = apigatewayName + DiscoverUtil.SERVICENAME_LINE_NAMESPACE + apigatewayNamespace;
590         if (publishApigateWayList.get(apigatewayConsulName) == null) {
591
592             try {
593                 List<MicroServiceFullInfo> apigatewayList = ConsulServiceWrapper.getInstance()
594                                 .getMicroServiceForNodes(apigatewayName, "v1", true, "", apigatewayNamespace);
595                 if (!apigatewayList.isEmpty()) {
596                     consulClientApp.startHealthNodeListen(apigatewayConsulName);
597                     return apigatewayList;
598                 }
599             } catch (ExtendedNotFoundException e) {
600                 LOGGER.warn("ApiGateWay Info not found:[serviceName]" + apigatewayName + ",[namespace]"
601                                 + apigatewayNamespace);
602             }
603
604         } else {
605             return publishApigateWayList.get(apigatewayConsulName);
606         }
607
608         return null;
609     }
610
611
612     public PublishAddress getPublishaddress(String serviceName, String version, String namespace, int wait) {
613         if ("null".equals(version)) {
614             version = "";
615         }
616
617         // 1.Check input parameter format efficacy
618         checkServiceInputFormat(serviceName, version, DiscoverUtil.VISUAL_RANGE_IN);
619
620
621         MicroServiceFullInfo microServiceFullInfo =
622                         ConsulServiceWrapper.getInstance().getMicroServiceInstance(serviceName, version, namespace);
623
624         if (!DiscoverUtil.checkVisualRangeIn(microServiceFullInfo.getVisualRange())) {
625             throw new ExtendedNotFoundException("This service is not published internally");
626         }
627
628         if (!DiscoverUtil.checkExist(DiscoverUtil.PUBLISH_PROTOCOL, microServiceFullInfo.getProtocol())) {
629             throw new ExtendedNotFoundException("This service's Protocol (" + microServiceFullInfo.getProtocol()
630                             + ") is not published to apigateway");
631         }
632
633         List<PublishAddress> publishaddress_all = new ArrayList<PublishAddress>();
634         List<PublishAddress> publishaddress_ns = new ArrayList<PublishAddress>();
635
636         List<MicroServiceFullInfo> apigatewayList_in_all =
637                         getApiGateWayFromCache(DiscoverUtil.APIGATEWAY_SERVINCE, "all");
638         if (apigatewayList_in_all != null && !apigatewayList_in_all.isEmpty()) {
639             for (MicroServiceFullInfo apigateway : apigatewayList_in_all) {
640                 if (isPublish2apigateway(apigateway, microServiceFullInfo)) {
641                     publishaddress_all.add(convert2PublishAddress(apigateway, microServiceFullInfo));
642                 }
643             }
644         }
645
646
647
648         String apigateway_ns;
649         if (StringUtils.isBlank(namespace)) {
650             apigateway_ns = DiscoverUtil.APIGATEWAY_SERVINCE_DEFAULT;
651         } else {
652             apigateway_ns = namespace;
653         }
654
655         List<MicroServiceFullInfo> apigatewayList_in_ns =
656                         getApiGateWayFromCache(DiscoverUtil.APIGATEWAY_SERVINCE, apigateway_ns);
657         if (apigatewayList_in_ns != null && !apigatewayList_in_ns.isEmpty()) {
658             for (MicroServiceFullInfo apigateway : apigatewayList_in_ns) {
659                 if (isPublish2apigateway(apigateway, microServiceFullInfo)) {
660                     publishaddress_ns.add(convert2PublishAddress(apigateway, microServiceFullInfo));
661                 }
662             }
663         }
664
665
666
667         // 即时返回
668         if (wait < 5) {
669             if (publishaddress_ns.size() > 0) {
670                 return publishaddress_ns.get(0);
671             } else if (publishaddress_all.size() > 0) {
672                 return publishaddress_all.get(0);
673             }
674
675
676             throw new ExtendedNotFoundException("This service's publish address is not found");
677         }
678
679         if (wait > 300) {
680             wait = 300;
681         }
682
683
684         // get service publish url
685         String publish_url = "/";
686         if (StringUtils.isNotBlank(microServiceFullInfo.getPath())) {
687             publish_url = microServiceFullInfo.getPath();
688         } else {
689             String versionUrl = "";
690             String serviceNameUrl = microServiceFullInfo.getServiceName();
691
692
693             if (StringUtils.isNotBlank(microServiceFullInfo.getVersion())) {
694                 versionUrl = "/" + microServiceFullInfo.getVersion();
695             }
696             switch (microServiceFullInfo.getProtocol()) {
697                 case "REST":
698                     publish_url = "/api/" + serviceNameUrl + versionUrl;
699                     break;
700                 case "UI":
701                     publish_url = "/iui/" + serviceNameUrl;
702                     break;
703                 case "HTTP":
704                     publish_url = "/" + serviceNameUrl + versionUrl;
705                     break;
706                 case "TCP":
707                     publish_url = microServiceFullInfo.getUrl();
708                     break;
709                 case "UDP":
710                     publish_url = microServiceFullInfo.getUrl();
711                     break;
712             }
713         }
714
715         // 延迟监听返回
716         Future<PublishAddress> f = exec.submit(new TimeTask(namespace, publish_url));
717         try {
718             return f.get(wait, TimeUnit.SECONDS);
719         } catch (InterruptedException e) {
720             // TODO Auto-generated catch block
721             LOGGER.error(e.getMessage());
722         } catch (ExecutionException e) {
723             // TODO Auto-generated catch block
724             LOGGER.error(e.getMessage());
725         } catch (TimeoutException e) {
726             // 定义超时后的状态修改
727             // LOGGER.error(e.getMessage());
728             LOGGER.error(e.getMessage());
729         } finally {
730
731             f.cancel(true);
732         }
733
734         if (publishaddress_ns.size() > 0) {
735             return publishaddress_ns.get(0);
736         } else if (publishaddress_all.size() > 0) {
737             return publishaddress_all.get(0);
738         }
739
740         throw new ExtendedNotFoundException("This service's apigatewayInfo is not found");
741
742     }
743
744
745     private PublishAddress convert2PublishAddress(MicroServiceFullInfo apigatewayInfo,
746                     MicroServiceFullInfo serviceInfo) {
747         PublishAddress publishAddress = new PublishAddress();
748
749         NodeInfo node = (NodeInfo) apigatewayInfo.getNodes().toArray()[0];
750         publishAddress.setIp(node.getIp());
751
752         if (DiscoverUtil.VISUAL_RANGE_IN.equals(apigatewayInfo.getVisualRange())) {
753             publishAddress.setPort(node.getPort());
754         } else {
755             if (StringUtils.isNotBlank(serviceInfo.getPublish_port())) {
756                 publishAddress.setPort(serviceInfo.getPublish_port());
757             } else {
758                 publishAddress.setPort(node.getPort());
759             }
760         }
761
762
763         // get service publish url
764         String publish_url = "/";
765         if (StringUtils.isNotBlank(serviceInfo.getPath())) {
766             publish_url = serviceInfo.getPath();
767         } else {
768             String versionUrl = "";
769             String serviceNameUrl = serviceInfo.getServiceName();
770
771
772             if (StringUtils.isNotBlank(serviceInfo.getVersion())) {
773                 versionUrl = "/" + serviceInfo.getVersion();
774             }
775             switch (serviceInfo.getProtocol()) {
776                 case "REST":
777                     publish_url = "/api/" + serviceNameUrl + versionUrl;
778                     break;
779                 case "UI":
780                     publish_url = "/iui/" + serviceNameUrl;
781                     break;
782                 case "HTTP":
783                     publish_url = "/" + serviceNameUrl + versionUrl;
784                     break;
785                 case "TCP":
786                     publish_url = serviceInfo.getUrl();
787                     break;
788                 case "UDP":
789                     publish_url = serviceInfo.getUrl();
790                     break;
791             }
792         }
793
794         publishAddress.setPublish_url(publish_url);
795
796
797         return publishAddress;
798     }
799
800
801
802     public class TimeTask implements Callable<PublishAddress> {
803
804         private String namespace;
805         private String publish_url;
806
807         @Override
808         public PublishAddress call() throws Exception {
809
810
811             while (true) {
812                 List<PublishAddress> oldAddress = getApigatewayListFromCache(namespace, publish_url);
813
814
815                 Thread.sleep(2000);
816                 // LOGGER.info("oldAddress:"+oldAddress);
817                 List<PublishAddress> newAddress = getApigatewayListFromCache(namespace, publish_url);
818                 if (!oldAddress.equals(newAddress)) {
819                     // LOGGER.info("CHANGED:"+oldAddress+"-"+apigatewayAddress);
820
821                     return newAddress.get(0);
822                 }
823             }
824
825         }
826
827         TimeTask(String namespace, String publish_url) {
828             this.namespace = namespace;
829             this.publish_url = publish_url;
830         }
831
832     }
833
834     private List<PublishAddress> getApigatewayListFromCache(String namespace, String publish_url) {
835         List<PublishAddress> fullAddress = new ArrayList<PublishAddress>();
836         String apigatewayName4ns =
837                         DiscoverUtil.APIGATEWAY_SERVINCE + DiscoverUtil.SERVICENAME_LINE_NAMESPACE + namespace;
838         if (publishApigateWayList.get(apigatewayName4ns) != null) {
839             List<MicroServiceFullInfo> publishaddress4ns = publishApigateWayList.get(apigatewayName4ns);
840             for (MicroServiceFullInfo address : publishaddress4ns) {
841                 NodeInfo node = (NodeInfo) address.getNodes().toArray()[0];
842                 fullAddress.add(new PublishAddress(node.getIp(), node.getPort(), publish_url));
843             }
844
845         } else {
846             if (publishApigateWayList.get(DiscoverUtil.APIGATEWAY_SERVINCE_ALL) != null) {
847                 List<MicroServiceFullInfo> publishaddress4all =
848                                 publishApigateWayList.get(DiscoverUtil.APIGATEWAY_SERVINCE_ALL);
849                 for (MicroServiceFullInfo address : publishaddress4all) {
850                     NodeInfo node = (NodeInfo) address.getNodes().toArray()[0];
851                     fullAddress.add(new PublishAddress(node.getIp(), node.getPort(), publish_url));
852                 }
853             }
854         }
855
856         return fullAddress;
857     }
858
859 }