import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_COMPRESSION;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_URL;
+import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_METRICS_URL;
@ServerSide
public class TelemetryClient implements Startable {
private final OkHttpClient okHttpClient;
private final Configuration config;
private String serverUrl;
+ private String metricsServerUrl;
private boolean compression;
public TelemetryClient(OkHttpClient okHttpClient, Configuration config) {
}
void upload(String json) throws IOException {
- Request request = buildHttpRequest(json);
+ Request request = buildHttpRequest(serverUrl, json);
+ execute(okHttpClient.newCall(request));
+ }
+
+ void uploadMetric(String json) throws IOException {
+ Request request = buildHttpRequest(metricsServerUrl, json);
execute(okHttpClient.newCall(request));
}
request.url(serverUrl);
RequestBody body = RequestBody.create(JSON, json);
request.delete(body);
-
try {
execute(okHttpClient.newCall(request.build()));
} catch (IOException e) {
}
}
- private Request buildHttpRequest(String json) {
+ private Request buildHttpRequest(String serverUrl, String json) {
Request.Builder request = new Request.Builder();
request.addHeader("Content-Encoding", "gzip");
request.addHeader("Content-Type", "application/json");
public void start() {
this.serverUrl = config.get(SONAR_TELEMETRY_URL.getKey())
.orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", SONAR_TELEMETRY_URL)));
+ this.metricsServerUrl = config.get(SONAR_TELEMETRY_METRICS_URL.getKey())
+ .orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", SONAR_TELEMETRY_METRICS_URL)));
this.compression = config.getBoolean(SONAR_TELEMETRY_COMPRESSION.getKey()).orElse(true);
}
TelemetryMetricsLoader.Context context = telemetryMetricsLoader.loadData();
for (BaseMessage message : context.getMessages()) {
String jsonString = MessageSerializer.serialize(message);
- telemetryClient.upload(jsonString);
+ telemetryClient.uploadMetric(jsonString);
}
try (DbSession dbSession = dbClient.openSession(false)) {
import org.sonar.api.config.internal.MapSettings;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_METRICS_URL;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_URL;
class TelemetryClientCompressionTest {
telemetryServer.enqueue(new MockResponse().setResponseCode(200));
MapSettings settings = new MapSettings();
settings.setProperty(SONAR_TELEMETRY_URL.getKey(), telemetryServer.url("/").toString());
+ settings.setProperty(SONAR_TELEMETRY_METRICS_URL.getKey(), telemetryServer.url("/").toString());
TelemetryClient underTest = new TelemetryClient(okHttpClient, settings.asConfig());
underTest.start();
underTest.upload("payload compressed with gzip");
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okio.Buffer;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.sonar.api.config.internal.MapSettings;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_COMPRESSION;
+import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_METRICS_URL;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_URL;
class TelemetryClientTest {
private static final String JSON = "{\"key\":\"value\"}";
private static final String TELEMETRY_URL = "https://telemetry.com/url";
+ private static final String METRICS_TELEMETRY_URL = "https://telemetry.com/url/metrics";
private final OkHttpClient okHttpClient = mock(OkHttpClient.class, RETURNS_DEEP_STUBS);
private final MapSettings settings = new MapSettings();
private final TelemetryClient underTest = new TelemetryClient(okHttpClient, settings.asConfig());
+ @BeforeEach
+ void setProperties() {
+ settings.setProperty(SONAR_TELEMETRY_URL.getKey(), TELEMETRY_URL);
+ settings.setProperty(SONAR_TELEMETRY_METRICS_URL.getKey(), METRICS_TELEMETRY_URL);
+ }
+
@Test
void upload() throws IOException {
ArgumentCaptor<Request> requestCaptor = ArgumentCaptor.forClass(Request.class);
- settings.setProperty(SONAR_TELEMETRY_URL.getKey(), TELEMETRY_URL);
settings.setProperty(SONAR_TELEMETRY_COMPRESSION.getKey(), false);
underTest.start();
assertThat(request.url()).hasToString(TELEMETRY_URL);
}
+ @Test
+ void uploadMetric() throws IOException {
+ ArgumentCaptor<Request> requestCaptor = ArgumentCaptor.forClass(Request.class);
+ settings.setProperty(SONAR_TELEMETRY_COMPRESSION.getKey(), false);
+ underTest.start();
+
+ underTest.uploadMetric(JSON);
+
+ verify(okHttpClient).newCall(requestCaptor.capture());
+ Request request = requestCaptor.getValue();
+ assertThat(request.method()).isEqualTo("POST");
+ assertThat(request.body().contentType()).isEqualTo(MediaType.parse("application/json; charset=utf-8"));
+ Buffer body = new Buffer();
+ request.body().writeTo(body);
+ assertThat(body.readUtf8()).isEqualTo(JSON);
+ assertThat(request.url()).hasToString(METRICS_TELEMETRY_URL);
+ }
+
@Test
void opt_out() throws IOException {
ArgumentCaptor<Request> requestCaptor = ArgumentCaptor.forClass(Request.class);
- settings.setProperty(SONAR_TELEMETRY_URL.getKey(), TELEMETRY_URL);
underTest.start();
underTest.optOut(JSON);