/**
* Copyright 2014 SAP AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.spotter.client;
import java.io.InputStream;
import java.util.Set;
import javax.ws.rs.core.MediaType;
import org.lpe.common.config.ConfigParameterDescription;
import org.lpe.common.util.web.LpeWebUtils;
import org.spotter.shared.configuration.ConfigKeys;
import org.spotter.shared.configuration.JobDescription;
import org.spotter.shared.configuration.SpotterExtensionType;
import org.spotter.shared.hierarchy.model.XPerformanceProblem;
import org.spotter.shared.service.SpotterServiceResponse;
import org.spotter.shared.status.SpotterProgress;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
/**
* Client for resource monitoring.
*
* @author Alexander Wert
*
*/
public class SpotterServiceClient {
private String url;
private WebResource webResource;
private Client client;
/**
* Constructor.
*
* @param host
* host of the service
* @param port
* port where to reach service
*/
public SpotterServiceClient(String host, String port) {
url = "http://" + host + ":" + port;
client = LpeWebUtils.getWebClient();
webResource = client.resource(url);
}
/**
* Updates the URL and creates a new web resource.
*
* @param host
* host of the service
* @param port
* port where to reach service
*/
public void updateUrl(String host, String port) {
url = "http://" + host + ":" + port;
webResource = client.resource(url);
}
/**
* Executes diagnostics process.
*
* @param jobDescription
* the job description to use
* @return job id for the started diagnosis task
*/
public long startDiagnosis(JobDescription jobDescription) {
SpotterServiceResponse<Long> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_START_DIAG).type(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON).post(new GenericType<SpotterServiceResponse<Long>>() {
}, jobDescription);
switch (response.getStatus()) {
case INVALID_STATE:
throw new IllegalStateException("Spotter is already running");
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
* Requests the results of a the run with the given job id.
*
* @param jobId
* the job id of the diagnosis run
* @return input stream of the zipped run result folder or <code>null</code>
* if none found
*/
public InputStream requestResults(String jobId) {
ClientResponse response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_REQU_RESULTS).type(MediaType.APPLICATION_JSON).accept("application/zip")
.post(ClientResponse.class, jobId);
InputStream inputStream = response.getEntityInputStream();
if (inputStream != null) {
return inputStream;
} else {
throw new RuntimeException("Server error: Received no data");
}
}
/**
* Returns whether the Spotter Diagnostics is currently running. If the
* method returns <code>false</code> either the last run has finished
* successfully or the run had been canceled. For the second case the last
* exception thrown during that run can be requested via
* {@link #getLastRunException}.
*
* @return <code>true</code> if Spotter Diagnostics is currently running,
* <code>false</code> otherwise
*/
public synchronized boolean isRunning() {
SpotterServiceResponse<Boolean> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_IS_RUNNING).accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<Boolean>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
*
* @return the exception thrown during the last diagnosis run or
* <code>null</code> if none
*/
public synchronized Exception getLastRunException() {
SpotterServiceResponse<Exception> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_LAST_EXCEPTION).accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<Exception>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
*
* @return list of configuration parameter descriptions for Spotter
* configuration.
*/
public synchronized Set<ConfigParameterDescription> getConfigurationParameters() {
SpotterServiceResponse<Set<ConfigParameterDescription>> response = webResource
.path(ConfigKeys.SPOTTER_REST_BASE).path(ConfigKeys.SPOTTER_REST_CONFIG_PARAMS)
.accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<Set<ConfigParameterDescription>>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
* Returns a list of extension names for the given extension type.
*
* @param extType
* extension type of interest
* @return list of names
*/
public Set<String> getAvailableExtensions(SpotterExtensionType extType) {
SpotterServiceResponse<Set<String>> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_EXTENSIONS).path(extType.toString()).accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<Set<String>>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
* Returns a set of available configuration parameters for the given
* extension.
*
* @param extName
* name of the extension of interest
* @return list of configuration parameters
*/
public Set<ConfigParameterDescription> getExtensionConfigParamters(String extName) {
SpotterServiceResponse<Set<ConfigParameterDescription>> response = webResource
.path(ConfigKeys.SPOTTER_REST_BASE).path(ConfigKeys.SPOTTER_REST_EXTENSION_PARAMETERS).path(extName)
.accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<Set<ConfigParameterDescription>>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
* Returns the default hierarchy.
*
* @return the default hierarchy
*/
public XPerformanceProblem getDefaultHierarchy() {
SpotterServiceResponse<XPerformanceProblem> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_DEFAULT_HIERARCHY).accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<XPerformanceProblem>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
* Returns a report on the progress of the current job.
*
* @return progress report
*/
public SpotterProgress getCurrentProgressReport() {
SpotterServiceResponse<SpotterProgress> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_CURRENT_PROGRESS).accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<SpotterProgress>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
* Returns the id of the currently running job.
*
* @return id
*/
public Long getCurrentJobId() {
SpotterServiceResponse<Long> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_CURRENT_JOB).accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<Long>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
* Returns the root problem of the currently running job.
*
* @return the root problem
*/
public XPerformanceProblem getCurrentRootProblem() {
SpotterServiceResponse<XPerformanceProblem> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_CURRENT_ROOT_PROBLEM).accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<XPerformanceProblem>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
@Override
protected void finalize() throws Throwable {
client.destroy();
}
/**
* Tests connection to the satellite specified by the given extension name,
* host and port. If extension is not a satellite this method returns false!
*
* @param extName
* name of the extension to connect to
* @param host
* host / ip to connect to
* @param port
* port to connect to
* @return true if connection could have been established, otherwise false
*/
public boolean testConnectionToSattelite(String extName, String host, String port) {
SpotterServiceResponse<Boolean> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_TEST_SATELLITE_CONNECTION).path(extName).path(host).path(port)
.accept(MediaType.APPLICATION_JSON).get(new GenericType<SpotterServiceResponse<Boolean>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
/**
* Tests connection to the Spotter service.
*
* @return true if connection could have been established, otherwise false
*/
public boolean testConnection() {
SpotterServiceResponse<Boolean> response = webResource.path(ConfigKeys.SPOTTER_REST_BASE)
.path(ConfigKeys.SPOTTER_REST_TEST_CONNECTION).accept(MediaType.APPLICATION_JSON)
.get(new GenericType<SpotterServiceResponse<Boolean>>() {
});
switch (response.getStatus()) {
case OK:
return response.getPayload();
case SERVER_ERROR:
throw new RuntimeException("Server error: " + response.getErrorMessage());
case INVALID_STATE:
default:
throw new IllegalStateException("Illegal response state!");
}
}
}