diff --git a/wsagent/agent/pom.xml b/wsagent/agent/pom.xml index 420c429fc93e..7ed77a7ffc37 100644 --- a/wsagent/agent/pom.xml +++ b/wsagent/agent/pom.xml @@ -29,6 +29,10 @@ com.google.inject guice + + com.squareup.okhttp3 + okhttp + javax.inject javax.inject diff --git a/wsagent/agent/src/main/java/org/eclipse/che/api/agent/WsAgentLauncher.java b/wsagent/agent/src/main/java/org/eclipse/che/api/agent/WsAgentLauncher.java index 29a6a15bd752..995f73bd7bd0 100644 --- a/wsagent/agent/src/main/java/org/eclipse/che/api/agent/WsAgentLauncher.java +++ b/wsagent/agent/src/main/java/org/eclipse/che/api/agent/WsAgentLauncher.java @@ -11,27 +11,36 @@ package org.eclipse.che.api.agent; import static com.google.common.base.MoreObjects.firstNonNull; +import static org.eclipse.che.api.machine.shared.Constants.WSAGENT_REFERENCE; import static org.eclipse.che.api.workspace.shared.Constants.WS_AGENT_PROCESS_NAME; +import java.io.IOException; import java.net.HttpURLConnection; +import java.util.Map; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Request.Builder; +import okhttp3.Response; import org.eclipse.che.api.agent.server.WsAgentHealthChecker; import org.eclipse.che.api.agent.server.WsAgentPingRequestFactory; import org.eclipse.che.api.agent.server.launcher.AgentLauncher; import org.eclipse.che.api.agent.shared.model.Agent; -import org.eclipse.che.api.core.ApiException; import org.eclipse.che.api.core.BadRequestException; import org.eclipse.che.api.core.NotFoundException; import org.eclipse.che.api.core.ServerException; +import org.eclipse.che.api.core.model.machine.Machine; +import org.eclipse.che.api.core.model.machine.Server; import org.eclipse.che.api.environment.server.MachineProcessManager; import org.eclipse.che.api.machine.server.exception.MachineException; import org.eclipse.che.api.machine.server.model.impl.CommandImpl; import org.eclipse.che.api.machine.server.spi.Instance; -import org.eclipse.che.api.workspace.shared.dto.WsAgentHealthStateDto; import org.eclipse.che.commons.annotation.Nullable; +import org.eclipse.che.commons.env.EnvironmentContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,6 +56,10 @@ public class WsAgentLauncher implements AgentLauncher { private static final String WS_AGENT_PROCESS_OUTPUT_CHANNEL = "workspace:%s:ext-server:output"; protected static final String DEFAULT_WS_AGENT_RUN_COMMAND = "~/che/ws-agent/bin/catalina.sh run"; + private static final String WS_AGENT_SERVER_NOT_FOUND_ERROR = + "Workspace agent server not found in dev machine."; + private static final String WS_AGENT_URL_IS_NULL_OR_EMPTY_ERROR = + "URL of Workspace Agent is null or empty."; private final Provider machineProcessManagerProvider; private final WsAgentPingRequestFactory wsAgentPingRequestFactory; @@ -56,6 +69,7 @@ public class WsAgentLauncher implements AgentLauncher { private final String pingTimedOutErrorMessage; private final int wsAgentPingSuccessThreshold; private final String wsAgentRunCommand; + private final OkHttpClient okHttpClient; @Inject public WsAgentLauncher( @@ -66,7 +80,8 @@ public WsAgentLauncher( @Named("che.workspace.agent.dev.max_start_time_ms") long wsAgentMaxStartTimeMs, @Named("che.workspace.agent.dev.ping_delay_ms") long wsAgentPingDelayMs, @Named("che.workspace.agent.dev.ping_success_threshold") int wsAgentPingSuccessThreshold, - @Named("che.workspace.agent.dev.ping_timeout_error_msg") String pingTimedOutErrorMessage) { + @Named("che.workspace.agent.dev.ping_timeout_error_msg") String pingTimedOutErrorMessage, + @Named("che.workspace.agent.dev.ping_conn_timeout_ms") int wsAgentPingConnectionTimeoutMs) { this.machineProcessManagerProvider = machineProcessManagerProvider; this.wsAgentPingRequestFactory = wsAgentPingRequestFactory; this.wsAgentHealthChecker = wsAgentHealthChecker; @@ -75,6 +90,11 @@ public WsAgentLauncher( this.wsAgentPingSuccessThreshold = wsAgentPingSuccessThreshold; this.pingTimedOutErrorMessage = pingTimedOutErrorMessage; this.wsAgentRunCommand = wsAgentRunCommand; + okHttpClient = + new OkHttpClient() + .newBuilder() + .connectTimeout(wsAgentPingConnectionTimeoutMs, TimeUnit.MILLISECONDS) + .build(); } @Override @@ -158,13 +178,41 @@ public static String getWsAgentProcessOutputChannel(String workspaceId) { } private boolean pingWsAgent(Instance machine) throws ServerException { - try { - WsAgentHealthStateDto state = wsAgentHealthChecker.check(machine); - if (state.getCode() == HttpURLConnection.HTTP_OK) { - return true; - } - } catch (ApiException ignored) { + String wsAgentURL = getWsAgentURL(machine); + String token = EnvironmentContext.getCurrent().getSubject().getToken(); + + Builder requestBuilder = new Request.Builder().url(wsAgentURL); + if (token != null) { + requestBuilder.addHeader("Authorization", token); + } + Request request = requestBuilder.build(); + try (Response response = okHttpClient.newCall(request).execute()) { + return response.code() == HttpURLConnection.HTTP_OK; + } catch (IOException e) { } return false; } + + private String getWsAgentURL(Machine machine) throws ServerException { + Server wsAgent = getWsAgent(machine); + if (wsAgent == null) { + LOG.error( + "{} WorkspaceId: {}, DevMachine Id: {}", + WS_AGENT_SERVER_NOT_FOUND_ERROR, + machine.getWorkspaceId(), + machine.getId()); + throw new ServerException(WS_AGENT_SERVER_NOT_FOUND_ERROR); + } + return wsAgent.getProperties().getInternalUrl(); + } + + private Server getWsAgent(Machine machine) { + final Map servers = machine.getRuntime().getServers(); + for (Server server : servers.values()) { + if (WSAGENT_REFERENCE.equals(server.getRef())) { + return server; + } + } + return null; + } } diff --git a/wsagent/agent/src/test/java/org/eclipse/che/api/agent/WsAgentLauncherTest.java b/wsagent/agent/src/test/java/org/eclipse/che/api/agent/WsAgentLauncherTest.java index d2938264e855..35cfedd07004 100644 --- a/wsagent/agent/src/test/java/org/eclipse/che/api/agent/WsAgentLauncherTest.java +++ b/wsagent/agent/src/test/java/org/eclipse/che/api/agent/WsAgentLauncherTest.java @@ -51,6 +51,7 @@ public class WsAgentLauncherTest { private static final String WORKSPACE_ID = "testWorkspaceId"; private static final String WS_AGENT_PORT = Constants.WS_AGENT_PORT; private static final long WS_AGENT_MAX_START_TIME_MS = 1000; + private static final int WS_AGENT_DEV_PING_CONN_TIMEOUT_MS = 30000; private static final long WS_AGENT_PING_DELAY_MS = 1; private static final int WS_AGENT_PING_SUCCESS_THRESHOLD = 5; private static final String WS_AGENT_SERVER_LOCATION = "ws-agent.com:456789/"; @@ -61,7 +62,11 @@ public class WsAgentLauncherTest { new ServerPropertiesImpl(null, WS_AGENT_SERVER_LOCATION, WS_AGENT_SERVER_URL); private static final ServerImpl SERVER = new ServerImpl( - "ref", "http", WS_AGENT_SERVER_LOCATION_EXT, WS_AGENT_SERVER_URL_EXT, SERVER_PROPERTIES); + "wsagent", + "http", + WS_AGENT_SERVER_LOCATION_EXT, + WS_AGENT_SERVER_URL_EXT, + SERVER_PROPERTIES); private static final String WS_AGENT_TIMED_OUT_MESSAGE = "timeout error message"; @Mock private MachineProcessManager machineProcessManager; @@ -86,7 +91,8 @@ public void setUp() throws Exception { WS_AGENT_MAX_START_TIME_MS, WS_AGENT_PING_DELAY_MS, WS_AGENT_PING_SUCCESS_THRESHOLD, - WS_AGENT_TIMED_OUT_MESSAGE); + WS_AGENT_TIMED_OUT_MESSAGE, + WS_AGENT_DEV_PING_CONN_TIMEOUT_MS); pingRequest = Mockito.mock(HttpJsonRequest.class, new SelfReturningAnswer()); Mockito.when(agent.getScript()).thenReturn("script"); Mockito.when(machine.getId()).thenReturn(MACHINE_ID);