Implemented getHealthCheck for Service
diff --git a/pom.xml b/pom.xml index 68f83d5..6898691 100644 --- a/pom.xml +++ b/pom.xml
@@ -28,6 +28,7 @@ <sonar-maven-plugin.version>3.0.2</sonar-maven-plugin.version> <commons-io.version>2.5</commons-io.version> <gson.version>2.8.0</gson.version> + <httpclient.version>4.5.2</httpclient.version> </properties> <dependencyManagement> @@ -58,6 +59,11 @@ <version>${gson.version}</version> </dependency> <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>${httpclient.version}</version> + </dependency> + <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>${easymock.version}</version> @@ -203,20 +209,5 @@ </plugins> </build> - <reporting> - <plugins> - <plugin> - <artifactId>maven-project-info-reports-plugin</artifactId> - <version>2.8.1</version> - <configuration> - <dependencyLocationsEnabled>false</dependencyLocationsEnabled> - <dependencyDetailsEnabled>false</dependencyDetailsEnabled> - </configuration> - </plugin> - <plugin> - <artifactId>maven-javadoc-plugin</artifactId> - <version>2.10.3</version> - </plugin> - </plugins> - </reporting> + </project>
diff --git a/src/main/java/pta/de/core/common/Globals.java b/src/main/java/pta/de/core/common/Globals.java new file mode 100644 index 0000000..a2e0d43 --- /dev/null +++ b/src/main/java/pta/de/core/common/Globals.java
@@ -0,0 +1,10 @@ +package pta.de.core.common; + + +public final class Globals { + public static final String HEADER_JSON_UTF8 = "application/json; charset=utf-8"; + public static final String HEALTH_CHECK_ADD_PATH = "healthcheck?pretty=true"; + + private Globals() { + } +}
diff --git a/src/main/java/pta/de/core/communication/RestServiceWrapper.java b/src/main/java/pta/de/core/communication/RestServiceWrapper.java new file mode 100644 index 0000000..dbfdbb8 --- /dev/null +++ b/src/main/java/pta/de/core/communication/RestServiceWrapper.java
@@ -0,0 +1,109 @@ +package pta.de.core.communication; + + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.util.EntityUtils; +import org.apache.log4j.Logger; +import pta.de.core.common.Globals; +import pta.de.core.exceptions.HttpStatusException; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +public class RestServiceWrapper { + private static final Logger LOGGER = Logger.getLogger(RestServiceWrapper.class.getName()); + private boolean useHttps; + + public RestServiceWrapper(boolean https) { + this.useHttps = https; + } + + public String performGetRequest(String restFunctionWithParams) throws HttpStatusException { + LOGGER.debug("CompleteUrl: " + restFunctionWithParams); + // create HTTP Client + CloseableHttpClient httpClient = createHttpsClient(); + + // create new Request with given URL + HttpGet getRequest = new HttpGet(restFunctionWithParams); + getRequest.addHeader("accept", Globals.HEADER_JSON_UTF8); + + HttpResponse response; + // Execute request an catch response + try { + response = httpClient.execute(getRequest); + + } catch (IOException e) { + String errtext = "Communication to <" + restFunctionWithParams + "> failed!"; + LOGGER.warn(errtext, e); + throw new HttpStatusException(HttpStatus.SC_SERVICE_UNAVAILABLE); + } + + return createJson(response); + } + + public String performPostRequest(String restFunctionWithParams, String data) throws HttpStatusException { + + // create HTTP Client + CloseableHttpClient httpClient = createHttpsClient(); + + // create new Post Request with given URL + HttpPost postRequest = new HttpPost(restFunctionWithParams); + + // add additional header to getRequest which accepts application/JSON data + postRequest.addHeader("accept", Globals.HEADER_JSON_UTF8); + postRequest.addHeader("Content-Type", Globals.HEADER_JSON_UTF8); + + postRequest.setEntity(new StringEntity(data, StandardCharsets.UTF_8)); + + HttpResponse response; + // Execute request an catch response + try { + response = httpClient.execute(postRequest); + } catch (IOException e) { + String errtext = "Communication to <" + restFunctionWithParams + "> failed!"; + LOGGER.warn(errtext, e); + throw new HttpStatusException(HttpStatus.SC_SERVICE_UNAVAILABLE); + } + return createJson(response); + } + + private CloseableHttpClient createHttpsClient() throws HttpStatusException { + if (useHttps) { + try { + SSLContextBuilder builder = new SSLContextBuilder(); + builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); + + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } catch (Exception e) { + LOGGER.error(e); + throw new HttpStatusException(HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + } else { + return HttpClientBuilder.create().build(); + } + } + + private String createJson(HttpResponse response) throws HttpStatusException { + String retJson; + try { + retJson = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + } catch (IOException e) { + LOGGER.error(e); + throw new HttpStatusException(HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + + return retJson; + } + +}
diff --git a/src/main/java/pta/de/core/controller/BackendController.java b/src/main/java/pta/de/core/controller/BackendController.java index 9364b43..e163863 100644 --- a/src/main/java/pta/de/core/controller/BackendController.java +++ b/src/main/java/pta/de/core/controller/BackendController.java
@@ -1,15 +1,21 @@ package pta.de.core.controller; +import org.apache.log4j.Logger; import org.eclipse.jetty.http.HttpStatus; import pta.de.api.ServiceDistributionCluster; import pta.de.api.VersionInfo; +import pta.de.core.common.Globals; +import pta.de.core.communication.RestServiceWrapper; import pta.de.core.exceptions.HttpStatusException; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; public class BackendController { + private static final Logger logger = Logger.getLogger(BackendController.class); + public ServiceDistributionCluster readServerDistribution(String cluster) throws HttpStatusException { ServiceDistributionCluster[] dcs = ServicesConfigCache.getInstance().getCache(); @@ -27,6 +33,44 @@ return vi; } + public String getServiceHealthState(String clustername, String servicename) throws HttpStatusException { + + ServiceDistributionCluster.ServiceDistribution dist = findDistribution(clustername, servicename); + RestServiceWrapper w = new RestServiceWrapper(false); + return w.performGetRequest(dist.getProtocol() + "://" + dist.getHost() + ":" + + dist.getPortHealth() + "/" + + Globals.HEALTH_CHECK_ADD_PATH); + } + + private ServiceDistributionCluster.ServiceDistribution findDistribution(String clustername, + String servicename) throws HttpStatusException { + ServiceDistributionCluster cluster = getCluster(ServicesConfigCache.getInstance().getCache(), clustername); + + Optional<ServiceDistributionCluster.ServiceDistribution> dist = Arrays.stream(cluster.getDistributions()) + .filter(e -> e.isActive() && e.getName().equals(servicename)) + .findFirst(); + + if(dist.isPresent()) { + return dist.get(); + } + else { + throw new HttpStatusException(HttpStatus.NOT_FOUND_404); + } + } + + private ServiceDistributionCluster getCluster(ServiceDistributionCluster[] clusterArray, String clustername) throws HttpStatusException { + List<ServiceDistributionCluster> clusterList = Arrays.asList(clusterArray); + Optional<ServiceDistributionCluster> ret = clusterList.stream() + .filter(c -> c.getClustername().equals(clustername)).findFirst(); + + if (ret.isPresent()) { + return ret.get(); + } else { + logger.info("Could not find a cluster with the name: " + clustername); + throw new HttpStatusException(HttpStatus.NOT_FOUND_404); + } + } + private ServiceDistributionCluster removeInactiveItems( ServiceDistributionCluster cluster ) { List<ServiceDistributionCluster.ServiceDistribution> dlist = Arrays.asList(cluster.getDistributions()); dlist = dlist.stream().filter(ServiceDistributionCluster.ServiceDistribution::isActive).collect(Collectors.toList());
diff --git a/src/main/java/pta/de/resources/MicsCentralResource.java b/src/main/java/pta/de/resources/MicsCentralResource.java index 284a4f4..15b4253 100644 --- a/src/main/java/pta/de/resources/MicsCentralResource.java +++ b/src/main/java/pta/de/resources/MicsCentralResource.java
@@ -29,6 +29,14 @@ } @GET + @Path("/serviceHealthState/{clustername}/{servicename}") + public Response getClusterHealthState(@PathParam("clustername") @NotEmpty String clustername, + @PathParam("servicename") @NotEmpty String servicename) { + return invokeRunnable(() -> new BackendController().getServiceHealthState(clustername, servicename)); + } + + + @GET @Path("/versionInfo") public Response getVersionInfo() { return invokeRunnable(() -> new BackendController().getVersionInfo(getVersionString()));