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  
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  
94  
95  
96  
97  
98  
99  
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
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 }