]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9721 Send Server UUID to Telemetry server
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Mon, 21 Aug 2017 09:07:55 +0000 (11:07 +0200)
committerTeryk Bellahsene <teryk@users.noreply.github.com>
Wed, 30 Aug 2017 14:24:53 +0000 (16:24 +0200)
15 files changed:
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryClient.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryFrequency.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryModule.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryProperties.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryUrl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/telemetry/package-info.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/telemetry/FakeServer.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryModuleTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryPropertiesTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryUrlTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/Category5Suite.java
tests/src/test/java/org/sonarqube/tests/telemetry/TelemetryTest.java [new file with mode: 0644]

index 2dd4f1f7378c9d3314c0ae90093beeb6ace9ab2a..57f67a4874a7a0ecb2485cc325b1738011352684 100644 (file)
@@ -185,6 +185,7 @@ import org.sonar.server.source.ws.LinesAction;
 import org.sonar.server.source.ws.RawAction;
 import org.sonar.server.source.ws.ScmAction;
 import org.sonar.server.source.ws.SourcesWs;
+import org.sonar.server.telemetry.TelemetryModule;
 import org.sonar.server.test.index.TestIndex;
 import org.sonar.server.test.index.TestIndexDefinition;
 import org.sonar.server.test.index.TestIndexer;
@@ -529,6 +530,10 @@ public class PlatformLevel4 extends PlatformLevel {
 
       RecoveryIndexer.class,
       ProjectIndexersImpl.class);
+    addIfStartupLeader(
+      // Telemetry
+      TelemetryModule.class);
+
     addAll(level4AddedComponents);
   }
 
diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryClient.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryClient.java
new file mode 100644 (file)
index 0000000..d318eef
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import com.google.common.base.Throwables;
+import java.io.IOException;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.server.ServerSide;
+
+@ServerSide
+public class TelemetryClient {
+  private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
+
+  private final OkHttpClient okHttpClient;
+  private final TelemetryUrl serverUrl;
+
+  public TelemetryClient(OkHttpClient okHttpClient, Configuration config) {
+    this.okHttpClient = okHttpClient;
+    this.serverUrl = new TelemetryUrl(config);
+  }
+
+  void send(String json) {
+    try {
+      Request request = buildHttpRequest(json);
+      okHttpClient.newCall(request).execute();
+    } catch (IOException e) {
+      Throwables.propagate(e);
+    }
+  }
+
+  private Request buildHttpRequest(String json) {
+    Request.Builder request = new Request.Builder();
+    request.url(serverUrl.get());
+    RequestBody body = RequestBody.create(JSON, json);
+    request.post(body);
+    return request.build();
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java
new file mode 100644 (file)
index 0000000..7ec293d
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.telemetry;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.io.StringWriter;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.picocontainer.Startable;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.platform.Server;
+import org.sonar.api.server.ServerSide;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.api.utils.text.JsonWriter;
+
+@ServerSide
+public class TelemetryDaemon implements Startable {
+  private static final String THREAD_NAME_PREFIX = "sq-telemetry-service-";
+  private static final Logger LOG = Loggers.get(TelemetryDaemon.class);
+
+  private final TelemetryClient telemetryClient;
+  private final Server server;
+  private final TelemetryFrequency frequencyInSeconds;
+
+  private ScheduledExecutorService executorService;
+
+  public TelemetryDaemon(TelemetryClient telemetryClient, Server server, Configuration config) {
+    this.telemetryClient = telemetryClient;
+    this.server = server;
+    this.frequencyInSeconds = new TelemetryFrequency(config);
+  }
+
+  @Override
+  public void start() {
+    executorService = Executors.newSingleThreadScheduledExecutor(
+      new ThreadFactoryBuilder()
+        .setNameFormat(THREAD_NAME_PREFIX + "%d")
+        .setPriority(Thread.MIN_PRIORITY)
+        .build());
+    executorService.scheduleWithFixedDelay(() -> {
+      try {
+        StringWriter json = new StringWriter();
+        try (JsonWriter writer = JsonWriter.of(json)) {
+          writer.beginObject();
+          writer.prop("id", server.getId());
+          writer.endObject();
+        }
+        telemetryClient.send(json.toString());
+      } catch (Exception e) {
+        // fail silently
+      }
+    // do not check at start up to exclude test instance which are not up for a long time
+    }, frequencyInSeconds.get(), frequencyInSeconds.get(), TimeUnit.SECONDS);
+  }
+
+  @Override
+  public void stop() {
+    try {
+      executorService.shutdown();
+      executorService.awaitTermination(5, TimeUnit.SECONDS);
+    } catch (InterruptedException e) {
+      Thread.currentThread().interrupt();
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryFrequency.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryFrequency.java
new file mode 100644 (file)
index 0000000..d2d11fe
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import org.sonar.api.config.Configuration;
+
+class TelemetryFrequency {
+  private final Configuration config;
+  private Long frequency;
+
+  TelemetryFrequency(Configuration config) {
+    this.config = config;
+  }
+
+  long get() {
+    if (frequency == null) {
+      frequency = config.getLong(TelemetryProperties.PROP_FREQUENCY)
+        .orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", TelemetryProperties.PROP_FREQUENCY)));
+    }
+
+    return frequency;
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryModule.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryModule.java
new file mode 100644 (file)
index 0000000..4f93a20
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.telemetry;
+
+import org.sonar.core.platform.Module;
+
+public class TelemetryModule extends Module {
+  @Override
+  protected void configureModule() {
+    add(
+      TelemetryProperties.class,
+      TelemetryDaemon.class,
+      TelemetryClient.class);
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryProperties.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryProperties.java
new file mode 100644 (file)
index 0000000..a77a67f
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import org.sonar.api.Properties;
+import org.sonar.api.Property;
+
+@Properties({
+  @Property(
+    key = TelemetryProperties.PROP_FREQUENCY,
+    // 6 hours in seconds
+    defaultValue = "21600",
+    name = "Frequency of telemetry checks, in seconds",
+    global = false),
+  @Property(
+    key = TelemetryProperties.PROP_URL,
+    defaultValue = "https://telemetry.sonarsource.com/sonarqube",
+    name = "URL where telemetry data is sent",
+    global = false)
+})
+public class TelemetryProperties {
+  static final String PROP_FREQUENCY = "sonar.telemetry.frequency";
+  static final String PROP_URL = "sonar.telemetry.url";
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryUrl.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryUrl.java
new file mode 100644 (file)
index 0000000..70bf5d1
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import org.sonar.api.config.Configuration;
+
+import static org.sonar.server.telemetry.TelemetryProperties.PROP_URL;
+
+class TelemetryUrl {
+  private final Configuration config;
+  private String url;
+
+  TelemetryUrl(Configuration config) {
+    this.config = config;
+  }
+
+  String get() {
+    if (url == null) {
+      url = config.get(PROP_URL).orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", PROP_URL)));
+    }
+
+    return url;
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/package-info.java
new file mode 100644 (file)
index 0000000..c3b6ec3
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.server.telemetry;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/server/sonar-server/src/test/java/org/sonar/server/telemetry/FakeServer.java b/server/sonar-server/src/test/java/org/sonar/server/telemetry/FakeServer.java
new file mode 100644 (file)
index 0000000..a4c788e
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import java.io.File;
+import java.util.Date;
+import javax.annotation.CheckForNull;
+import org.sonar.api.platform.Server;
+
+class FakeServer extends Server {
+  private String id;
+
+  @Override
+  public String getId() {
+    return id;
+  }
+
+  FakeServer setId(String id) {
+    this.id = id;
+    return this;
+  }
+
+  @CheckForNull
+  @Override
+  public String getPermanentServerId() {
+    return null;
+  }
+
+  @Override
+  public String getVersion() {
+    return null;
+  }
+
+  @Override
+  public Date getStartedAt() {
+    return null;
+  }
+
+  @Override
+  public File getRootDir() {
+    return null;
+  }
+
+  @CheckForNull
+  @Override
+  public File getDeployDir() {
+    return null;
+  }
+
+  @Override
+  public String getContextPath() {
+    return null;
+  }
+
+  @Override
+  public String getPublicRootUrl() {
+    return null;
+  }
+
+  @Override
+  public boolean isDev() {
+    return false;
+  }
+
+  @Override
+  public boolean isSecured() {
+    return false;
+  }
+
+  @Override
+  public String getURL() {
+    return null;
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java b/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java
new file mode 100644 (file)
index 0000000..1f523fd
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.internal.MapSettings;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.contains;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+public class TelemetryDaemonTest {
+
+  private TelemetryClient client = mock(TelemetryClient.class);
+  private FakeServer server = new FakeServer();
+  private MapSettings settings;
+
+  private TelemetryDaemon underTest;
+
+  @Before
+  public void setUp() throws Exception {
+    settings = new MapSettings(new PropertyDefinitions(TelemetryProperties.class));
+
+    underTest = new TelemetryDaemon(client, server, settings.asConfig());
+  }
+
+  @Test
+  public void send_data_via_client_at_startup_after_initial_delay() {
+    settings.setProperty("sonar.telemetry.frequency", "1");
+    underTest.start();
+
+    verify(client, timeout(2_000).atLeastOnce()).send(anyString());
+  }
+
+  @Test
+  public void send_data_periodically() {
+    settings.setProperty("sonar.telemetry.frequency", "1");
+    underTest = new TelemetryDaemon(client, server, settings.asConfig());
+
+    underTest.start();
+
+    verify(client, timeout(3_000).atLeast(2)).send(anyString());
+  }
+
+  @Test
+  public void send_server_id() {
+    settings.setProperty("sonar.telemetry.frequency", "1");
+    String id = randomAlphanumeric(40);
+    server.setId(id);
+    underTest.start();
+
+    verify(client, timeout(2_000).atLeastOnce()).send(contains(id));
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryModuleTest.java
new file mode 100644 (file)
index 0000000..57c07eb
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.telemetry;
+
+import org.junit.Test;
+import org.sonar.core.platform.ComponentContainer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TelemetryModuleTest {
+  @Test
+  public void verify_count_of_added_components() {
+    ComponentContainer container = new ComponentContainer();
+    new TelemetryModule().configure(container);
+    assertThat(container.size()).isEqualTo(3 + 2);
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryPropertiesTest.java b/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryPropertiesTest.java
new file mode 100644 (file)
index 0000000..e3453ba
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import org.junit.Test;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.internal.MapSettings;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TelemetryPropertiesTest {
+
+  Configuration underTest = new MapSettings(new PropertyDefinitions(TelemetryProperties.class)).asConfig();
+
+  @Test
+  public void default_frequency_is_6_hours_in_seconds() {
+    assertThat(underTest.getInt("sonar.telemetry.frequency")).contains(6 * 60 * 60);
+  }
+
+  @Test
+  public void default_url_point_to_telemetry_server() {
+    assertThat(underTest.get("sonar.telemetry.url")).contains("https://telemetry.sonarsource.com/sonarqube");
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryUrlTest.java b/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryUrlTest.java
new file mode 100644 (file)
index 0000000..7f56216
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.MapSettings;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TelemetryUrlTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private MapSettings settings = new MapSettings();
+
+  private TelemetryUrl underTest;
+
+  @Test
+  public void return_url_as_is_when_no_ending_slash() {
+    settings.setProperty("sonar.telemetry.url", "http://localhost:9001");
+    underTest = new TelemetryUrl(settings.asConfig());
+
+    assertThat(underTest.get()).isEqualTo("http://localhost:9001");
+  }
+
+  @Test
+  public void fail_when_no_settings_to_define_muppet_url() {
+    underTest = new TelemetryUrl(settings.asConfig());
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Setting 'sonar.telemetry.url' must be provided.");
+
+    underTest.get();
+  }
+}
index 98587c470277bbc95d6e7eb28d049ee5f702fa5e..6c563a322949bdabeada00ff41d4e6570aca330a 100644 (file)
@@ -30,6 +30,7 @@ import org.sonarqube.tests.serverSystem.RestartTest;
 import org.sonarqube.tests.serverSystem.ServerSystemRestartingOrchestrator;
 import org.sonarqube.tests.settings.LicensesPageTest;
 import org.sonarqube.tests.settings.SettingsTestRestartingOrchestrator;
+import org.sonarqube.tests.telemetry.TelemetryTest;
 import org.sonarqube.tests.updateCenter.UpdateCenterTest;
 import org.sonarqube.tests.user.OnboardingTest;
 import org.sonarqube.tests.user.RealmAuthenticationTest;
@@ -57,6 +58,7 @@ import org.sonarqube.tests.user.UserEsResilienceTest;
   ActiveRuleEsResilienceTest.class,
   RuleEsResilienceTest.class,
   UserEsResilienceTest.class,
+  TelemetryTest.class,
   // ce
   CeWorkersTest.class
 })
diff --git a/tests/src/test/java/org/sonarqube/tests/telemetry/TelemetryTest.java b/tests/src/test/java/org/sonarqube/tests/telemetry/TelemetryTest.java
new file mode 100644 (file)
index 0000000..48797c7
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonarqube.tests.telemetry;
+
+import com.sonar.orchestrator.Orchestrator;
+import java.util.concurrent.TimeUnit;
+import javax.ws.rs.core.HttpHeaders;
+import okhttp3.mockwebserver.MockWebServer;
+import okhttp3.mockwebserver.RecordedRequest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+import static util.ItUtils.xooPlugin;
+
+public class TelemetryTest {
+
+  private static Orchestrator orchestrator;
+
+  private MockWebServer server;
+  private String url;
+
+  @Before
+  public void setUp() throws Exception {
+    server = new MockWebServer();
+    server.start();
+    url = server.url("").url().toString();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    server.shutdown();
+  }
+
+  @Test
+  public void send_telemetry_data_at_startup() throws Exception {
+    String serverId = randomAlphanumeric(40);
+    orchestrator = Orchestrator.builderEnv()
+      .addPlugin(xooPlugin())
+      .setServerProperty("sonar.telemetry.url", url)
+      .setServerProperty("sonar.core.id", serverId)
+      .build();
+    orchestrator.start();
+
+    RecordedRequest request = server.takeRequest(1, TimeUnit.SECONDS);
+
+    assertThat(request.getMethod()).isEqualTo("POST");
+    assertThat(request.getBody().readUtf8()).contains(serverId);
+    assertThat(request.getHeader(HttpHeaders.USER_AGENT)).contains("SonarQube");
+
+    orchestrator.stop();
+  }
+}