From: Sébastien Lesaint Date: Mon, 10 Jul 2017 11:57:34 +0000 (+0200) Subject: SONAR-9525 make CeHttpClient an interface X-Git-Tag: 6.6-RC1~878 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7779619c9134b24eadb7b37d322a91d6b498e09d;p=sonarqube.git SONAR-9525 make CeHttpClient an interface --- diff --git a/server/sonar-server/src/main/java/org/sonar/ce/CeModule.java b/server/sonar-server/src/main/java/org/sonar/ce/CeModule.java index 2b58a89ae48..7468de33f63 100644 --- a/server/sonar-server/src/main/java/org/sonar/ce/CeModule.java +++ b/server/sonar-server/src/main/java/org/sonar/ce/CeModule.java @@ -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, diff --git a/server/sonar-server/src/main/java/org/sonar/ce/http/CeHttpClient.java b/server/sonar-server/src/main/java/org/sonar/ce/http/CeHttpClient.java index 4d6271a7921..9c2d24e3b86 100644 --- a/server/sonar-server/src/main/java/org/sonar/ce/http/CeHttpClient.java +++ b/server/sonar-server/src/main/java/org/sonar/ce/http/CeHttpClient.java @@ -19,167 +19,14 @@ */ 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 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 retrieveSystemInfo() { - return call(SystemInfoActionClient.INSTANCE); - } - - private enum SystemInfoActionClient implements ActionClient> { - INSTANCE; - - @Override - public String getPath() { - return PATH_SYSTEM_INFO; - } - - @Override - public Optional getDefault() { - return Optional.empty(); - } - - @Override - public Optional 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 { - 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 { - 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 call(ActionClient 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 { - /** - * 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 index 00000000000..09f0f8abeaa --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/ce/http/CeHttpClientImpl.java @@ -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 retrieveSystemInfo() { + return call(SystemInfoActionClient.INSTANCE); + } + + private enum SystemInfoActionClient implements ActionClient> { + INSTANCE; + + @Override + public String getPath() { + return PATH_SYSTEM_INFO; + } + + @Override + public Optional getDefault() { + return Optional.empty(); + } + + @Override + public Optional 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 { + 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 { + 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 call(ActionClient 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 { + /** + * 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; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/ce/http/CeHttpClientTest.java b/server/sonar-server/src/test/java/org/sonar/ce/http/CeHttpClientTest.java index f44a234f28c..2e121fc8ddd 100644 --- a/server/sonar-server/src/test/java/org/sonar/ce/http/CeHttpClientTest.java +++ b/server/sonar-server/src/test/java/org/sonar/ce/http/CeHttpClientTest.java @@ -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 diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/ChangeLogLevelActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/ChangeLogLevelActionTest.java index 1d03eafa8c9..3650dc10d7b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/ChangeLogLevelActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/ChangeLogLevelActionTest.java @@ -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); diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java index 4f245cb601e..7182b0c34d7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java @@ -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); diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java index ab574a72946..99530152be3 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java @@ -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() {