332 lines
11 KiB
Java
332 lines
11 KiB
Java
package org.gcube.vremanagement.executor.client;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.net.HttpURLConnection;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
|
|
import javax.ws.rs.ForbiddenException;
|
|
import javax.ws.rs.NotFoundException;
|
|
import javax.ws.rs.WebApplicationException;
|
|
|
|
import org.gcube.common.gxhttp.reference.GXConnection;
|
|
import org.gcube.common.gxhttp.reference.GXConnection.HTTPMETHOD;
|
|
import org.gcube.common.gxhttp.request.GXHTTPStringRequest;
|
|
import org.gcube.vremanagement.executor.api.rest.RestConstants;
|
|
import org.gcube.vremanagement.executor.api.types.LaunchParameter;
|
|
import org.gcube.vremanagement.executor.exception.ExecutorException;
|
|
import org.gcube.vremanagement.executor.json.SEMapper;
|
|
import org.gcube.vremanagement.executor.plugin.PluginDefinition;
|
|
import org.gcube.vremanagement.executor.plugin.PluginStateEvolution;
|
|
import org.gcube.vremanagement.executor.plugin.ScheduledTask;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
*/
|
|
public class SmartExecutorClientImpl implements SmartExecutorClient {
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(SmartExecutorClientImpl.class);
|
|
|
|
public static final String PATH_SEPARATOR = "/";
|
|
|
|
protected String pluginName;
|
|
|
|
protected String host;
|
|
protected String address;
|
|
|
|
public static String getHostFromCompleteURL(String address) {
|
|
return address.split("(http)s{0,1}://")[1].split(":")[0];
|
|
}
|
|
|
|
@Override
|
|
public String getHost() {
|
|
return host;
|
|
}
|
|
|
|
public String getAddress() {
|
|
return address;
|
|
}
|
|
|
|
public void setAddress(String address) {
|
|
this.address = address;
|
|
this.host = getHostFromCompleteURL(address);
|
|
}
|
|
|
|
public String getPluginName() {
|
|
return pluginName;
|
|
}
|
|
|
|
public void setPluginName(String pluginName) {
|
|
this.pluginName = pluginName;
|
|
}
|
|
|
|
protected static StringBuilder getStringBuilder(InputStream inputStream) throws IOException {
|
|
StringBuilder result = new StringBuilder();
|
|
try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
|
String line;
|
|
while((line = reader.readLine()) != null) {
|
|
result.append(line);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
protected String parseHttpURLConnection(HttpURLConnection connection) throws WebApplicationException {
|
|
try {
|
|
int responseCode = connection.getResponseCode();
|
|
// String responseMessage = connection.getResponseMessage();
|
|
|
|
if(connection.getRequestMethod().compareTo(HTTPMETHOD.HEAD.toString()) == 0) {
|
|
if(responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
|
|
return null;
|
|
}
|
|
if(responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
|
|
throw new NotFoundException();
|
|
}
|
|
if(responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
|
|
throw new ForbiddenException();
|
|
}
|
|
}
|
|
|
|
if(responseCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
|
|
InputStream inputStream = connection.getErrorStream();
|
|
StringBuilder result = getStringBuilder(inputStream);
|
|
String res = result.toString();
|
|
throw new WebApplicationException(res, responseCode);
|
|
}
|
|
|
|
StringBuilder result = getStringBuilder(connection.getInputStream());
|
|
return result.toString();
|
|
} catch(WebApplicationException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new WebApplicationException(e);
|
|
} finally {
|
|
connection.disconnect();
|
|
}
|
|
}
|
|
|
|
private void checkPluginName(String pluginName) throws ExecutorException {
|
|
if(pluginName.compareTo(this.pluginName) != 0) {
|
|
throw new ExecutorException(
|
|
String.format("The client has been instantiated for %s so it cannot be used to launch %s",
|
|
this.pluginName, pluginName));
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public String getAvailablePlugins() {
|
|
try {
|
|
logger.info("Going to get Available Plugins on {}", host);
|
|
|
|
GXHTTPStringRequest gxHTTPStringRequest = GXHTTPStringRequest.newRequest(address);
|
|
gxHTTPStringRequest.from(SmartExecutorClient.class.getSimpleName());
|
|
gxHTTPStringRequest.header("Accept", GXConnection.APPLICATION_JSON_CHARSET_UTF_8);
|
|
gxHTTPStringRequest.path(RestConstants.PLUGINS_PATH_PART);
|
|
|
|
HttpURLConnection httpURLConnection = gxHTTPStringRequest.get();
|
|
String pluginList = parseHttpURLConnection(httpURLConnection);
|
|
|
|
logger.info("Available Plugins on {} are {}", host, pluginList);
|
|
|
|
return pluginList;
|
|
} catch(WebApplicationException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public List<PluginDefinition> getPlugins() throws IOException {
|
|
String pluginList = getAvailablePlugins();
|
|
return SEMapper.getInstance().unmarshalList(PluginDefinition.class,pluginList);
|
|
}
|
|
|
|
private String getScheduledTask(String name) {
|
|
try {
|
|
logger.info("Going to get {} scheduled tasks", name);
|
|
|
|
GXHTTPStringRequest gxHTTPStringRequest = GXHTTPStringRequest.newRequest(address);
|
|
gxHTTPStringRequest.from(SmartExecutorClient.class.getSimpleName());
|
|
gxHTTPStringRequest.header("Accept", GXConnection.APPLICATION_JSON_CHARSET_UTF_8);
|
|
gxHTTPStringRequest.path(RestConstants.PLUGINS_PATH_PART);
|
|
gxHTTPStringRequest.path(name);
|
|
gxHTTPStringRequest.path(RestConstants.EXECUTIONS_PATH_PART);
|
|
|
|
HttpURLConnection httpURLConnection = gxHTTPStringRequest.get();
|
|
String scheduledList = parseHttpURLConnection(httpURLConnection);
|
|
|
|
logger.info("{} scheduled task are {}", name, scheduledList);
|
|
|
|
return scheduledList;
|
|
} catch(WebApplicationException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getOrphanLaunches() {
|
|
return getScheduledTask(RestConstants.ORPHAN_PATH_PARAM);
|
|
}
|
|
|
|
@Override
|
|
public List<ScheduledTask> getOrphanScheduledLaunches() throws IOException {
|
|
String orphanList = getOrphanLaunches();
|
|
return SEMapper.getInstance().unmarshalList(ScheduledTask.class, orphanList);
|
|
}
|
|
|
|
@Override
|
|
public String getLaunches() {
|
|
return getScheduledTask(pluginName);
|
|
}
|
|
|
|
@Override
|
|
public List<ScheduledTask> getScheduledLaunches() throws IOException {
|
|
String launchesList = getLaunches();
|
|
return SEMapper.getInstance().unmarshalList(ScheduledTask.class, launchesList);
|
|
}
|
|
|
|
@Override
|
|
public String launch(String launchParameter) {
|
|
try {
|
|
logger.info("Going to launch plugin {} on {} with parameters {} ", pluginName, host, launchParameter);
|
|
GXHTTPStringRequest gxHTTPStringRequest = GXHTTPStringRequest.newRequest(address);
|
|
gxHTTPStringRequest.from(SmartExecutorClient.class.getSimpleName());
|
|
gxHTTPStringRequest.header("Content-Type", GXConnection.APPLICATION_JSON_CHARSET_UTF_8);
|
|
gxHTTPStringRequest.header("Accept", "text/plain");
|
|
gxHTTPStringRequest.path(RestConstants.PLUGINS_PATH_PART);
|
|
gxHTTPStringRequest.path(pluginName);
|
|
gxHTTPStringRequest.path(RestConstants.EXECUTIONS_PATH_PART);
|
|
HttpURLConnection httpURLConnection = gxHTTPStringRequest.post(launchParameter);
|
|
String uuid = parseHttpURLConnection(httpURLConnection);
|
|
logger.debug("Plugin {} launched on host {}. UUID to monitor the execution is {} ", pluginName, host, uuid);
|
|
return uuid;
|
|
} catch(WebApplicationException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
public UUID launch(LaunchParameter launchParameter) {
|
|
try {
|
|
checkPluginName(launchParameter.getPluginName());
|
|
String uuid = launch(SEMapper.getInstance().marshal(launchParameter));
|
|
return UUID.fromString(uuid);
|
|
} catch(WebApplicationException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getPluginStateEvolution(String executionIdentifier) {
|
|
return getPluginStateEvolution(executionIdentifier, -1);
|
|
}
|
|
|
|
@Override
|
|
public String getPluginStateEvolution(String executionIdentifier, int iterationNumber) {
|
|
try {
|
|
|
|
logger.info("Going to get {} of {} with UUID {} ", PluginStateEvolution.class.getSimpleName(), pluginName,
|
|
executionIdentifier);
|
|
|
|
GXHTTPStringRequest gxHTTPStringRequest = GXHTTPStringRequest.newRequest(address);
|
|
gxHTTPStringRequest.from(SmartExecutorClient.class.getSimpleName());
|
|
gxHTTPStringRequest.header("Accept", GXConnection.APPLICATION_JSON_CHARSET_UTF_8);
|
|
gxHTTPStringRequest.path(RestConstants.PLUGINS_PATH_PART);
|
|
gxHTTPStringRequest.path(pluginName);
|
|
gxHTTPStringRequest.path(RestConstants.EXECUTIONS_PATH_PART);
|
|
gxHTTPStringRequest.path(executionIdentifier);
|
|
|
|
if(iterationNumber > 0) {
|
|
Map<String,String> parameters = new HashMap<>();
|
|
parameters.put(RestConstants.ITERATION_PARAM, Integer.toString(iterationNumber));
|
|
gxHTTPStringRequest.queryParams(parameters);
|
|
}
|
|
|
|
HttpURLConnection httpURLConnection = gxHTTPStringRequest.get();
|
|
String pluginStateEvolution = parseHttpURLConnection(httpURLConnection);
|
|
return pluginStateEvolution;
|
|
} catch(WebApplicationException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public PluginStateEvolution getPluginStateEvolution(UUID executionIdentifier) {
|
|
return getPluginStateEvolution(executionIdentifier, -1);
|
|
}
|
|
|
|
@Override
|
|
public PluginStateEvolution getPluginStateEvolution(UUID executionIdentifier, int iterationNumber) {
|
|
try {
|
|
String pluginStateEvolution = getPluginStateEvolution(executionIdentifier.toString(), iterationNumber);
|
|
return SEMapper.getInstance().unmarshal(PluginStateEvolution.class, pluginStateEvolution);
|
|
} catch(WebApplicationException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean delete(String executionIdentifier) {
|
|
return delete(executionIdentifier.toString(), true);
|
|
}
|
|
|
|
@Override
|
|
public boolean delete(String executionIdentifier, boolean unschedule) {
|
|
try {
|
|
|
|
logger.info("Going to stop plugin {} with UUID {} on host {}", pluginName, executionIdentifier, host);
|
|
|
|
GXHTTPStringRequest gxHTTPStringRequest = GXHTTPStringRequest.newRequest(address);
|
|
gxHTTPStringRequest.from(SmartExecutorClient.class.getSimpleName());
|
|
gxHTTPStringRequest.header("Accept", "text/plain");
|
|
gxHTTPStringRequest.path(RestConstants.PLUGINS_PATH_PART);
|
|
gxHTTPStringRequest.path(pluginName);
|
|
gxHTTPStringRequest.path(RestConstants.EXECUTIONS_PATH_PART);
|
|
gxHTTPStringRequest.path(executionIdentifier);
|
|
|
|
Map<String,String> parameters = new HashMap<>();
|
|
parameters.put(RestConstants.UNSCHEDULE_PARAM, Boolean.toString(unschedule));
|
|
gxHTTPStringRequest.queryParams(parameters);
|
|
|
|
HttpURLConnection httpURLConnection = gxHTTPStringRequest.delete();
|
|
parseHttpURLConnection(httpURLConnection);
|
|
return true;
|
|
} catch(WebApplicationException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean delete(UUID executionIdentifier) {
|
|
return delete(executionIdentifier.toString(), true);
|
|
}
|
|
|
|
@Override
|
|
public boolean delete(UUID executionIdentifier, boolean unschedule) {
|
|
return delete(executionIdentifier.toString(), unschedule);
|
|
}
|
|
|
|
}
|