##### Coverage Report - com.ctrip.apollo.portal.service.ServiceLocator

Classes in this File | Line Coverage | Branch Coverage | Complexity
ServiceLocator |
56% | 23/41
10% | 2/20
| 4.25;4.25

1 |  |
     package com.ctrip.apollo.portal.service;
2 |  |
3 |  |
     import java.net.URI;
4 |  |
     import java.util.ArrayList;
5 |  |
     import java.util.List;
6 |  |
     import java.util.Map;
7 |  |
     import java.util.concurrent.ConcurrentHashMap;
8 |  |
     import java.util.concurrent.atomic.AtomicInteger;
9 |  |
10 |  |
     import javax.annotation.PostConstruct;
11 |  |
12 |  |
     import org.slf4j.Logger;
13 |  |
     import org.slf4j.LoggerFactory;
14 |  |
     import org.springframework.beans.factory.annotation.Autowired;
15 |  |
     import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
16 |  |
     import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
17 |  |
     import org.springframework.http.client.SimpleClientHttpRequestFactory;
18 |  |
     import org.springframework.stereotype.Service;
19 |  |
     import org.springframework.web.client.RestTemplate;
20 |  |
21 |  |
     import com.ctrip.apollo.core.MetaDomainConsts;
22 |  |
     import com.ctrip.apollo.core.dto.ServiceDTO;
23 |  |
     import com.ctrip.apollo.core.enums.Env;
24 |  |
     import com.ctrip.apollo.core.exception.ServiceException;
25 |  |
26 |  |
     /**
27 |  |
      * @author liuym
28 |  |
      */
29 |  |
     @Service
30 | 1 |
     public class ServiceLocator {
31 |  |
32 | 1 |
       private static final Logger logger = LoggerFactory.getLogger(ServiceLocator.class);
33 |  |
34 |  |
       private static final int DEFAULT_TIMEOUT_MS = 1000;
35 |  |
36 |  |
       private RestTemplate restTemplate;
37 |  |
38 |  |
       @Autowired
39 |  |
       private HttpMessageConverters httpMessageConverters;
40 |  |
41 | 1 |
       private Map<Env, List<ServiceDTO>> serviceCaches = new ConcurrentHashMap<Env, List<ServiceDTO>>();
42 |  |
43 | 1 |
       private final AtomicInteger adminCallCounts = new AtomicInteger(0);
44 |  |
45 | 1 |
       private final AtomicInteger configCallCounts = new AtomicInteger(0);
46 |  |
47 |  |
       public ServiceDTO getAdminService(Env env) throws ServiceException {
48 | 2 |
         List<ServiceDTO> services = getServices(env, "admin");
49 | 2 |
         if (services == null || services.size() == 0) {
50 | 2 |
           throw new ServiceException("No available admin service");
51 |  |
         }
52 | 0 |
         return services.get(Math.abs(adminCallCounts.getAndIncrement()) % services.size());
53 |  |
       }
54 |  |
55 |  |
       public ServiceDTO getConfigService(Env env) throws ServiceException {
56 | 0 |
         List<ServiceDTO> services = getServices(env, "config");
57 | 0 |
         if (services == null || services.size() == 0) {
58 | 0 |
           throw new ServiceException("No available config service");
59 |  |
         }
60 | 0 |
         return services.get(Math.abs(configCallCounts.getAndIncrement()) % services.size());
61 |  |
       }
62 |  |
63 |  |
       private List<ServiceDTO> getServices(Env env, String serviceUrl) {
64 | 2 |
         String domainName = MetaDomainConsts.getDomain(env);
65 | 2 |
         String url = domainName + "/services/" + serviceUrl;
66 | 2 |
         List<ServiceDTO> serviceDtos = null;
67 |  |
         try {
68 | 2 |
           ServiceDTO[] services = restTemplate.getForObject(new URI(url), ServiceDTO[].class);
69 | 0 |
           if (services != null && services.length > 0) {
70 | 0 |
             if (!serviceCaches.containsKey(env)) {
71 | 0 |
               serviceDtos = new ArrayList<ServiceDTO>();
72 | 0 |
               serviceCaches.put(env, serviceDtos);
73 |  |
             } else {
74 | 0 |
               serviceDtos = serviceCaches.get(env);
75 | 0 |
               serviceDtos.clear();
76 |  |
             }
77 | 0 |
             for (ServiceDTO service : services) {
78 | 0 |
               serviceDtos.add(service);
79 |  |
             }
80 |  |
           }
81 | 2 |
         } catch (Exception ex) {
82 | 2 |
           logger.warn(ex.getMessage());
83 | 0 |
         }
84 | 2 |
         return serviceDtos;
85 |  |
       }
86 |  |
87 |  |
       @PostConstruct
88 |  |
       private void postConstruct() {
89 | 1 |
         restTemplate = new RestTemplate(httpMessageConverters.getConverters());
90 | 1 |
         if (restTemplate.getRequestFactory() instanceof SimpleClientHttpRequestFactory) {
91 | 1 |
           SimpleClientHttpRequestFactory rf =
92 | 1 |
               (SimpleClientHttpRequestFactory) restTemplate.getRequestFactory();
93 | 1 |
           rf.setReadTimeout(DEFAULT_TIMEOUT_MS);
94 | 1 |
           rf.setConnectTimeout(DEFAULT_TIMEOUT_MS);
95 | 1 |
         } else if (restTemplate.getRequestFactory() instanceof HttpComponentsClientHttpRequestFactory) {
96 | 0 |
           HttpComponentsClientHttpRequestFactory rf =
97 | 0 |
               (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory();
98 | 0 |
           rf.setReadTimeout(DEFAULT_TIMEOUT_MS);
99 | 0 |
           rf.setConnectTimeout(DEFAULT_TIMEOUT_MS);
100 |  |
         }
101 | 1 |
       }
102 |  |
     }