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