View Javadoc
1   package cn.home1.oss.environment.admin;
2   
3   import static cn.home1.oss.lib.common.BasicAuthUtils.basicAuthHeader;
4   import static org.springframework.http.HttpMethod.GET;
5   
6   import de.codecentric.boot.admin.event.ClientApplicationStatusChangedEvent;
7   import de.codecentric.boot.admin.model.Application;
8   import de.codecentric.boot.admin.model.StatusInfo;
9   import de.codecentric.boot.admin.registry.StatusUpdater;
10  import de.codecentric.boot.admin.registry.store.ApplicationStore;
11  import de.codecentric.boot.admin.web.client.ApplicationOperations;
12  
13  import lombok.extern.slf4j.Slf4j;
14  
15  import org.springframework.beans.factory.annotation.Autowired;
16  import org.springframework.context.ApplicationEventPublisher;
17  import org.springframework.http.HttpEntity;
18  import org.springframework.http.HttpHeaders;
19  import org.springframework.http.ResponseEntity;
20  import org.springframework.web.client.RestTemplate;
21  
22  import java.io.Serializable;
23  import java.util.Map;
24  
25  /**
26   * Created by Yuliang on 16/11/25.
27   */
28  @Slf4j
29  public class PatchedStatusUpdater extends StatusUpdater {
30  
31    private final ApplicationOperations applicationOps;
32  
33    private final RestTemplate restTemplate;
34  
35    private final ApplicationStore store;
36  
37    private boolean active = false;
38  
39    private ApplicationEventPublisher publisher;
40  
41    @Autowired
42    private BasicAuthFilter basicAuthFilter;
43    @Autowired
44    private ClientKeyStore clientKeyStore;
45  
46    public PatchedStatusUpdater( //
47        final ApplicationStore store, //
48        final ApplicationOperations applicationOps, //
49        final RestTemplate restTemplate
50    ) {
51      super(store, applicationOps);
52      this.applicationOps = applicationOps;
53      this.store = store;
54      this.restTemplate = restTemplate;
55    }
56  
57    @Override
58    public void updateStatus(final Application application) {
59  
60      if (this.active) {
61        final StatusInfo oldStatus = application.getStatusInfo();
62        final StatusInfo newStatus = queryStatus(application);
63  
64        final Application newState = Application.create(application.getName()).withStatusInfo(newStatus).build();
65        this.store.save(newState);
66  
67        if (!newStatus.equals(oldStatus)) {
68          this.publisher.publishEvent(new ClientApplicationStatusChangedEvent(newState, oldStatus, newStatus));
69        }
70      } else {
71        log.info("Application not started yet. Application update process not executed");
72      }
73    }
74  
75    public void setActive(final boolean active) {
76      log.debug("Setting active property to: {}", active);
77      this.active = active;
78    }
79  
80    public boolean isActive() {
81      return this.active;
82    }
83  
84    @Override
85    public void setApplicationEventPublisher(final ApplicationEventPublisher publisher) {
86      this.publisher = publisher;
87    }
88  
89    private static final Class<Map<String, Serializable>> RESPONSE_TYPE_MAP = (Class<Map<String, Serializable>>) (Class<?>) Map.class;
90  
91    @Override
92    protected StatusInfo queryStatus(final Application application) {
93  //    StatusInfo resultStatus = StatusInfo.ofUnknown();
94  //
95  //    log.trace("Updating status for {}", application);
96  //    try {
97  //      final String url = application.getHealthUrl();
98  //      ClientKey clientKey = this.clientKeyStore.find(application.getId());
99  //
100 //      if (clientKey == null) {
101 //        final String infoUrl = getInfoUrl(url);
102 //        clientKey = this.basicAuthFilter.requestForClientKey(application.getId(), infoUrl);
103 //        this.clientKeyStore.save(clientKey);
104 //      }
105 //
106 //      final HttpEntity<String> httpEntity = new HttpEntity<>(createBasicAuthHeaders(clientKey));
107 //      final ResponseEntity<Map<String, Serializable>> response = this.operations.exchange(url, GET, httpEntity, RESPONSE_TYPE_MAP);
108 //      log.debug("/health for {} responded with {}", application, response);
109 //
110 //      if (response.hasBody() && response.getBody().get("status") instanceof String) {
111 //        resultStatus = StatusInfo.valueOf((String) response.getBody().get("status"));
112 //      } else if (response.getStatusCode().is2xxSuccessful()) {
113 //        resultStatus = StatusInfo.ofUp();
114 //      } else {
115 //        resultStatus = StatusInfo.ofDown();
116 //      }
117 //    } catch (final Exception ex) {
118 //      if ("OFFLINE".equals(application.getStatusInfo().getStatus())) {
119 //        log.debug("Couldn't retrieve status for {}", application, ex);
120 //      } else {
121 //        log.warn("Couldn't retrieve status for {}", application, ex);
122 //      }
123 //      resultStatus = StatusInfo.ofOffline();
124 //    }
125 //
126 //    return resultStatus;
127 
128     try {
129       final String url = application.getHealthUrl();
130       ClientKey clientKey = this.clientKeyStore.find(application.getId());
131       if (clientKey == null) {
132         final String infoUrl = getInfoUrl(url);
133         clientKey = this.basicAuthFilter.requestForClientKey(application.getId(), infoUrl);
134         this.clientKeyStore.save(clientKey);
135       }
136       final HttpEntity<String> httpEntity = new HttpEntity<>(createBasicAuthHeaders(clientKey));
137       final ResponseEntity<Map<String, Serializable>> response = this.restTemplate.exchange( //
138           url, GET, httpEntity, RESPONSE_TYPE_MAP);
139 
140       return convertStatusInfo(response);
141     } catch (final Exception ex) {
142       if ("OFFLINE".equals(application.getStatusInfo().getStatus())) {
143         log.debug("Couldn't retrieve status for {}", application, ex);
144       } else {
145         log.info("Couldn't retrieve status for {}", application, ex);
146       }
147       return convertStatusInfo(ex);
148     }
149   }
150 
151   private String getInfoUrl(final String url) {
152     return url.substring(0, url.lastIndexOf('/') + 1) + "info";
153   }
154 
155   HttpHeaders createBasicAuthHeaders(final ClientKey clientKey) {
156     HttpHeaders httpHeaders = new HttpHeaders();
157     String authHeader = basicAuthHeader(clientKey.getUserName(), clientKey.getPassword());
158     httpHeaders.set("Authorization", authHeader);
159     return httpHeaders;
160   }
161 }