]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9525 make CeHttpClient an interface
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 10 Jul 2017 11:57:34 +0000 (13:57 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Tue, 18 Jul 2017 06:51:46 +0000 (08:51 +0200)
server/sonar-server/src/main/java/org/sonar/ce/CeModule.java
server/sonar-server/src/main/java/org/sonar/ce/http/CeHttpClient.java
server/sonar-server/src/main/java/org/sonar/ce/http/CeHttpClientImpl.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/ce/http/CeHttpClientTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/ws/ChangeLogLevelActionTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java

index 2b58a89ae48abf9bb272674d2d788017db8df3a4..7468de33f63852b7682e177da14e88ea61fb65c0 100644 (file)
@@ -19,7 +19,7 @@
  */
 package org.sonar.ce;
 
-import org.sonar.ce.http.CeHttpClient;
+import org.sonar.ce.http.CeHttpClientImpl;
 import org.sonar.ce.log.CeLogging;
 import org.sonar.ce.queue.CeQueueImpl;
 import org.sonar.ce.taskprocessor.ReportTaskProcessorDeclaration;
@@ -30,7 +30,7 @@ public class CeModule extends Module {
   @Override
   protected void configureModule() {
     add(CeLogging.class,
-      CeHttpClient.class,
+      CeHttpClientImpl.class,
 
       // Queue
       CeQueueImpl.class,
index 4d6271a79219dc990b5db7bf0ab7c9804bc7ae68..9c2d24e3b86965743f23bbdbe926419d66c93d59 100644 (file)
  */
 package org.sonar.ce.http;
 
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
 import java.util.Optional;
-import okhttp3.OkHttpClient;
-import okhttp3.RequestBody;
-import org.apache.commons.io.IOUtils;
-import org.sonar.api.config.Configuration;
 import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.process.DefaultProcessCommands;
 import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
 
-import static java.util.Objects.requireNonNull;
-import static org.sonar.process.ProcessEntryPoint.PROPERTY_SHARED_PATH;
-import static org.sonar.process.ProcessId.COMPUTE_ENGINE;
+public interface CeHttpClient {
+  Optional<ProtobufSystemInfo.SystemInfo> retrieveSystemInfo();
 
-/**
- * Client for the HTTP server of the Compute Engine.
- */
-public class CeHttpClient {
-
-  private static final String PATH_CHANGE_LOG_LEVEL = "changeLogLevel";
-  private static final String PATH_SYSTEM_INFO = "systemInfo";
-
-  private final File ipcSharedDir;
-
-  public CeHttpClient(Configuration config) {
-    this.ipcSharedDir = new File(config.get(PROPERTY_SHARED_PATH).get());
-  }
-
-  /**
-   * Connects to the specified JVM process and requests system information.
-   * @return the system info, or absent if the process is not up or if its HTTP URL
-   * is not registered into IPC.
-   */
-  public Optional<ProtobufSystemInfo.SystemInfo> retrieveSystemInfo() {
-    return call(SystemInfoActionClient.INSTANCE);
-  }
-
-  private enum SystemInfoActionClient implements ActionClient<Optional<ProtobufSystemInfo.SystemInfo>> {
-    INSTANCE;
-
-    @Override
-    public String getPath() {
-      return PATH_SYSTEM_INFO;
-    }
-
-    @Override
-    public Optional<ProtobufSystemInfo.SystemInfo> getDefault() {
-      return Optional.empty();
-    }
-
-    @Override
-    public Optional<ProtobufSystemInfo.SystemInfo> call(String url) throws Exception {
-      byte[] protobuf = IOUtils.toByteArray(new URI(url));
-      return Optional.of(ProtobufSystemInfo.SystemInfo.parseFrom(protobuf));
-    }
-  }
-
-  public void changeLogLevel(LoggerLevel level) {
-    requireNonNull(level, "level can't be null");
-    call(new ChangeLogLevelActionClient(level));
-  }
-
-  private static final class ChangeLogLevelActionClient implements ActionClient<Void> {
-    private final LoggerLevel newLogLevel;
-
-    private ChangeLogLevelActionClient(LoggerLevel newLogLevel) {
-      this.newLogLevel = newLogLevel;
-    }
-
-    @Override
-    public String getPath() {
-      return PATH_CHANGE_LOG_LEVEL;
-    }
-
-    @Override
-    public Void getDefault() {
-      return null;
-    }
-
-    @Override
-    public Void call(String url) throws Exception {
-      okhttp3.Request request = new okhttp3.Request.Builder()
-        .post(RequestBody.create(null, new byte[0]))
-        .url(url + "?level=" + newLogLevel.name())
-        .build();
-      okhttp3.Response response = new OkHttpClient().newCall(request).execute();
-      if (response.code() != 200) {
-        throw new IOException(
-          String.format(
-            "Failed to change log level in Compute Engine. Code was '%s' and response was '%s' for url '%s'",
-            response.code(),
-            response.body().string(),
-            url));
-      }
-      return null;
-    }
-  }
-
-  public void refreshCeWorkerCount() {
-    call(RefreshCeWorkerCountActionClient.INSTANCE);
-  }
-
-  private enum RefreshCeWorkerCountActionClient implements ActionClient<Void> {
-    INSTANCE;
-
-    @Override
-    public String getPath() {
-      return "refreshWorkerCount";
-    }
-
-    @Override
-    public Void getDefault() {
-      return null;
-    }
-
-    @Override
-    public Void call(String url) throws Exception {
-      okhttp3.Request request = new okhttp3.Request.Builder()
-        .post(RequestBody.create(null, new byte[0]))
-        .url(url)
-        .build();
-      okhttp3.Response response = new OkHttpClient().newCall(request).execute();
-      if (response.code() != 200) {
-        throw new IOException(
-          String.format(
-            "Failed to trigger refresh of CE Worker count. Code was '%s' and response was '%s' for url '%s'",
-            response.code(),
-            response.body().string(),
-            url));
-      }
-      return null;
-    }
-  }
-
-  private <T> T call(ActionClient<T> actionClient) {
-    try (DefaultProcessCommands commands = DefaultProcessCommands.secondary(ipcSharedDir, COMPUTE_ENGINE.getIpcIndex())) {
-      if (commands.isUp()) {
-        return actionClient.call(commands.getHttpUrl() + "/" + actionClient.getPath());
-      }
-      return actionClient.getDefault();
-    } catch (Exception e) {
-      throw new IllegalStateException("Failed to call HTTP server of process " + COMPUTE_ENGINE, e);
-    }
-  }
-
-  private interface ActionClient<T> {
-    /**
-     * Path of the action.
-     */
-    String getPath();
-
-    /**
-     * Value to return when the Compute Engine is not ready.
-     */
-    T getDefault();
+  void changeLogLevel(LoggerLevel level);
 
-    /**
-     * Delegates to perform the call to the Compute Engine's specified absolute URL.
-     */
-    T call(String url) throws Exception;
-  }
+  void refreshCeWorkerCount();
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/ce/http/CeHttpClientImpl.java b/server/sonar-server/src/main/java/org/sonar/ce/http/CeHttpClientImpl.java
new file mode 100644 (file)
index 0000000..09f0f8a
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * 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.ce.http;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Optional;
+import okhttp3.OkHttpClient;
+import okhttp3.RequestBody;
+import org.apache.commons.io.IOUtils;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.utils.log.LoggerLevel;
+import org.sonar.process.DefaultProcessCommands;
+import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
+
+import static java.util.Objects.requireNonNull;
+import static org.sonar.process.ProcessEntryPoint.PROPERTY_SHARED_PATH;
+import static org.sonar.process.ProcessId.COMPUTE_ENGINE;
+
+/**
+ * Client for the HTTP server of the Compute Engine.
+ */
+public class CeHttpClientImpl implements CeHttpClient {
+
+  private static final String PATH_CHANGE_LOG_LEVEL = "changeLogLevel";
+  private static final String PATH_SYSTEM_INFO = "systemInfo";
+
+  private final File ipcSharedDir;
+
+  public CeHttpClientImpl(Configuration config) {
+    this.ipcSharedDir = new File(config.get(PROPERTY_SHARED_PATH).get());
+  }
+
+  /**
+   * Connects to the specified JVM process and requests system information.
+   * @return the system info, or absent if the process is not up or if its HTTP URL
+   * is not registered into IPC.
+   */
+  @Override
+  public Optional<ProtobufSystemInfo.SystemInfo> retrieveSystemInfo() {
+    return call(SystemInfoActionClient.INSTANCE);
+  }
+
+  private enum SystemInfoActionClient implements ActionClient<Optional<ProtobufSystemInfo.SystemInfo>> {
+    INSTANCE;
+
+    @Override
+    public String getPath() {
+      return PATH_SYSTEM_INFO;
+    }
+
+    @Override
+    public Optional<ProtobufSystemInfo.SystemInfo> getDefault() {
+      return Optional.empty();
+    }
+
+    @Override
+    public Optional<ProtobufSystemInfo.SystemInfo> call(String url) throws Exception {
+      byte[] protobuf = IOUtils.toByteArray(new URI(url));
+      return Optional.of(ProtobufSystemInfo.SystemInfo.parseFrom(protobuf));
+    }
+  }
+
+  @Override
+  public void changeLogLevel(LoggerLevel level) {
+    requireNonNull(level, "level can't be null");
+    call(new ChangeLogLevelActionClient(level));
+  }
+
+  private static final class ChangeLogLevelActionClient implements ActionClient<Void> {
+    private final LoggerLevel newLogLevel;
+
+    private ChangeLogLevelActionClient(LoggerLevel newLogLevel) {
+      this.newLogLevel = newLogLevel;
+    }
+
+    @Override
+    public String getPath() {
+      return PATH_CHANGE_LOG_LEVEL;
+    }
+
+    @Override
+    public Void getDefault() {
+      return null;
+    }
+
+    @Override
+    public Void call(String url) throws Exception {
+      okhttp3.Request request = new okhttp3.Request.Builder()
+        .post(RequestBody.create(null, new byte[0]))
+        .url(url + "?level=" + newLogLevel.name())
+        .build();
+      okhttp3.Response response = new OkHttpClient().newCall(request).execute();
+      if (response.code() != 200) {
+        throw new IOException(
+          String.format(
+            "Failed to change log level in Compute Engine. Code was '%s' and response was '%s' for url '%s'",
+            response.code(),
+            response.body().string(),
+            url));
+      }
+      return null;
+    }
+  }
+
+  @Override
+  public void refreshCeWorkerCount() {
+    call(RefreshCeWorkerCountActionClient.INSTANCE);
+  }
+
+  private enum RefreshCeWorkerCountActionClient implements ActionClient<Void> {
+    INSTANCE;
+
+    @Override
+    public String getPath() {
+      return "refreshWorkerCount";
+    }
+
+    @Override
+    public Void getDefault() {
+      return null;
+    }
+
+    @Override
+    public Void call(String url) throws Exception {
+      okhttp3.Request request = new okhttp3.Request.Builder()
+        .post(RequestBody.create(null, new byte[0]))
+        .url(url)
+        .build();
+      okhttp3.Response response = new OkHttpClient().newCall(request).execute();
+      if (response.code() != 200) {
+        throw new IOException(
+          String.format(
+            "Failed to trigger refresh of CE Worker count. Code was '%s' and response was '%s' for url '%s'",
+            response.code(),
+            response.body().string(),
+            url));
+      }
+      return null;
+    }
+  }
+
+  private <T> T call(ActionClient<T> actionClient) {
+    try (DefaultProcessCommands commands = DefaultProcessCommands.secondary(ipcSharedDir, COMPUTE_ENGINE.getIpcIndex())) {
+      if (commands.isUp()) {
+        return actionClient.call(commands.getHttpUrl() + "/" + actionClient.getPath());
+      }
+      return actionClient.getDefault();
+    } catch (Exception e) {
+      throw new IllegalStateException("Failed to call HTTP server of process " + COMPUTE_ENGINE, e);
+    }
+  }
+
+  private interface ActionClient<T> {
+    /**
+     * Path of the action.
+     */
+    String getPath();
+
+    /**
+     * Value to return when the Compute Engine is not ready.
+     */
+    T getDefault();
+
+    /**
+     * Delegates to perform the call to the Compute Engine's specified absolute URL.
+     */
+    T call(String url) throws Exception;
+  }
+}
index f44a234f28c32477ba619e783f0b751138391bd6..2e121fc8dddc93cdd2b51fc18716c52ef7918667 100644 (file)
@@ -57,7 +57,7 @@ public class CeHttpClientTest {
     ipcSharedDir = temp.newFolder();
     MapSettings settings = new MapSettings();
     settings.setProperty(ProcessEntryPoint.PROPERTY_SHARED_PATH, ipcSharedDir.getAbsolutePath());
-    underTest = new CeHttpClient(settings.asConfig());
+    underTest = new CeHttpClientImpl(settings.asConfig());
   }
 
   @Test
index 1d03eafa8c9bebe493f1209484d97908b2975600..3650dc10d7b84b90a6c53561cbd0891a1cb0d87f 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.ce.http.CeHttpClient;
+import org.sonar.ce.http.CeHttpClientImpl;
 import org.sonar.db.Database;
 import org.sonar.server.app.WebServerProcessLogging;
 import org.sonar.server.exceptions.ForbiddenException;
@@ -43,7 +44,7 @@ public class ChangeLogLevelActionTest {
 
   private ServerLogging serverLogging = mock(ServerLogging.class);
   private Database db = mock(Database.class);
-  private CeHttpClient ceHttpClient = mock(CeHttpClient.class);
+  private CeHttpClient ceHttpClient = mock(CeHttpClientImpl.class);
   private WebServerProcessLogging webServerProcessLogging = new WebServerProcessLogging();
   private ChangeLogLevelAction underTest = new ChangeLogLevelAction(userSession, serverLogging, db, ceHttpClient, webServerProcessLogging);
   private WsActionTester actionTester = new WsActionTester(underTest);
index 4f245cb601e13f5d506cb5db4610676e73387ad0..7182b0c34d7a215361fea4d402ec966e581d3050 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.Mockito;
 import org.sonar.ce.http.CeHttpClient;
+import org.sonar.ce.http.CeHttpClientImpl;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.platform.monitoring.Monitor;
 import org.sonar.server.tester.UserSessionRule;
@@ -46,7 +47,7 @@ public class InfoActionTest {
 
   private Monitor monitor1 = mock(Monitor.class);
   private Monitor monitor2 = mock(Monitor.class);
-  private CeHttpClient ceHttpClient = mock(CeHttpClient.class, Mockito.RETURNS_MOCKS);
+  private CeHttpClient ceHttpClient = mock(CeHttpClientImpl.class, Mockito.RETURNS_MOCKS);
 
   private InfoAction underTest = new InfoAction(userSessionRule, ceHttpClient, monitor1, monitor2);
   private WsActionTester actionTester = new WsActionTester(underTest);
index ab574a72946c57f8554358e94274cfc5e797165f..99530152be3c69efddfe24bb89784b7ceecd1876 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Test;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.ce.http.CeHttpClient;
+import org.sonar.ce.http.CeHttpClientImpl;
 import org.sonar.server.app.ProcessCommandWrapper;
 import org.sonar.server.app.RestartFlagHolder;
 import org.sonar.server.platform.Platform;
@@ -34,7 +35,7 @@ import static org.mockito.Mockito.mock;
 
 public class SystemWsTest {
 
-  CeHttpClient ceHttpClient = mock(CeHttpClient.class);
+  CeHttpClient ceHttpClient = mock(CeHttpClientImpl.class);
 
   @Test
   public void define() {