/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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.opencastproject.serviceregistry.remote;
import static com.entwinemedia.fn.Stream.$;
import static org.apache.commons.lang3.StringUtils.isBlank;
import org.opencastproject.job.api.JaxbJob;
import org.opencastproject.job.api.JaxbJobList;
import org.opencastproject.job.api.Job;
import org.opencastproject.job.api.Job.Status;
import org.opencastproject.job.api.JobParser;
import org.opencastproject.security.api.TrustedHttpClient;
import org.opencastproject.security.api.TrustedHttpClientException;
import org.opencastproject.serviceregistry.api.HostRegistration;
import org.opencastproject.serviceregistry.api.HostRegistrationParser;
import org.opencastproject.serviceregistry.api.IncidentService;
import org.opencastproject.serviceregistry.api.Incidents;
import org.opencastproject.serviceregistry.api.JaxbHostRegistrationList;
import org.opencastproject.serviceregistry.api.JaxbServiceRegistrationList;
import org.opencastproject.serviceregistry.api.JaxbServiceStatistics;
import org.opencastproject.serviceregistry.api.ServiceRegistration;
import org.opencastproject.serviceregistry.api.ServiceRegistrationParser;
import org.opencastproject.serviceregistry.api.ServiceRegistry;
import org.opencastproject.serviceregistry.api.ServiceRegistryException;
import org.opencastproject.serviceregistry.api.ServiceStatistics;
import org.opencastproject.serviceregistry.api.SystemLoad;
import org.opencastproject.serviceregistry.api.SystemLoad.NodeLoad;
import org.opencastproject.serviceregistry.api.SystemLoadParser;
import org.opencastproject.util.HttpUtil;
import org.opencastproject.util.NotFoundException;
import org.opencastproject.util.QueryStringBuilder;
import org.opencastproject.util.UrlSupport;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
/**
* This implementation of the remote service registry is able to provide the functionality specified by the api over
* <code>HTTP</code> rather than by directly connecting to the database that is backing the service.
* <p>
* This means that it is suited to run inside protected environments as long as there is an implementation of the
* service running somwhere that provides the matching communication endpoint, which is the case with the default
* implementation at org.opencastproject.serviceregistry.impl.ServiceRegistryJpaImpl.
* <p>
* Other than with the other <code>-remote</code> implementations, this one needs to be configured to find it's
* counterpart implementation. It may either point to a load balancer hiding a number of running instances or to one
* specific instance.
*/
public abstract class ServiceRegistryRemoteBase implements ServiceRegistry {
/** The logger */
private static final Logger logger = LoggerFactory.getLogger(ServiceRegistryRemoteBase.class);
/** Current job used to process job in the service registry. */
private static final ThreadLocal<Job> currentJob = new ThreadLocal<Job>();
/** Configuration key for the service registry */
public static final String OPT_SERVICE_REGISTRY_URL = "org.opencastproject.serviceregistry.url";
/** The http client to use when connecting to remote servers. */
public abstract TrustedHttpClient getHttpClient();
/** The incident service. */
public abstract IncidentService getIncidentService();
/** The complete URL of the actual service implementation, e.g. http://mh-admin:8080/services */
public abstract String getServiceUrl();
/** The base URL of this server, e.g. http://mh-client */
public abstract String getServerUrl();
private Incidents incidents;
@Override
public ServiceRegistration registerService(String serviceType, String host, String path)
throws ServiceRegistryException {
return registerService(serviceType, host, path, false);
}
@Override
public void enableHost(String host) throws ServiceRegistryException, NotFoundException {
final HttpPost post = post("enablehost");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("host", host));
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
throw new ServiceRegistryException("Can not url encode post parameters", e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(post);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
logger.info("Enabled host '" + host + "'.");
return;
} else if (responseStatusCode == HttpStatus.SC_NOT_FOUND) {
throw new NotFoundException("Host not found: " + host);
}
} catch (NotFoundException e) {
throw e;
} catch (Exception e) {
throw new ServiceRegistryException("Unable to enable '" + host + "'", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to enable '" + host + "'. HTTP status=" + responseStatusCode);
}
@Override
public void disableHost(String host) throws ServiceRegistryException, NotFoundException {
final HttpPost post = post("disablehost");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("host", host));
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
throw new ServiceRegistryException("Can not url encode post parameters", e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(post);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
logger.info("Disabled host '" + host + "'.");
return;
} else if (responseStatusCode == HttpStatus.SC_NOT_FOUND) {
throw new NotFoundException("Host not found: " + host);
}
} catch (NotFoundException e) {
throw e;
} catch (Exception e) {
throw new ServiceRegistryException("Unable to disable '" + host + "'", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to disable '" + host + "'. HTTP status=" + responseStatusCode);
}
/**
* {@inheritDoc}
* @throws ServiceRegistryException
*
* @see org.opencastproject.serviceregistry.api.ServiceRegistry#registerHost(String, String, long, int, float)
*/
@Override
public void registerHost(String host, String address, long memory, int cores, float maxLoad)
throws ServiceRegistryException {
final HttpPost post = post("registerhost");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("host", host));
params.add(new BasicNameValuePair("address", address));
params.add(new BasicNameValuePair("memory", Long.toString(memory)));
params.add(new BasicNameValuePair("cores", Integer.toString(cores)));
params.add(new BasicNameValuePair("maxLoad", Float.toString(maxLoad)));
post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new ServiceRegistryException("Can not url encode post parameters", e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(post);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
logger.info("Registered '" + host + "'.");
return;
}
} catch (Exception e) {
throw new ServiceRegistryException("Unable to register '" + host + "'", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to register '" + host + "'. HTTP status=" + responseStatusCode);
}
@Override
public void unregisterHost(String host) throws ServiceRegistryException {
final HttpPost post = post("unregisterhost");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("host", host));
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
throw new ServiceRegistryException("Can not url encode post parameters", e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(post);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
logger.info("Unregistered '" + host + "'.");
return;
}
} catch (Exception e) {
throw new ServiceRegistryException("Unable to unregister '" + host + "'", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to unregister '" + host + "'. HTTP status=" + responseStatusCode);
}
@Override
public ServiceRegistration registerService(String serviceType, String host, String path, boolean jobProducer)
throws ServiceRegistryException {
final HttpPost post = post("register");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("serviceType", serviceType));
params.add(new BasicNameValuePair("host", host));
params.add(new BasicNameValuePair("path", path));
params.add(new BasicNameValuePair("jobProducer", Boolean.toString(jobProducer)));
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
throw new ServiceRegistryException("Can not url encode post parameters", e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(post);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
logger.info("Registered '" + serviceType + "' on host '" + host + "' with path '" + path + "'.");
return ServiceRegistrationParser.parse(response.getEntity().getContent());
}
} catch (Exception e) {
throw new ServiceRegistryException("Unable to register '" + serviceType + "' on host '" + host + "' with path '"
+ path + "'.", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to register '" + serviceType + "' on host '" + host + "' with path '"
+ path + "'. HTTP status=" + responseStatusCode);
}
@Override
public void unRegisterService(String serviceType, String host) throws ServiceRegistryException {
final HttpPost post = post("unregister");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("serviceType", serviceType));
params.add(new BasicNameValuePair("host", host));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params);
post.setEntity(entity);
} catch (UnsupportedEncodingException e) {
throw new ServiceRegistryException("Can not url encode post parameters", e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(post);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
logger.info("Unregistered '" + serviceType + "' on host '" + host + "'.");
return;
}
} catch (Exception e) {
throw new ServiceRegistryException("Unable to register " + serviceType + " from host " + host, e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to unregister '" + serviceType + "' on host '" + host
+ "'. HTTP status=" + responseStatusCode);
}
@Override
public void setMaintenanceStatus(String host, boolean maintenance) throws NotFoundException, ServiceRegistryException {
final HttpPost post = post("maintenance");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("host", host));
params.add(new BasicNameValuePair("maintenance", Boolean.toString(maintenance)));
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
throw new ServiceRegistryException("Can not url encode post parameters", e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(post);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
logger.info("Set maintenance mode on '" + host + "' to '" + maintenance + "'.");
return;
} else if (responseStatusCode == HttpStatus.SC_NOT_FOUND) {
throw new NotFoundException("Host not found: " + host);
}
} catch (NotFoundException e) {
throw e;
} catch (Exception e) {
throw new ServiceRegistryException("Unable to set maintenance mode on " + host + " to '" + maintenance + "'", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to set maintenace mode on '" + host + "' to '" + maintenance
+ "'. HTTP status=" + responseStatusCode);
}
@Override
public Job createJob(String type, String operation) throws ServiceRegistryException {
return createJob(type, operation, null, null, true, 1.0f);
}
@Override
public Job createJob(String type, String operation, Float jobLoad) throws ServiceRegistryException {
return createJob(type, operation, null, null, true, jobLoad);
}
@Override
public Job createJob(String type, String operation, List<String> arguments) throws ServiceRegistryException {
return createJob(type, operation, arguments, null, true, 1.0f);
}
@Override
public Job createJob(String type, String operation, List<String> arguments, Float jobLoad) throws ServiceRegistryException {
return createJob(type, operation, arguments, null, true, jobLoad);
}
@Override
public Job createJob(String type, String operation, List<String> arguments, String payload)
throws ServiceRegistryException {
return createJob(type, operation, arguments, payload, true, 1.0f);
}
@Override
public Job createJob(String type, String operation, List<String> arguments, String payload, Float jobLoad)
throws ServiceRegistryException {
return createJob(type, operation, arguments, payload, true, jobLoad);
}
@Override
public Job createJob(String type, String operation, List<String> arguments, String payload, boolean queueable)
throws ServiceRegistryException {
return createJob(type, operation, arguments, payload, queueable, getCurrentJob(), 1.0f);
}
@Override
public Job createJob(String type, String operation, List<String> arguments, String payload, boolean queueable, Float jobLoad)
throws ServiceRegistryException {
return createJob(type, operation, arguments, payload, queueable, getCurrentJob(), jobLoad);
}
@Override
public Job createJob(String type, String operation, List<String> arguments, String payload, boolean queueable,
Job parentJob) throws ServiceRegistryException {
return createJob(type, operation, arguments, payload, queueable, parentJob, 1.0f);
}
@Override
public Job createJob(String type, String operation, List<String> arguments, String payload, boolean queueable,
Job parentJob, Float jobLoad) throws ServiceRegistryException {
final HttpPost post = post("job");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("jobType", type));
params.add(new BasicNameValuePair("host", getServerUrl()));
params.add(new BasicNameValuePair("operation", operation));
if (arguments != null && !arguments.isEmpty()) {
for (String argument : arguments) {
params.add(new BasicNameValuePair("arg", argument));
}
}
if (payload != null)
params.add(new BasicNameValuePair("payload", payload));
params.add(new BasicNameValuePair("start", Boolean.toString(queueable)));
params.add(new BasicNameValuePair("jobLoad", Float.toString(jobLoad)));
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
throw new ServiceRegistryException("Can not url encode post parameters", e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(post);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_CREATED) {
Job job = JobParser.parseJob(response.getEntity().getContent());
logger.debug("Created a new job '{}'", job);
return job;
}
} catch (Exception e) {
throw new ServiceRegistryException("Unable to create a job of type '" + type, e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to create a job of type '" + type + " (" + responseStatusCode + ")");
}
@Override
public Job updateJob(Job job) throws ServiceRegistryException, NotFoundException {
final HttpPut put = put("job/" + job.getId() + ".xml");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("job", JobParser.toXml(new JaxbJob(job))));
put.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
throw new ServiceRegistryException("Can not url encode post parameters", e);
} catch (IOException e) {
throw new ServiceRegistryException("Can not serialize job " + job, e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(put);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
logger.info("Updated job '{}'", job);
return job;
} else if (responseStatusCode == HttpStatus.SC_NOT_FOUND) {
throw new NotFoundException("Job not found: " + job.getId());
}
} catch (NotFoundException e) {
throw e;
} catch (Exception e) {
throw new ServiceRegistryException("Unable to update " + job, e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to update " + job + " (" + responseStatusCode + ")");
}
@Override
public Job getJob(long id) throws NotFoundException, ServiceRegistryException {
final HttpGet get = get("job/" + id + ".xml");
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NOT_FOUND) {
throw new NotFoundException("Unable to locate job " + id);
}
if (responseStatusCode == HttpStatus.SC_OK) {
return JobParser.parseJob(response.getEntity().getContent());
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get job id=" + id, e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to retrieve job " + id + " (" + responseStatusCode + ")");
}
@Override
public List<Job> getChildJobs(long id) throws ServiceRegistryException {
final HttpGet get = get("job/" + id + "/children.xml");
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
final JaxbJobList jaxbJobList = JobParser.parseJobList(response.getEntity().getContent());
return $(jaxbJobList.getJobs()).map(JaxbJob.fnToJob()).toList();
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get job id=" + id, e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to retrieve job " + id + " (" + responseStatusCode + ")");
}
@Override
public List<Job> getJobs(String serviceType, Status status) throws ServiceRegistryException {
QueryStringBuilder qsb = new QueryStringBuilder("jobs.xml").add("serviceType", serviceType);
if (status != null)
qsb.add("status", status.toString());
final HttpGet get = get(qsb.toString());
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
final JaxbJobList jaxbJobList = JobParser.parseJobList(response.getEntity().getContent());
return $(jaxbJobList.getJobs()).map(JaxbJob.fnToJob()).toList();
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get jobs", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to retrieve jobs via http:" + response.getStatusLine());
}
@Override
public List<Job> getActiveJobs() throws ServiceRegistryException {
QueryStringBuilder qsb = new QueryStringBuilder("activeJobs.xml");
final HttpGet get = get(qsb.toString());
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
final JaxbJobList jaxbJobList = JobParser.parseJobList(response.getEntity().getContent());
return $(jaxbJobList.getJobs()).map(JaxbJob.fnToJob()).toList();
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get active jobs", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to retrieve active jobs via http:" + response.getStatusLine());
}
@Override
public Incidents incident() {
if (incidents == null && getIncidentService() != null)
incidents = new Incidents(this, getIncidentService());
return incidents;
}
@Override
public List<ServiceRegistration> getServiceRegistrationsByLoad(String serviceType) throws ServiceRegistryException {
String servicePath = new QueryStringBuilder("available.xml").add("serviceType", serviceType).toString();
final HttpGet get = get(servicePath);
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
JaxbServiceRegistrationList serviceList = ServiceRegistrationParser.parseRegistrations(response.getEntity()
.getContent());
return new ArrayList<ServiceRegistration>(serviceList.getRegistrations());
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get service registrations", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get service registrations (" + responseStatusCode + ")");
}
@Override
public List<ServiceRegistration> getServiceRegistrationsByHost(String host) throws ServiceRegistryException {
String servicePath = new QueryStringBuilder("services.xml").add("host", host).toString();
final HttpGet get = get(servicePath);
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
JaxbServiceRegistrationList serviceList = ServiceRegistrationParser.parseRegistrations(response.getEntity()
.getContent());
return new ArrayList<ServiceRegistration>(serviceList.getRegistrations());
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get service registrations", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get service registrations (" + responseStatusCode + ")");
}
@Override
public List<ServiceRegistration> getServiceRegistrationsByType(String serviceType) throws ServiceRegistryException {
String servicePath = new QueryStringBuilder("services.xml").add("serviceType", serviceType).toString();
final HttpGet get = get(servicePath);
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
JaxbServiceRegistrationList serviceList = ServiceRegistrationParser.parseRegistrations(response.getEntity()
.getContent());
return new ArrayList<ServiceRegistration>(serviceList.getRegistrations());
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get service registrations", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get service registrations (" + responseStatusCode + ")");
}
@Override
public ServiceRegistration getServiceRegistration(String serviceType, String host) throws ServiceRegistryException {
if (isBlank(serviceType) || isBlank(host)) {
throw new IllegalArgumentException("Service type and host must be provided to locate service registrations");
}
String servicePath = new QueryStringBuilder("services.xml").add("serviceType", serviceType).add("host", host)
.toString();
final HttpGet get = get(servicePath);
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
return ServiceRegistrationParser.parse(response.getEntity().getContent());
} else if (responseStatusCode == HttpStatus.SC_NOT_FOUND) {
return null;
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get service registrations", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get service registrations (" + responseStatusCode + ")");
}
@Override
public List<ServiceRegistration> getServiceRegistrations() throws ServiceRegistryException {
final HttpGet get = get("services.xml");
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
JaxbServiceRegistrationList serviceList = ServiceRegistrationParser.parseRegistrations(response.getEntity()
.getContent());
return new ArrayList<ServiceRegistration>(serviceList.getRegistrations());
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get service registrations", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get service registrations (" + responseStatusCode + ")");
}
@Override
public List<HostRegistration> getHostRegistrations() throws ServiceRegistryException {
final HttpGet get = get("hosts.xml");
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
JaxbHostRegistrationList serviceList = HostRegistrationParser.parseRegistrations(response.getEntity()
.getContent());
return new ArrayList<HostRegistration>(serviceList.getRegistrations());
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get host registrations", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get host registrations (" + responseStatusCode + ")");
}
@Override
public List<ServiceStatistics> getServiceStatistics() throws ServiceRegistryException {
final HttpGet get = get("statistics.xml");
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
List<JaxbServiceStatistics> stats = ServiceRegistrationParser
.parseStatistics(response.getEntity().getContent()).getStats();
return new ArrayList<ServiceStatistics>(stats);
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get service statistics", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get service statistics (" + responseStatusCode + ")");
}
@Override
public long count(String serviceType, Status status) throws ServiceRegistryException {
return count(serviceType, null, null, status);
}
@Override
public long countByHost(String serviceType, String host, Status status) throws ServiceRegistryException {
if (isBlank(serviceType))
throw new IllegalArgumentException("Service type must not be null");
if (isBlank(host))
throw new IllegalArgumentException("Host must not be null");
if (status == null)
throw new IllegalArgumentException("Status must not be null");
return count(serviceType, host, null, status);
}
@Override
public long countByOperation(String serviceType, String operation, Status status) throws ServiceRegistryException {
if (isBlank(serviceType))
throw new IllegalArgumentException("Service type must not be null");
if (isBlank(operation))
throw new IllegalArgumentException("Operation must not be null");
if (status == null)
throw new IllegalArgumentException("Status must not be null");
return count(serviceType, null, operation, status);
}
@Override
public long count(String serviceType, String host, String operation, Status status) throws ServiceRegistryException {
QueryStringBuilder queryStringBuilder = new QueryStringBuilder("count");
if (StringUtils.isNotBlank(serviceType))
queryStringBuilder.add("serviceType", serviceType);
if (status != null)
queryStringBuilder.add("status", status.toString());
if (StringUtils.isNotBlank(host))
queryStringBuilder.add("host", host);
if (StringUtils.isNotBlank(operation))
queryStringBuilder.add("operation", operation);
final HttpGet get = get(queryStringBuilder.toString());
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
return Long.parseLong(EntityUtils.toString(response.getEntity()));
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get service statistics", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get service statistics (" + responseStatusCode + ")");
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.serviceregistry.api.ServiceRegistry#countOfAbnormalServices()
*/
@Override
public long countOfAbnormalServices() throws ServiceRegistryException {
QueryStringBuilder queryStringBuilder = new QueryStringBuilder("servicewarnings");
final HttpGet get = get(queryStringBuilder.toString());
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
return Long.parseLong(EntityUtils.toString(response.getEntity()));
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get service statistics", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get service statistics (" + responseStatusCode + ")");
}
@Override
public SystemLoad getCurrentHostLoads(boolean activeOnly) throws ServiceRegistryException {
QueryStringBuilder queryStringBuilder = new QueryStringBuilder("currentload");
queryStringBuilder.add("activeOnly", Boolean.toString(activeOnly));
final HttpGet get = get(queryStringBuilder.toString());
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
try (InputStream in = response.getEntity().getContent()) {
SystemLoad systemLoad = SystemLoadParser.parse(in);
return systemLoad;
}
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get node loads", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get node loads (" + responseStatusCode + ")");
}
private SystemLoad getMaxLoads(String host) throws ServiceRegistryException {
QueryStringBuilder queryStringBuilder = new QueryStringBuilder("maxload");
if (StringUtils.isNotBlank(StringUtils.trimToEmpty(host)))
queryStringBuilder.add("host", StringUtils.trimToEmpty(host));
final HttpGet get = get(queryStringBuilder.toString());
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(get);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_OK) {
SystemLoad systemLoad = SystemLoadParser.parse(response.getEntity().getContent());
return systemLoad;
}
} catch (IOException e) {
throw new ServiceRegistryException("Unable to get node loads", e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to get node loads (" + responseStatusCode + ")");
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.serviceregistry.api.ServiceRegistry#getMaxLoads()
*/
@Override
public SystemLoad getMaxLoads() throws ServiceRegistryException {
return getMaxLoads(null);
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.serviceregistry.api.ServiceRegistry#getMaxLoadOnNode(java.lang.String)
*/
@Override
public NodeLoad getMaxLoadOnNode(String host) throws ServiceRegistryException {
return getMaxLoads(host).get(host);
}
@Override
public void sanitize(String serviceType, String host) throws NotFoundException {
final HttpPost post = post("sanitize");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("serviceType", serviceType));
params.add(new BasicNameValuePair("host", host));
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Can not url encode post parameters", e);
}
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(post);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
return;
} else if (responseStatusCode == HttpStatus.SC_NOT_FOUND) {
throw new NotFoundException();
}
} catch (IOException e) {
throw new IllegalStateException("Unable to get service statistics", e);
} finally {
getHttpClient().close(response);
}
throw new IllegalStateException("Unable to get service statistics (" + responseStatusCode + ")");
}
@Override
public void removeJob(long id) throws NotFoundException, ServiceRegistryException {
HttpDelete delete = new HttpDelete(UrlSupport.concat(getServiceUrl(), "job", String.valueOf(id)));
HttpResponse response = null;
int responseStatusCode;
try {
response = getHttpClient().execute(delete);
responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
return;
} else if (responseStatusCode == HttpStatus.SC_NOT_FOUND) {
throw new NotFoundException();
}
} catch (TrustedHttpClientException e) {
throw new ServiceRegistryException(e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to remove job with ID " + id + " (" + responseStatusCode + ")");
}
@Override
public void removeParentlessJobs(int lifetime) throws ServiceRegistryException {
HttpPost post = post("removeparentlessjobs");
try {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("lifetime", String.valueOf(lifetime)));
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
HttpResponse response = null;
try {
response = getHttpClient().execute(post);
int responseStatusCode = response.getStatusLine().getStatusCode();
if (responseStatusCode == HttpStatus.SC_NO_CONTENT) {
logger.info("Parentless jobs successfully removed");
return;
}
} catch (TrustedHttpClientException e) {
throw new ServiceRegistryException(e);
} finally {
getHttpClient().close(response);
}
throw new ServiceRegistryException("Unable to remove parentless jobs");
}
@Override
public Job getCurrentJob() {
return currentJob.get();
}
@Override
public void setCurrentJob(Job job) {
currentJob.set(job);
}
/** Create a GET request. */
private HttpGet get(String action) {
return new HttpGet(HttpUtil.path(getServiceUrl(), action));
}
/** Create a POST request. */
private HttpPost post(String action) {
return new HttpPost(HttpUtil.path(getServiceUrl(), action));
}
/** Create a PUT request. */
private HttpPut put(String action) {
return new HttpPut(HttpUtil.path(getServiceUrl(), action));
}
}