diff options
Diffstat (limited to 'oom-app-common/src/main/java/org/onap/oom/dashboard/rest')
4 files changed, 1055 insertions, 0 deletions
diff --git a/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientImpl.java b/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientImpl.java new file mode 100644 index 0000000..858ed5a --- /dev/null +++ b/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientImpl.java @@ -0,0 +1,425 @@ +/******************************************************************************* + * =============LICENSE_START========================================================= + * + * ================================================================================= + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + *******************************************************************************/ +package org.onap.oom.dashboard.rest; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.onap.oom.dashboard.model.CloudifyBlueprintContent; +import org.onap.oom.dashboard.model.CloudifyBlueprintList; +import org.onap.oom.dashboard.model.CloudifyBlueprintUpload; +import org.onap.oom.dashboard.model.CloudifyDeploymentList; +import org.onap.oom.dashboard.model.CloudifyDeploymentRequest; +import org.onap.oom.dashboard.model.CloudifyExecution; +import org.onap.oom.dashboard.model.CloudifyExecutionList; +import org.onap.oom.dashboard.model.CloudifyExecutionRequest; +import org.onap.oom.dashboard.model.ConsulDatacenter; +import org.onap.oom.dashboard.model.ConsulHealthServiceRegistration; +import org.onap.oom.dashboard.model.ConsulNodeInfo; +import org.onap.oom.dashboard.model.ConsulServiceHealth; +import org.onap.oom.dashboard.model.ConsulServiceHealthHistory; +import org.onap.oom.dashboard.model.ConsulServiceInfo; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Provides methods for accessing the ECOMP Controller API via REST. Most + * methods are just simple proxies. Only the methods that fetch one page of data + * have to do any real work. + * + * Implemented using Spring RestTemplate. Supports basic HTTP authentication. + * + */ +public class ControllerRestClientImpl implements IControllerRestClient { + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ControllerRestClientImpl.class); + + private final String baseUrl; + private final RestTemplate restTemplate; + private final ObjectMapper objectMapper = new ObjectMapper(); + + /** + * Builds a restTemplate. If username and password are supplied, uses basic + * HTTP authentication. + * + * @param webapiUrl + * URL of the web endpoint + * @param user + * user name; ignored if null + * @param pass + * password + */ + public ControllerRestClientImpl(String webapiUrl, String user, String pass) { + if (webapiUrl == null) + throw new IllegalArgumentException("Null URL not permitted"); + + URL url = null; + try { + url = new URL(webapiUrl); + baseUrl = url.toExternalForm(); + } catch (MalformedURLException ex) { + throw new RuntimeException("Failed to parse URL", ex); + } + final HttpHost httpHost = new HttpHost(url.getHost(), url.getPort()); + + // Build a client with a credentials provider + CloseableHttpClient httpClient = null; + if (user != null && pass != null) { + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(new AuthScope(httpHost), new UsernamePasswordCredentials(user, pass)); + httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(credsProvider).build(); + } else { + httpClient = HttpClientBuilder.create().build(); + } + // Create request factory + HttpComponentsClientHttpRequestFactoryBasicAuth requestFactory = new HttpComponentsClientHttpRequestFactoryBasicAuth( + httpHost); + requestFactory.setHttpClient(httpClient); + + // Put the factory in the template + this.restTemplate = new RestTemplate(); + restTemplate.setRequestFactory(requestFactory); + } + + /** + * Builds URL ensuring appropriate separators. The base comes from + * properties file so could have many problems. + * + * @param base + * @param suffix + * @param queryParams + * key-value pairs; i.e. must have an even number of entries. + * Ignored if null. + * @return + */ + private String buildUrl(final String[] path, final String[] queryParams) { + StringBuilder sb = new StringBuilder(path[0]); + for (int p = 1; p < path.length; ++p) { + if (!path[p - 1].endsWith("/") && !path[p].startsWith("/")) + sb.append('/'); + sb.append(path[p]); + } + if (queryParams != null && queryParams.length > 0) { + sb.append('?'); + int i = 0; + while (i < queryParams.length) { + if (i > 0) + sb.append('&'); + sb.append(queryParams[i]); + sb.append('='); + sb.append(queryParams[i + 1]); + i += 2; + } + } + return sb.toString(); + } + + @Override + public CloudifyBlueprintList getBlueprints() { + String url = buildUrl(new String[] { baseUrl, blueprintsPath }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "getBlueprints: url {}", url); + ResponseEntity<CloudifyBlueprintList> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<CloudifyBlueprintList>() { + }); + CloudifyBlueprintList result = response.getBody(); + return result; + } + + @Override + public CloudifyBlueprintList getBlueprint(final String id) { + String url = buildUrl(new String[] { baseUrl, blueprintsPath }, new String[] { "id", id }); + logger.debug(EELFLoggerDelegate.debugLogger, "getBlueprint: url {}", url); + ResponseEntity<CloudifyBlueprintList> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<CloudifyBlueprintList>() { + }); + CloudifyBlueprintList result = response.getBody(); + return result; + } + + @Override + public CloudifyBlueprintContent viewBlueprint(final String id) { + String url = buildUrl(new String[] { baseUrl, viewBlueprintsPath }, new String[] { "id", id }); + logger.debug(EELFLoggerDelegate.debugLogger, "viewBlueprint: url {}", url); + ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, null, String.class); + String yaml = response.getBody(); + CloudifyBlueprintContent result = new CloudifyBlueprintContent(id, yaml); + return result; + } + + @Override + public CloudifyBlueprintList uploadBlueprint(CloudifyBlueprintUpload blueprint) { + String url = buildUrl(new String[] { baseUrl, blueprintsPath }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "uploadBlueprint: url {}", url); + CloudifyBlueprintList result = restTemplate.postForObject(url, blueprint, CloudifyBlueprintList.class); + return result; + } + + @Override + public int deleteBlueprint(final String id) { + String url = buildUrl(new String[] { baseUrl, blueprintsPath, id }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "deleteBlueprint: url {}", url); + ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, null, + new ParameterizedTypeReference<String>() { + }); + return response.getStatusCode().value(); + } + + @Override + public CloudifyDeploymentList getDeployments() { + String url = buildUrl(new String[] { baseUrl, deploymentsPath }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "getDeployments: url {}", url); + ResponseEntity<CloudifyDeploymentList> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<CloudifyDeploymentList>() { + }); + CloudifyDeploymentList list = response.getBody(); + return list; + } + + @Override + public CloudifyDeploymentList getDeployment(final String id) { + String url = buildUrl(new String[] { baseUrl, deploymentsPath }, new String[] { "id", id }); + logger.debug(EELFLoggerDelegate.debugLogger, "getDeployment: url {}", url); + ResponseEntity<CloudifyDeploymentList> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<CloudifyDeploymentList>() { + }); + CloudifyDeploymentList list = response.getBody(); + return list; + } + + @Override + public CloudifyDeploymentList createDeployment(CloudifyDeploymentRequest deployment) { + String url = buildUrl(new String[] { baseUrl, deploymentsPath }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "createDeployment: url {}", url); + CloudifyDeploymentList result = restTemplate.postForObject(url, deployment, CloudifyDeploymentList.class); + return result; + } + + @Override + public int deleteDeployment(final String id, boolean ignoreLiveNodes) { + String url = buildUrl(new String[] { baseUrl, deploymentsPath, id }, + new String[] { "ignore_live_nodes", Boolean.toString(ignoreLiveNodes) }); + logger.debug(EELFLoggerDelegate.debugLogger, "deleteDeployment: url {}", url); + ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, null, + new ParameterizedTypeReference<String>() { + }); + return response.getStatusCode().value(); + } + + @Override + public CloudifyExecutionList getExecutions(final String deploymentId) { + String url = buildUrl(new String[] { baseUrl, executionsPath }, new String[] { "deployment_id", deploymentId }); + logger.debug(EELFLoggerDelegate.debugLogger, "getExecutions: url {}", url); + ResponseEntity<CloudifyExecutionList> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<CloudifyExecutionList>() { + }); + CloudifyExecutionList list = response.getBody(); + return list; + } + + @Override + public CloudifyExecutionList getExecution(String executionId, String deploymentId) { + String url = buildUrl(new String[] { baseUrl, executionsPath, executionId }, + new String[] { "deployment_id", deploymentId }); + logger.debug(EELFLoggerDelegate.debugLogger, "getExecution: url {}", url); + ResponseEntity<CloudifyExecutionList> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<CloudifyExecutionList>() { + }); + CloudifyExecutionList list = response.getBody(); + return list; + } + + @Override + public CloudifyExecution startExecution(CloudifyExecutionRequest execution) { + String url = buildUrl(new String[] { baseUrl, executionsPath }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "startExecution: url {}", url); + CloudifyExecution result = restTemplate.postForObject(url, execution, CloudifyExecution.class); + return result; + } + + @Override + public int cancelExecution(final String executionId, final String deploymentId, final String action) { + String url = buildUrl(new String[] { baseUrl, executionsPath, executionId }, + new String[] { "deployment_id", deploymentId, "action", action }); + logger.debug(EELFLoggerDelegate.debugLogger, "deleteExecution: url {}", url); + ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, null, + new ParameterizedTypeReference<String>() { + }); + return response.getStatusCode().value(); + } + + @Override + public URI registerService(ConsulHealthServiceRegistration registration) { + String url = buildUrl(new String[] { baseUrl, healthServicesPath, "register" }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "registerService: url {}", url); + URI uri = restTemplate.postForLocation(url, registration); + return uri; + } + + @Override + public int deregisterService(String serviceName) { + String url = buildUrl(new String[] { baseUrl, healthServicesPath, "deregister" , serviceName}, null); + logger.debug(EELFLoggerDelegate.debugLogger, "deregisterService: url {}", url); + ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, null, + new ParameterizedTypeReference<String>() { + }); + return response.getStatusCode().value(); + } + + /** + * Translates the awkward map of String-to-List of IP into a list of + * ConsulServiceInfo objects + */ + @SuppressWarnings("unchecked") + @Override + public List<ConsulServiceInfo> getServices() { + String url = buildUrl(new String[] { baseUrl, healthServicesPath, "services" }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "getServicesHealth: url {}", url); + ResponseEntity<Map<String, Object>> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<Map<String, Object>>() { + }); + Map<String, Object> serviceInfo = response.getBody(); + List<ConsulServiceInfo> list = new ArrayList<>(); + for (Map.Entry<String, Object> entry : serviceInfo.entrySet()) { + // Be defensive + List<String> addrs = null; + if (entry.getValue() instanceof List<?>) + addrs = (List<String>) entry.getValue(); + else + addrs = new ArrayList<>(); + list.add(new ConsulServiceInfo(entry.getKey(), addrs)); + } + return list; + } + + @Override + public List<ConsulServiceHealth> getServiceHealth(String serviceName) { + String url = buildUrl(new String[] { baseUrl, healthServicesPath, "services", serviceName }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "getServiceHealth: url {}", url); + ResponseEntity<List<ConsulServiceHealth>> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<List<ConsulServiceHealth>>() { + }); + List<ConsulServiceHealth> list = response.getBody(); + return list; + } + + @Override + public List<ConsulServiceHealthHistory> getServiceHealthHistory(String serviceName, Instant start, + Instant end) { + String url = buildUrl(new String[] { baseUrl, healthServicesPath, "svchist", serviceName }, + new String[] { "start", start.toString(), "end", end.toString() }); + logger.debug(EELFLoggerDelegate.debugLogger, "getServiceHealthHistory: url {}", url); + // Hack around an odd interface that returns non-JSON on error: + // "No health Data found for the selected dates or service" + ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<String>() { }); + if (response.getBody().startsWith("No health")) + throw new RuntimeException(response.getBody()); + List<ConsulServiceHealthHistory> result = null; + try { + TypeReference<List<ConsulServiceHealthHistory>> typeRef = new TypeReference<List<ConsulServiceHealthHistory>>() { }; + result = objectMapper.readValue(response.getBody(), typeRef); + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, "getServiceHealthHistory failed to parse response body", ex); + } + return result; + } + + @Override + public List<ConsulNodeInfo> getNodes() { + String url = buildUrl(new String[] { baseUrl, healthServicesPath, "nodes" }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "getNodesHealth: url {}", url); + ResponseEntity<List<ConsulNodeInfo>> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<List<ConsulNodeInfo>>() { + }); + List<ConsulNodeInfo> list = response.getBody(); + return list; + } + + @Override + public List<ConsulServiceHealth> getNodeServicesHealth(String nodeId) { + String url = buildUrl(new String[] { baseUrl, healthServicesPath, "nodes", nodeId }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "getNodeServicesHealth: url {}", url); + ResponseEntity<List<ConsulServiceHealth>> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<List<ConsulServiceHealth>>() { + }); + List<ConsulServiceHealth> list = response.getBody(); + return list; + } + + @Override + public List<ConsulDatacenter> getDatacenters() { + String url = buildUrl(new String[] { baseUrl, healthServicesPath, "datacenters" }, null); + logger.debug(EELFLoggerDelegate.debugLogger, "getDatacentersHealth: url {}", url); + ResponseEntity<List<String>> response = restTemplate.exchange(url, HttpMethod.GET, null, + new ParameterizedTypeReference<List<String>>() { + }); + List<String> list = response.getBody(); + List<ConsulDatacenter> result = new ArrayList<>(); + for (String dc : list) + result.add(new ConsulDatacenter(dc)); + return result; + } + + /** + * Simple test + * + * @param args + * blueprint ID + * @throws IllegalArgumentException + * On bad arguments + */ + public static void main(String[] args) throws IllegalArgumentException { + if (args.length != 1) + throw new IllegalArgumentException("Single argument expected: blueprint-id"); + ControllerRestClientImpl client = new ControllerRestClientImpl("http://localhost:8081/controller", "dbus_user", + "dbus_pass"); + final String id = args[0]; + System.out.println("Requesting blueprint for " + id); + CloudifyBlueprintList list = client.getBlueprint(id); + if (list == null) + System.err.println("Received null"); + else + for (int i = 0; i < list.items.size(); ++i) { + System.out.println("Blueprint " + Integer.toString(i)); + System.out.println(list.items.get(i).toString()); + } + } + +} diff --git a/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientMockImpl.java b/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientMockImpl.java new file mode 100644 index 0000000..217f878 --- /dev/null +++ b/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/ControllerRestClientMockImpl.java @@ -0,0 +1,311 @@ +/******************************************************************************* + * =============LICENSE_START========================================================= + * + * ================================================================================= + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + *******************************************************************************/ +package org.onap.oom.dashboard.rest; + +import java.io.InputStream; +import java.net.URI; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; + +import org.onap.oom.dashboard.exception.DashboardControllerException; +import org.onap.oom.dashboard.model.CloudifyBlueprintContent; +import org.onap.oom.dashboard.model.CloudifyBlueprintList; +import org.onap.oom.dashboard.model.CloudifyBlueprintUpload; +import org.onap.oom.dashboard.model.CloudifyDeploymentList; +import org.onap.oom.dashboard.model.CloudifyDeploymentRequest; +import org.onap.oom.dashboard.model.CloudifyExecution; +import org.onap.oom.dashboard.model.CloudifyExecutionList; +import org.onap.oom.dashboard.model.CloudifyExecutionRequest; +import org.onap.oom.dashboard.model.ConsulDatacenter; +import org.onap.oom.dashboard.model.ConsulHealthServiceRegistration; +import org.onap.oom.dashboard.model.ConsulNodeInfo; +import org.onap.oom.dashboard.model.ConsulServiceHealth; +import org.onap.oom.dashboard.model.ConsulServiceHealthHistory; +import org.onap.oom.dashboard.model.ConsulServiceInfo; +import org.onap.oom.dashboard.model.ECTransportModel; +import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Provides mock implementations that return contents of files on the classpath. + */ +public class ControllerRestClientMockImpl implements IControllerRestClient { + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ControllerRestClientMockImpl.class); + + /** + * For mock outputs + */ + private final ObjectMapper objectMapper = new ObjectMapper(); + + /** + * No-arg constructor + */ + public ControllerRestClientMockImpl() { + } + + private String getMockDataContent(final String path) { + String result = null; + try { + InputStream is = getClass().getResourceAsStream(path); + if (is == null) + throw new DashboardControllerException("Failed to find resource at path " + path); + Scanner scanner = new Scanner(is, "UTF-8"); + result = scanner.useDelimiter("\\A").next(); + scanner.close(); + is.close(); + } catch (Exception ex) { + logger.error("getMockDataContent failed", ex); + throw new RuntimeException(ex); + } + return result; + } + + /** + * Creates an input stream using the specified path and requests the mapper + * create an object of the specified type. + * + * @param modelClass + * Model class + * @param path + * Path to classpath resource + * @return Instance of modelClass + */ + private ECTransportModel getMockData(final Class<? extends ECTransportModel> modelClass, final String path) { + ECTransportModel result = null; + String json = getMockDataContent(path); + try { + result = (ECTransportModel) objectMapper.readValue(json, modelClass); + } catch (Exception ex) { + logger.error("getMockData failed", ex); + throw new RuntimeException(ex); + } + return result; + } + + @Override + public CloudifyBlueprintList getBlueprints() { + return (CloudifyBlueprintList) getMockData(CloudifyBlueprintList.class, "/blueprintList.json"); + } + + @Override + public CloudifyBlueprintList getBlueprint(final String id) { + return (CloudifyBlueprintList) getMockData(CloudifyBlueprintList.class, "/blueprintByID.json"); + } + + @Override + public CloudifyBlueprintContent viewBlueprint(final String id) { + String yaml = getMockDataContent("/blueprintContent.yaml"); + CloudifyBlueprintContent cbc = new CloudifyBlueprintContent(id, yaml); + return cbc; + } + + @Override + public CloudifyBlueprintList uploadBlueprint(CloudifyBlueprintUpload blueprint) { + logger.debug(EELFLoggerDelegate.debugLogger, "uploadBlueprint: {}", blueprint.toString()); + return new CloudifyBlueprintList(null, null); + } + + @Override + public int deleteBlueprint(final String id) { + logger.debug(EELFLoggerDelegate.debugLogger, "deleteBlueprint: {}", id); + return 204; + } + + @Override + public CloudifyDeploymentList getDeployments() { + return (CloudifyDeploymentList) getMockData(CloudifyDeploymentList.class, "/deploymentList.json"); + } + + @Override + public CloudifyDeploymentList getDeployment(final String id) { + return (CloudifyDeploymentList) getMockData(CloudifyDeploymentList.class, "/deploymentByID.json"); + } + + public CloudifyDeploymentList createDeployment(CloudifyDeploymentRequest deployment) { + logger.debug(EELFLoggerDelegate.debugLogger, "createDeployment: {}", deployment.toString()); + return new CloudifyDeploymentList(null, null); + } + + @Override + public int deleteDeployment(final String id, boolean ignoreLiveNodes) { + logger.debug(EELFLoggerDelegate.debugLogger, "deleteDeployment: id {}, ignoreLiveNodes", id, ignoreLiveNodes); + return 204; + } + + @Override + public CloudifyExecutionList getExecutions(final String deploymentId) { + return (CloudifyExecutionList) getMockData(CloudifyExecutionList.class, "/listExecutionForDeploymentID.json"); + } + + @Override + public CloudifyExecutionList getExecution(String executionId, String deploymentId) { + return (CloudifyExecutionList) getMockData(CloudifyExecutionList.class, "/listExecutionForDeploymentID.json"); + } + + @Override + public CloudifyExecution startExecution(CloudifyExecutionRequest execution) { + logger.debug(EELFLoggerDelegate.debugLogger, "startExecution: {}", execution.toString()); + return new CloudifyExecution(null, null, null, null, null, null, null, null, null); + } + + @Override + public int cancelExecution(String executionId, String deploymentId, String action) { + logger.debug(EELFLoggerDelegate.debugLogger, "deleteExecution: executionId {}, deploymentId {}, action {}", + executionId, deploymentId, action); + return 204; + } + + @Override + public URI registerService(ConsulHealthServiceRegistration registration) { + logger.debug(EELFLoggerDelegate.debugLogger, "registerService: {}", registration); + return null; + } + + @Override + public int deregisterService(String serviceName) { + logger.debug(EELFLoggerDelegate.debugLogger, "deregisterService: {}", serviceName); + return 200; + } + + @Override + public List<ConsulServiceHealth> getServiceHealth(String serviceName) { + logger.debug(EELFLoggerDelegate.debugLogger, "getServiceHealth: serviceName={}", serviceName); + String json = getMockDataContent("/serviceHealth.json"); + TypeReference<List<ConsulServiceHealth>> typeRef = new TypeReference<List<ConsulServiceHealth>>() { + }; + List<ConsulServiceHealth> result = null; + try { + result = objectMapper.readValue(json, typeRef); + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, "getServiceHealth failed", ex); + } + return result; + } + + @Override + public List<ConsulServiceHealthHistory> getServiceHealthHistory(String serviceName, Instant start, Instant end) { + logger.debug(EELFLoggerDelegate.debugLogger, "getServiceHealthHistory: serviceName={}", serviceName); + String json = getMockDataContent("/serviceHealthHistory.json"); + TypeReference<List<ConsulServiceHealthHistory>> typeRef = new TypeReference<List<ConsulServiceHealthHistory>>() { + }; + List<ConsulServiceHealthHistory> result = null; + try { + result = objectMapper.readValue(json, typeRef); + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, "getServiceHealthHistory failed", ex); + } + return result; + } + + @Override + public List<ConsulServiceHealth> getNodeServicesHealth(String nodeId) { + logger.debug(EELFLoggerDelegate.debugLogger, "getNodeServicesHealth: nodeId={}", nodeId); + String json = getMockDataContent("/nodeServicesHealth.json"); + TypeReference<List<ConsulServiceHealth>> typeRef = new TypeReference<List<ConsulServiceHealth>>() { + }; + List<ConsulServiceHealth> result = null; + try { + result = objectMapper.readValue(json, typeRef); + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, "getNodeServicesHealth failed", ex); + } + return result; + } + + @Override + public List<ConsulServiceInfo> getServices() { + logger.debug(EELFLoggerDelegate.debugLogger, "getServices"); + String json = getMockDataContent("/services.json"); + TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>() { + }; + HashMap<String, Object> map = null; + try { + map = objectMapper.readValue(json, typeRef); + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, "getNode failed", ex); + } + ArrayList<ConsulServiceInfo> result = new ArrayList<>(); + for (Map.Entry<String, Object> entry : map.entrySet()) { + final String service = entry.getKey(); + @SuppressWarnings("unchecked") + final List<String> addrs = (List<String>) entry.getValue(); + result.add(new ConsulServiceInfo(service, addrs)); + } + return result; + } + + @Override + public List<ConsulNodeInfo> getNodes() { + logger.debug(EELFLoggerDelegate.debugLogger, "getNodes"); + String json = getMockDataContent("/nodesHealth.json"); + TypeReference<List<ConsulNodeInfo>> typeRef = new TypeReference<List<ConsulNodeInfo>>() { + }; + List<ConsulNodeInfo> result = null; + try { + result = objectMapper.readValue(json, typeRef); + } catch (Exception ex) { + logger.error(EELFLoggerDelegate.errorLogger, "getNode failed", ex); + + } + return result; + } + + @Override + public List<ConsulDatacenter> getDatacenters() { + logger.debug(EELFLoggerDelegate.debugLogger, "getDatacentersHealth"); + return null; + } + + /** + * Simple test + * + * @param args + * blueprint ID + * @throws DashboardControllerException + * On any failure + */ + public static void main(String[] args) throws DashboardControllerException { + System.out.println("Testing paths and parsing mock data"); + ControllerRestClientMockImpl client = new ControllerRestClientMockImpl(); + CloudifyBlueprintList list1 = client.getBlueprints(); + CloudifyBlueprintList list2 = client.getBlueprint("mock"); + CloudifyDeploymentList list3 = client.getDeployments(); + CloudifyDeploymentList list4 = client.getDeployment("mock"); + CloudifyExecutionList list5 = client.getExecutions("mock"); + List<ConsulServiceInfo> list6 = client.getServices(); + List<ConsulNodeInfo> list7 = client.getNodes(); + List<ConsulServiceHealth> list8 = client.getServiceHealth("mock"); + List<ConsulServiceHealthHistory> list9 = client.getServiceHealthHistory("mock", Instant.now(), Instant.now()); + if (list1 == null || list2 == null || list3 == null || list4 == null || list5 == null || list6 == null + || list7 == null || list8 == null || list9 == null) + throw new DashboardControllerException("Failed"); + System.out.println("Pass."); + } + +} diff --git a/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/HttpComponentsClientHttpRequestFactoryBasicAuth.java b/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/HttpComponentsClientHttpRequestFactoryBasicAuth.java new file mode 100644 index 0000000..7ad1d46 --- /dev/null +++ b/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/HttpComponentsClientHttpRequestFactoryBasicAuth.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * =============LICENSE_START========================================================= + * + * ================================================================================= + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + *******************************************************************************/ +package org.onap.oom.dashboard.rest; + +import java.net.URI; + +import org.apache.http.HttpHost; +import org.apache.http.client.AuthCache; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.springframework.http.HttpMethod; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; + +/** + * Utility class to enable Basic HTTP Authentication with Spring REST templates. + * + * From: + * http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1/ + */ +public class HttpComponentsClientHttpRequestFactoryBasicAuth extends HttpComponentsClientHttpRequestFactory { + + private HttpHost host; + + /** + * @param host + * HttpHost + */ + public HttpComponentsClientHttpRequestFactoryBasicAuth(HttpHost host) { + super(); + this.host = host; + } + + protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) { + return createHttpContext(); + } + + private HttpContext createHttpContext() { + // Create AuthCache instance + AuthCache authCache = new BasicAuthCache(); + // Generate BASIC scheme object and add it to the local auth cache + BasicScheme basicAuth = new BasicScheme(); + authCache.put(host, basicAuth); + + // Add AuthCache to the execution context + BasicHttpContext localcontext = new BasicHttpContext(); + localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache); + return localcontext; + } +} diff --git a/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/IControllerRestClient.java b/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/IControllerRestClient.java new file mode 100644 index 0000000..a9b1a2d --- /dev/null +++ b/oom-app-common/src/main/java/org/onap/oom/dashboard/rest/IControllerRestClient.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * =============LICENSE_START========================================================= + * + * ================================================================================= + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + *******************************************************************************/ +package org.onap.oom.dashboard.rest; + +import java.net.URI; +import java.time.Instant; +import java.util.List; + +import org.onap.oom.dashboard.model.CloudifyBlueprintContent; +import org.onap.oom.dashboard.model.CloudifyBlueprintList; +import org.onap.oom.dashboard.model.CloudifyBlueprintUpload; +import org.onap.oom.dashboard.model.CloudifyDeploymentList; +import org.onap.oom.dashboard.model.CloudifyDeploymentRequest; +import org.onap.oom.dashboard.model.CloudifyExecution; +import org.onap.oom.dashboard.model.CloudifyExecutionList; +import org.onap.oom.dashboard.model.CloudifyExecutionRequest; +import org.onap.oom.dashboard.model.ConsulDatacenter; +import org.onap.oom.dashboard.model.ConsulHealthServiceRegistration; +import org.onap.oom.dashboard.model.ConsulNodeInfo; +import org.onap.oom.dashboard.model.ConsulServiceHealth; +import org.onap.oom.dashboard.model.ConsulServiceHealthHistory; +import org.onap.oom.dashboard.model.ConsulServiceInfo; + +/** + * Defines the interface of the Controller REST client. + */ +public interface IControllerRestClient { + + public static String blueprintsPath = "blueprints"; + public static String viewBlueprintsPath = "viewblueprints"; + public static String deploymentsPath = "deployments"; + public static String executionsPath = "executions"; + public static String healthServicesPath = "healthservices"; + + /** + * Gets the list of Cloudify blueprints. + * + * @return CloudifyBlueprintList + */ + public CloudifyBlueprintList getBlueprints(); + + /** + * Gets the Cloudify blueprint metadata for the specified ID + * + * @param id + * Blueprint ID + * @return CloudifyBlueprintList of size 1; null if not found + */ + public CloudifyBlueprintList getBlueprint(String id); + + /** + * Gets the Cloudify blueprint content for the specified ID + * + * @param id + * Blueprint ID + * @return Blueprint content + */ + public CloudifyBlueprintContent viewBlueprint(String id); + + /** + * Uploads a Cloudify blueprint. + * + * @param blueprint + * Cloudify Blueprint to upload + * @return CloudifyBlueprintList of size 1; null if not found + */ + public CloudifyBlueprintList uploadBlueprint(CloudifyBlueprintUpload blueprint); + + /** + * Deletes the Cloudify blueprint with the specified id. + * + * @param id + * Blueprint ID + * @return Status code; e.g., 200, 202, 204. + */ + public int deleteBlueprint(String id); + + /** + * Gets the list of Cloudify deployments. + * + * @return CloudifyDeploymentList + */ + public CloudifyDeploymentList getDeployments(); + + /** + * Gets the Cloudify deployment for the specified ID + * + * @param id + * Deployment ID + * @return CloudifyDeploymentList of size 1; null if not found. + */ + public CloudifyDeploymentList getDeployment(String id); + + /** + * Creates a Cloudify deployment. + * + * @param deployment + * Deployment details + * @return CloudifyDeploymentList of size 1 + */ + public CloudifyDeploymentList createDeployment(CloudifyDeploymentRequest deployment); + + /** + * Deletes the Cloudify deployment with the specified id. + * + * @param id + * Deployment ID + * @param ignoreLiveNodes + * Boolean indicator whether to delete even if live nodes exist + * @return Status code; e.g., 200, 202, 204. + */ + public int deleteDeployment(String id, boolean ignoreLiveNodes); + + /** + * Gets the Cloudify executions for the specified deployment ID + * + * @param deploymentId + * Deployment ID + * @return CloudifyExecutionList + */ + public CloudifyExecutionList getExecutions(String deploymentId); + + /** + * Gets the Cloudify execution for the specified execution ID and deployment + * ID + * + * @param executionId + * Execution ID + * @param deploymentId + * Deployment ID + * @return CloudifyExecutionList of size 1 + */ + public CloudifyExecutionList getExecution(String executionId, String deploymentId); + + /** + * Starts a Cloudify execution. + * + * @param execution + * Execution details + * @return CloudifyExecution + */ + public CloudifyExecution startExecution(CloudifyExecutionRequest execution); + + /** + * Deletes the Cloudify execution with the specified ids. + * + * @param executionId + * execution ID + * @param deploymentId + * Deployment ID + * @param action + * either "cancel" or "force-cancel" + * @return Status code; e.g., 200, 202, 204. + */ + public int cancelExecution(String executionId, String deploymentId, String action); + + /** + * Registers a service with Consul for health check. + * + * @param registration + * Details about the service to be registered. + * @return Result of registering a service + */ + public URI registerService(ConsulHealthServiceRegistration registration); + + /** + * Deregisters a service with Consul for health check. + * + * @param serviceName + * Name of the service to be deregistered. + * @return Response code + */ + public int deregisterService(String serviceName); + + /** + * Gets all the services that are monitored by Consul. + * + * @return List of ConsulServiceHealth + */ + public List<ConsulServiceInfo> getServices(); + + /** + * Gets the status for the specified service on all nodes. + * + * @param serviceName + * Service name + * @return List of ConsulServiceHealth + */ + public List<ConsulServiceHealth> getServiceHealth(String serviceName); + + /** + * Gets the status for the specified service on all nodes for the specified + * time window. + * + * @param serviceName + * Service name + * @param start + * Start (earliest point) of the time window + * @param end + * End (latest point) of the time window + * @return List of ConsulServiceHealth + */ + public List<ConsulServiceHealthHistory> getServiceHealthHistory(String serviceName, Instant start, Instant end); + + /** + * Gets all the nodes that are monitored by Consul. + * + * @return List of ConsulNodeHealth + */ + public List<ConsulNodeInfo> getNodes(); + + /** + * Gets the status for all registered services running on the specified + * node. + * + * @param nodeId + * Node ID + * @return List of ConsulServiceHealth + */ + public List<ConsulServiceHealth> getNodeServicesHealth(String nodeId); + + /** + * Gets all the data centers that are monitored by Consul. + * + * @return List of ConsulDatacenter objects + */ + public List<ConsulDatacenter> getDatacenters(); + +} |