1 package io.getunleash.metric;
2
3 import com.google.gson.*;
4 import io.getunleash.UnleashException;
5 import io.getunleash.event.EventDispatcher;
6 import io.getunleash.util.AtomicLongSerializer;
7 import io.getunleash.util.DateTimeSerializer;
8 import io.getunleash.util.UnleashConfig;
9 import io.getunleash.util.UnleashURLs;
10 import java.io.IOException;
11 import java.io.OutputStreamWriter;
12 import java.net.HttpURLConnection;
13 import java.net.URL;
14 import java.time.LocalDateTime;
15 import java.util.concurrent.atomic.AtomicLong;
16
17 public class DefaultHttpMetricsSender implements MetricSender {
18     private static final int CONNECT_TIMEOUT = 1000;
19
20     private final Gson gson;
21     private final EventDispatcher eventDispatcher;
22     private UnleashConfig unleashConfig;
23     private final URL clientRegistrationURL;
24     private final URL clientMetricsURL;
25
26     public DefaultHttpMetricsSender(UnleashConfig unleashConfig) {
27         this.unleashConfig = unleashConfig;
28         this.eventDispatcher = new EventDispatcher(unleashConfig);
29         UnleashURLs urls = unleashConfig.getUnleashURLs();
30         this.clientMetricsURL = urls.getClientMetricsURL();
31         this.clientRegistrationURL = urls.getClientRegisterURL();
32
33         this.gson =
34                 new GsonBuilder()
35                         .registerTypeAdapter(LocalDateTime.classnew DateTimeSerializer())
36                         .registerTypeAdapter(AtomicLong.classnew AtomicLongSerializer())
37                         .create();
38     }
39
40     public int registerClient(ClientRegistration registration) {
41         if (!unleashConfig.isDisableMetrics()) {
42             try {
43                 int statusCode = post(clientRegistrationURL, registration);
44                 eventDispatcher.dispatch(registration);
45                 return statusCode;
46             } catch (UnleashException ex) {
47                 eventDispatcher.dispatch(ex);
48                 return -1;
49             }
50         }
51         return -1;
52     }
53
54     public int sendMetrics(ClientMetrics metrics) {
55         if (!unleashConfig.isDisableMetrics()) {
56             try {
57                 int statusCode = post(clientMetricsURL, metrics);
58                 eventDispatcher.dispatch(metrics);
59                 return statusCode;
60             } catch (UnleashException ex) {
61                 eventDispatcher.dispatch(ex);
62                 return -1;
63             }
64         }
65         return -1;
66     }
67
68     private int post(URL url, Object o) throws UnleashException {
69
70         HttpURLConnection connection = null;
71         try {
72             if (this.unleashConfig.getProxy() != null) {
73                 connection = (HttpURLConnection) url.openConnection(this.unleashConfig.getProxy());
74             } else {
75                 connection = (HttpURLConnection) url.openConnection();
76             }
77             connection.setConnectTimeout(
78                     (int) unleashConfig.getSendMetricsConnectTimeout().toMillis());
79             connection.setReadTimeout((int) unleashConfig.getSendMetricsReadTimeout().toMillis());
80             connection.setRequestMethod("POST");
81             connection.setRequestProperty("Accept""application/json");
82             connection.setRequestProperty("Content-Type""application/json");
83             UnleashConfig.setRequestProperties(connection, this.unleashConfig);
84             connection.setUseCaches(false);
85             connection.setDoInput(true);
86             connection.setDoOutput(true);
87
88             OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
89             gson.toJson(o, wr);
90             wr.flush();
91             wr.close();
92
93             connection.connect();
94
95             // TODO should probably check response code to detect errors?
96             return connection.getResponseCode();
97         } catch (IOException e) {
98             throw new UnleashException("Could not post to Unleash API", e);
99         } catch (IllegalStateException e) {
100             throw new UnleashException(e.getMessage(), e);
101         } finally {
102             if (connection != null) {
103                 connection.disconnect();
104             }
105         }
106     }
107 }
108