smart-executor-client/src/main/java/org/gcube/vremanagement/executor/client/SmartExecutorClientImpl.java

247 lines
8.5 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.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.exception.InputsNullException;
import org.gcube.vremanagement.executor.exception.LaunchException;
import org.gcube.vremanagement.executor.exception.PluginInstanceNotFoundException;
import org.gcube.vremanagement.executor.exception.PluginNotFoundException;
import org.gcube.vremanagement.executor.json.SEMapper;
import org.gcube.vremanagement.executor.plugin.PluginStateEvolution;
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 final String pluginName;
protected final String address;
public SmartExecutorClientImpl(String pluginName, String address) {
this.pluginName = pluginName;
this.address = address;
}
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() throws ExecutorException {
// TODO Auto-generated method stub
return null;
}
@Override
public String getLaunches(String pluginName) throws ExecutorException {
// TODO Auto-generated method stub
return null;
}
@Override
public String launch(String pluginName, String launchParameter)
throws InputsNullException, PluginNotFoundException, LaunchException, ExecutorException {
try {
checkPluginName(pluginName);
logger.info("Going to launch {} ", launchParameter);
GXHTTPStringRequest gxHTTPStringRequest = GXHTTPStringRequest.newRequest(address);
gxHTTPStringRequest.from(SmartExecutorClient.class.getSimpleName());
gxHTTPStringRequest.header("Accept", GXConnection.APPLICATION_JSON_CHARSET_UTF_8);
gxHTTPStringRequest.header("Accept", "text/plain");
gxHTTPStringRequest.path(RestConstants.PLUGINS_PATH_PART);
gxHTTPStringRequest.path(pluginName);
HttpURLConnection httpURLConnection = gxHTTPStringRequest.post(launchParameter);
String uuid = parseHttpURLConnection(httpURLConnection);
logger.debug("{} launched with UUID {} ", pluginName, uuid);
return uuid;
} catch(ExecutorException e) {
throw e;
} catch(Exception e) {
throw new RuntimeException(e);
}
}
public UUID launch(String pluginName, LaunchParameter launchParameter)
throws InputsNullException, PluginNotFoundException, LaunchException, ExecutorException {
try {
String uuid = launch(pluginName, SEMapper.marshal(launchParameter));
return UUID.fromString(uuid);
} catch(ExecutorException e) {
throw e;
} catch(Exception e) {
throw new RuntimeException(e);
}
}
@Override
public String getLaunchState(String pluginName, String executionIdentifier, Integer iterationNumber)
throws PluginInstanceNotFoundException, ExecutorException {
try {
checkPluginName(pluginName);
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(executionIdentifier);
if(iterationNumber != null) {
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(ExecutorException e) {
throw e;
} catch(Exception e) {
throw new RuntimeException(e);
}
}
@Override
public PluginStateEvolution getPluginStateEvolution(String pluginName, UUID executionIdentifier,
Integer iterationNumber) throws PluginInstanceNotFoundException, ExecutorException {
try {
String pluginStateEvolution = getLaunchState(pluginName, executionIdentifier.toString(),
iterationNumber);
return SEMapper.unmarshal(PluginStateEvolution.class, pluginStateEvolution);
} catch(ExecutorException e) {
throw e;
} catch(Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean delete(String pluginName, String executionIdentifier, Boolean unschedule) throws ExecutorException {
try {
checkPluginName(pluginName);
logger.info("Going to stop plugin with UUID {} ", 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(executionIdentifier);
Map<String,String> parameters = new HashMap<>();
parameters.put(RestConstants.UNSCHEDULE_PARAM, Boolean.toString(unschedule));
gxHTTPStringRequest.queryParams(parameters);
HttpURLConnection httpURLConnection = gxHTTPStringRequest.delete();
String stoppedString = parseHttpURLConnection(httpURLConnection);
Boolean stopped = Boolean.valueOf(stoppedString);
logger.debug("Plugin with UUID {} {} stopped", executionIdentifier, stopped ? "successfully" : "was not");
return stopped;
} catch(ExecutorException e) {
throw e;
} catch(Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean delete(String pluginName, UUID executionIdentifier, boolean unschedule) throws ExecutorException {
return delete(pluginName, executionIdentifier.toString(), unschedule);
}
@Override
public boolean purge(String pluginName, String executionIdentifier) throws ExecutorException {
return delete(pluginName, executionIdentifier.toString(), true);
}
}