diff options
Diffstat (limited to 'so-cnf-adapter-application')
27 files changed, 1490 insertions, 109 deletions
diff --git a/so-cnf-adapter-application/pom.xml b/so-cnf-adapter-application/pom.xml index 8a7b4b4..cd2d28e 100755 --- a/so-cnf-adapter-application/pom.xml +++ b/so-cnf-adapter-application/pom.xml @@ -96,6 +96,11 @@ </build> <dependencies> <dependency> + <groupId>org.onap.so</groupId> + <artifactId>aai-client</artifactId> + <version>1.9.0</version> + </dependency> + <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudClient.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudClient.java new file mode 100644 index 0000000..762f192 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudClient.java @@ -0,0 +1,143 @@ +package org.onap.so.adapters.cnf.client; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.onap.so.adapters.cnf.MulticloudConfiguration; +import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheck; +import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheckSimple; +import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceStatus; +import org.onap.so.client.exception.BadResponseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.ArrayList; +import java.util.List; + +import static org.springframework.http.HttpMethod.DELETE; +import static org.springframework.http.HttpMethod.GET; +import static org.springframework.http.HttpMethod.POST; + +@Component +public class MulticloudClient { + + private static final Logger log = LoggerFactory.getLogger(MulticloudClient.class); + + private final RestTemplate restTemplate; + private final MulticloudConfiguration multicloudConfiguration; + private final ObjectMapper objectMapper; + + public MulticloudClient(RestTemplate restTemplate, MulticloudConfiguration multicloudConfiguration) { + this.restTemplate = restTemplate; + this.multicloudConfiguration = multicloudConfiguration; + this.objectMapper = new ObjectMapper(); + } + + public K8sRbInstanceStatus getInstanceStatus(String instanceId) throws BadResponseException { + MulticloudApiUrl multicloudApiUrl = new MulticloudApiUrl(multicloudConfiguration); + multicloudApiUrl.setInstanceId(instanceId); + String endpoint = multicloudApiUrl.apiUrl() + "/status"; + ResponseEntity<String> result = restTemplate.exchange(endpoint, GET, getHttpEntity(), String.class); + checkResponseStatusCode(result); + log.info("getInstanceStatus response status: {}", result.getStatusCode()); + String body = result.getBody(); + log.debug("getInstanceStatus response body: {}", body); + + try { + return objectMapper.readValue(body, K8sRbInstanceStatus.class); + } catch (JsonProcessingException e) { + throw new IllegalStateException(e); + } + } + + public K8sRbInstanceHealthCheckSimple startInstanceHealthCheck(String instanceId) throws BadResponseException { + MulticloudApiUrl multicloudApiUrl = new MulticloudApiUrl(multicloudConfiguration); + multicloudApiUrl.setInstanceId(instanceId); + String endpoint = multicloudApiUrl.apiUrl() + "/healthcheck"; + ResponseEntity<String> result = restTemplate.exchange(endpoint, POST, getHttpEntity(), String.class); + checkResponseStatusCode(result); + log.info("startInstanceHealthCheck response status: {}", result.getStatusCode()); + String body = result.getBody(); + log.debug("startInstanceHealthCheck response body: {}", body); + + try { + return objectMapper.readValue(body, K8sRbInstanceHealthCheckSimple.class); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + public K8sRbInstanceHealthCheck getInstanceHealthCheck(String instanceId, String healthCheckInstance) throws BadResponseException { + MulticloudApiUrl multicloudApiUrl = new MulticloudApiUrl(multicloudConfiguration); + multicloudApiUrl.setInstanceId(instanceId); + String endpoint = multicloudApiUrl.apiUrl() + "/healthcheck/" + healthCheckInstance; + ResponseEntity<String> result = restTemplate.exchange(endpoint, GET, getHttpEntity(), String.class); + checkResponseStatusCode(result); + log.info("getInstanceHealthCheck response status: {}", result.getStatusCode()); + String body = result.getBody(); + log.debug("getInstanceHealthCheck response body: {}", body); + + try { + return objectMapper.readValue(body, K8sRbInstanceHealthCheck.class); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + public void deleteInstanceHealthCheck(String instanceId, String healthCheckInstance) throws BadResponseException { + MulticloudApiUrl multicloudApiUrl = new MulticloudApiUrl(multicloudConfiguration); + multicloudApiUrl.setInstanceId(instanceId); + String endpoint = multicloudApiUrl.apiUrl() + "/healthcheck/" + healthCheckInstance; + ResponseEntity<String> result = restTemplate.exchange(endpoint, DELETE, getHttpEntity(), String.class); + checkResponseStatusCode(result); + log.info("deleteInstanceHealthCheck response status: {}", result.getStatusCode()); + String body = result.getBody(); + log.debug("deleteInstanceHealthCheck response body: {}", body); + + if (!result.getStatusCode().is2xxSuccessful()) { + throw new IllegalStateException("Delete response different than 2xx:" + result.getStatusCode()); + } + } + + private HttpEntity<?> getHttpEntity() { + HttpHeaders headers = new HttpHeaders(); + List<MediaType> acceptableMediaTypes = new ArrayList<>(); + acceptableMediaTypes.add(MediaType.APPLICATION_JSON); + headers.setAccept(acceptableMediaTypes); + headers.setContentType(MediaType.APPLICATION_JSON); + + return new HttpEntity<>(headers); + } + + private void checkResponseStatusCode(ResponseEntity<String> result) throws BadResponseException { + HttpStatus statusCode = result.getStatusCode(); + if (!statusCode.is2xxSuccessful()) { + throw new BadResponseException("Multicloud response status error", String.valueOf(statusCode.value())); + } + } + + private class MulticloudApiUrl { + + private String instanceId; + private final MulticloudConfiguration multicloudConfiguration; + + MulticloudApiUrl(MulticloudConfiguration multicloudConfiguration1) { + this.multicloudConfiguration = multicloudConfiguration1; + } + + String apiUrl() { + String instanceUri = multicloudConfiguration.getMulticloudUrl() + "/v1/instance/"; + return instanceId.equals("") ? instanceUri : instanceUri + instanceId; + } + + void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/SoCallbackClient.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/SoCallbackClient.java new file mode 100644 index 0000000..f6e39e8 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/SoCallbackClient.java @@ -0,0 +1,41 @@ +package org.onap.so.adapters.cnf.client; + +import com.google.gson.Gson; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.util.ArrayList; +import java.util.List; + +import static org.springframework.http.HttpMethod.POST; + +@Component +public class SoCallbackClient { + + private final RestTemplate restTemplate; + private final static Gson gson = new Gson(); + + @Autowired + public SoCallbackClient(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + public ResponseEntity<String> sendPostCallback(String url, Object body) { + return restTemplate.exchange(url, POST, httpEntity(body), String.class); + } + + private HttpEntity<?> httpEntity(Object body) { + HttpHeaders headers = new HttpHeaders(); + List<MediaType> acceptableMediaTypes = new ArrayList<>(); + acceptableMediaTypes.add(MediaType.APPLICATION_JSON); + headers.setAccept(acceptableMediaTypes); + headers.setContentType(MediaType.APPLICATION_JSON); + + return new HttpEntity<>(gson.toJson(body), headers); + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/CheckInstanceRequest.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/CheckInstanceRequest.java new file mode 100644 index 0000000..ac8fe54 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/CheckInstanceRequest.java @@ -0,0 +1,42 @@ +package org.onap.so.adapters.cnf.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class CheckInstanceRequest { + + @JsonProperty("requestedInstances") + private List<InstanceRequest> instances; + + @JsonProperty("callbackUrl") + private String callbackUrl; + + public List<InstanceRequest> getInstances() { + return instances; + } + + public void setInstances(List<InstanceRequest> instances) { + this.instances = instances; + } + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callbackUrl) { + this.callbackUrl = callbackUrl; + } + + @Override + public String toString() { + return "CheckInstanceRequest{" + + "instances=" + instances + + ", callbackUrl='" + callbackUrl + '\'' + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/InstanceRequest.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/InstanceRequest.java new file mode 100644 index 0000000..da34b3a --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/InstanceRequest.java @@ -0,0 +1,28 @@ +package org.onap.so.adapters.cnf.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class InstanceRequest { + + @JsonProperty("instanceId") + private String instanceId; + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + @Override + public String toString() { + return "InstanceRequest{" + + "instanceId='" + instanceId + '\'' + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/aai/AaiCallbackResponse.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/aai/AaiCallbackResponse.java new file mode 100644 index 0000000..65e79ac --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/aai/AaiCallbackResponse.java @@ -0,0 +1,44 @@ +package org.onap.so.adapters.cnf.model.aai; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class AaiCallbackResponse { + + @JsonProperty("status") + private CompletionStatus completionStatus; + + @JsonProperty("statusMessage") + private String message; + + public CompletionStatus getCompletionStatus() { + return completionStatus; + } + + public void setCompletionStatus(CompletionStatus completionStatus) { + this.completionStatus = completionStatus; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return "AaiCallbackResponse{" + + "completionStatus=" + completionStatus + + ", message='" + message + '\'' + + '}'; + } + + public enum CompletionStatus { + COMPLETED, FAILED + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/HealthCheckInstance.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/HealthCheckInstance.java new file mode 100644 index 0000000..df87768 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/HealthCheckInstance.java @@ -0,0 +1,27 @@ +package org.onap.so.adapters.cnf.model.healthcheck; + +public class HealthCheckInstance { + private final String instanceId; + private final String healthCheckInstance; + + public HealthCheckInstance(String instanceId, String healthCheckInstance) { + this.instanceId = instanceId; + this.healthCheckInstance = healthCheckInstance; + } + + public String getInstanceId() { + return instanceId; + } + + public String getHealthCheckInstance() { + return healthCheckInstance; + } + + @Override + public String toString() { + return "HealthCheckInstance{" + + "instanceId='" + instanceId + '\'' + + ", healthCheckInstance='" + healthCheckInstance + '\'' + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/HealthCheckInstanceResponse.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/HealthCheckInstanceResponse.java new file mode 100644 index 0000000..7811fe1 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/HealthCheckInstanceResponse.java @@ -0,0 +1,60 @@ +package org.onap.so.adapters.cnf.model.healthcheck; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class HealthCheckInstanceResponse { + + @JsonProperty("instanceId") + private String instanceId; + + @JsonProperty("reason") + private String reason; + + @JsonProperty("status") + private String status; + + public HealthCheckInstanceResponse() { } + + public HealthCheckInstanceResponse(String instanceId, String reason, String status) { + this.instanceId = instanceId; + this.reason = reason; + this.status = status; + } + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @Override + public String toString() { + return "StatusCheckInstanceResponse{" + + "instanceId='" + instanceId + '\'' + + ", reason='" + reason + '\'' + + ", status=" + status + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/HealthCheckResponse.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/HealthCheckResponse.java new file mode 100644 index 0000000..2d0bb88 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/HealthCheckResponse.java @@ -0,0 +1,42 @@ +package org.onap.so.adapters.cnf.model.healthcheck; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class HealthCheckResponse { + + @JsonProperty("result") + private List<HealthCheckInstanceResponse> instanceResponse; + + @JsonProperty("error") + private String errorMessage; + + public List<HealthCheckInstanceResponse> getInstanceResponse() { + return instanceResponse; + } + + public void setInstanceResponse(List<HealthCheckInstanceResponse> instanceResponse) { + this.instanceResponse = instanceResponse; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + @Override + public String toString() { + return "HealthCheckResponse{" + + "instanceResponse=" + instanceResponse + + ", errorMessage='" + errorMessage + '\'' + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/K8sRbInstanceHealthCheck.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/K8sRbInstanceHealthCheck.java new file mode 100644 index 0000000..bab6a5a --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/K8sRbInstanceHealthCheck.java @@ -0,0 +1,28 @@ +package org.onap.so.adapters.cnf.model.healthcheck; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class K8sRbInstanceHealthCheck { + + @JsonProperty("status") + private String status; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @Override + public String toString() { + return "K8sRbInstanceHealthCheck{" + + "status='" + status + '\'' + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/K8sRbInstanceHealthCheckSimple.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/K8sRbInstanceHealthCheckSimple.java new file mode 100644 index 0000000..8a2590d --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/healthcheck/K8sRbInstanceHealthCheckSimple.java @@ -0,0 +1,37 @@ +package org.onap.so.adapters.cnf.model.healthcheck; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class K8sRbInstanceHealthCheckSimple { + + @JsonProperty("healthcheck-id") + private String id; + + @JsonProperty("status") + private String status; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @Override + public String toString() { + return "K8sRbInstanceHealthCheckSimple{" + + "id='" + id + '\'' + + ", status='" + status + '\'' + + '}'; + } + +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/instantiation/AaiRequest.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/instantiation/AaiRequest.java new file mode 100644 index 0000000..0665d9a --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/instantiation/AaiRequest.java @@ -0,0 +1,72 @@ +package org.onap.so.adapters.cnf.model.instantiation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class AaiRequest { + + @JsonProperty("instanceId") + private String instanceId; + @JsonProperty("cloudRegion") + private String cloudRegion; + @JsonProperty("cloudOwner") + private String cloudOwner; + @JsonProperty("tenantId") + private String tenantId; + @JsonProperty("callbackUrl") + private String callbackUrl; + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + public String getCloudRegion() { + return cloudRegion; + } + + public void setCloudRegion(String cloudRegion) { + this.cloudRegion = cloudRegion; + } + + public String getCloudOwner() { + return cloudOwner; + } + + public void setCloudOwner(String cloudOwner) { + this.cloudOwner = cloudOwner; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callbackUrl) { + this.callbackUrl = callbackUrl; + } + + @Override + public String toString() { + return "AaiRequest{" + + "instanceId='" + instanceId + '\'' + + ", cloudRegion='" + cloudRegion + '\'' + + ", cloudOwner='" + cloudOwner + '\'' + + ", tenantId='" + tenantId + '\'' + + ", callbackUrl='" + callbackUrl + '\'' + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceGvk.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceGvk.java new file mode 100644 index 0000000..fee6496 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceGvk.java @@ -0,0 +1,43 @@ +package org.onap.so.adapters.cnf.model.statuscheck; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class K8sRbInstanceGvk { + + @JsonProperty("Group") + private String group; + + @JsonProperty("Kind") + private String kind; + + @JsonProperty("Version") + private String version; + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + public String getKind() { + return kind; + } + + public void setKind(String kind) { + this.kind = kind; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceResourceStatus.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceResourceStatus.java new file mode 100644 index 0000000..fe11b03 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceResourceStatus.java @@ -0,0 +1,47 @@ +package org.onap.so.adapters.cnf.model.statuscheck; + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class K8sRbInstanceResourceStatus { + + @JsonProperty("name") + private String name; + + @JsonProperty("GVK") + private K8sRbInstanceGvk gvk; + + @JsonProperty("status") + private K8sStatus status; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public K8sRbInstanceGvk getGvk() { + return gvk; + } + + public void setGvk(K8sRbInstanceGvk gvk) { + this.gvk = gvk; + } + + public K8sStatus getStatus() { + return status; + } + + public void setStatus(K8sStatus status) { + this.status = status; + } + +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceStatus.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceStatus.java new file mode 100644 index 0000000..f8680af --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceStatus.java @@ -0,0 +1,67 @@ +package org.onap.so.adapters.cnf.model.statuscheck; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest; + +import java.util.List; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class K8sRbInstanceStatus { + + @JsonProperty("request") + private MulticloudInstanceRequest request; + + @JsonProperty("resourceCount") + private int resourceCount; + + @JsonProperty("ready") + private boolean ready; + + @JsonProperty("resourcesStatus") + private List<K8sRbInstanceResourceStatus> resourcesStatus; + + public MulticloudInstanceRequest getRequest() { + return request; + } + + public void setRequest(MulticloudInstanceRequest request) { + this.request = request; + } + + public int getResourceCount() { + return resourceCount; + } + + public void setResourceCount(int resourceCount) { + this.resourceCount = resourceCount; + } + + public boolean isReady() { + return ready; + } + + public void setReady(boolean ready) { + this.ready = ready; + } + + public List<K8sRbInstanceResourceStatus> getResourcesStatus() { + return resourcesStatus; + } + + public void setResourcesStatus(List<K8sRbInstanceResourceStatus> resourcesStatus) { + this.resourcesStatus = resourcesStatus; + } + + @Override + public String toString() { + return "K8sRbInstanceStatus{" + + "request=" + request + + ", resourceCount=" + resourceCount + + ", ready=" + ready + + ", resourcesStatus=" + resourcesStatus + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sStatus.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sStatus.java new file mode 100644 index 0000000..5fe4e30 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sStatus.java @@ -0,0 +1,26 @@ +package org.onap.so.adapters.cnf.model.statuscheck; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties +public class K8sStatus { + + @JsonProperty("metadata") + private K8sStatusMetadata k8sStatusMetadata; + + public K8sStatusMetadata getK8sStatusMetadata() { + return k8sStatusMetadata; + } + + public void setK8sStatusMetadata(K8sStatusMetadata k8sStatusMetadata) { + this.k8sStatusMetadata = k8sStatusMetadata; + } + + @Override + public String toString() { + return "K8sStatus{" + + "k8sStatusMetadata=" + k8sStatusMetadata + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sStatusMetadata.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sStatusMetadata.java new file mode 100644 index 0000000..a69f7e7 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sStatusMetadata.java @@ -0,0 +1,40 @@ +package org.onap.so.adapters.cnf.model.statuscheck; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Map; + +@JsonIgnoreProperties +public class K8sStatusMetadata { + + @JsonProperty("metadata") + private String namespace; + + @JsonProperty("metadata") + private Map<String, String> labels; + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public Map<String, String> getLabels() { + return labels; + } + + public void setLabels(Map<String, String> labels) { + this.labels = labels; + } + + @Override + public String toString() { + return "K8sStatusMetadata{" + + "namespace='" + namespace + '\'' + + ", labels=" + labels + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/StatusCheckInstanceResponse.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/StatusCheckInstanceResponse.java new file mode 100644 index 0000000..fc5da9b --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/StatusCheckInstanceResponse.java @@ -0,0 +1,60 @@ +package org.onap.so.adapters.cnf.model.statuscheck; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class StatusCheckInstanceResponse { + + @JsonProperty("instanceId") + private String instanceId; + + @JsonProperty("reason") + private String reason; + + @JsonProperty("status") + private boolean status; + + public StatusCheckInstanceResponse() { } + + public StatusCheckInstanceResponse(String instanceId, String reason, boolean status) { + this.instanceId = instanceId; + this.reason = reason; + this.status = status; + } + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public boolean isStatus() { + return status; + } + + public void setStatus(boolean status) { + this.status = status; + } + + @Override + public String toString() { + return "StatusCheckInstanceResponse{" + + "instanceId='" + instanceId + '\'' + + ", reason='" + reason + '\'' + + ", status=" + status + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/StatusCheckResponse.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/StatusCheckResponse.java new file mode 100644 index 0000000..5fdf762 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/StatusCheckResponse.java @@ -0,0 +1,42 @@ +package org.onap.so.adapters.cnf.model.statuscheck; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(value = "true") +public class StatusCheckResponse { + + @JsonProperty("result") + private List<StatusCheckInstanceResponse> instanceResponse; + + @JsonProperty("error") + private String errorMessage; + + public List<StatusCheckInstanceResponse> getInstanceResponse() { + return instanceResponse; + } + + public void setInstanceResponse(List<StatusCheckInstanceResponse> instanceResponse) { + this.instanceResponse = instanceResponse; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + @Override + public String toString() { + return "StatusCheckResponse{" + + "instanceResponse=" + instanceResponse + + ", errorMessage='" + errorMessage + '\'' + + '}'; + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java index 2036f46..488b384 100644 --- a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java @@ -20,8 +20,10 @@ package org.onap.so.adapters.cnf.rest; -import java.io.File; -import java.io.IOException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpDelete; @@ -37,7 +39,9 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.onap.so.adapters.cnf.MulticloudConfiguration; +import org.onap.so.adapters.cnf.client.SoCallbackClient; import org.onap.so.adapters.cnf.model.BpmnInstanceRequest; +import org.onap.so.adapters.cnf.model.CheckInstanceRequest; import org.onap.so.adapters.cnf.model.ConfigTemplateEntity; import org.onap.so.adapters.cnf.model.ConfigurationEntity; import org.onap.so.adapters.cnf.model.ConfigurationRollbackEntity; @@ -45,10 +49,18 @@ import org.onap.so.adapters.cnf.model.ConnectivityInfo; import org.onap.so.adapters.cnf.model.ProfileEntity; import org.onap.so.adapters.cnf.model.ResourceBundleEntity; import org.onap.so.adapters.cnf.model.Tag; +import org.onap.so.adapters.cnf.model.aai.AaiCallbackResponse; +import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckResponse; +import org.onap.so.adapters.cnf.model.instantiation.AaiRequest; +import org.onap.so.adapters.cnf.model.statuscheck.StatusCheckResponse; import org.onap.so.adapters.cnf.service.CnfAdapterService; +import org.onap.so.adapters.cnf.service.aai.AaiService; +import org.onap.so.adapters.cnf.service.statuscheck.SimpleStatusCheckService; +import org.onap.so.client.exception.BadResponseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -56,34 +68,125 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.multipart.MultipartFile; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ForkJoinPool; @RestController public class CnfAdapterRest { private static final Logger logger = LoggerFactory.getLogger(CnfAdapterRest.class); private final CloseableHttpClient httpClient = HttpClients.createDefault(); + private final SimpleStatusCheckService simpleStatusCheckService; private final CnfAdapterService cnfAdapterService; + private final SoCallbackClient callbackClient; + private final AaiService aaiService; private final String uri; @Autowired - public CnfAdapterRest(CnfAdapterService cnfAdapterService, MulticloudConfiguration multicloudConfiguration) { + public CnfAdapterRest(SimpleStatusCheckService simpleStatusCheckService, + CnfAdapterService cnfAdapterService, + SoCallbackClient callbackClient, + AaiService aaiService, + MulticloudConfiguration multicloudConfiguration) { + this.simpleStatusCheckService = simpleStatusCheckService; this.cnfAdapterService = cnfAdapterService; + this.aaiService = aaiService; + this.callbackClient = callbackClient; this.uri = multicloudConfiguration.getMulticloudUrl(); } @ResponseBody - @RequestMapping(value = {"/api/cnf-adapter/v1/healthcheck"}, method = RequestMethod.GET, + @RequestMapping(value = {"/api/cnf-adapter/v1/healthcheck"}, method = RequestMethod.POST, produces = "application/json") - public String healthCheck() throws Exception { - + public DeferredResult<ResponseEntity> healthCheck(@RequestBody CheckInstanceRequest healthCheckRequest) { logger.info("healthCheck called."); - return cnfAdapterService.healthCheck(); + DeferredResult<ResponseEntity> response = new DeferredResult<>(); + + ForkJoinPool.commonPool().submit(() -> { + logger.info("Processing healthCheck service"); + HealthCheckResponse healthCheckResponse = null; + try { + healthCheckResponse = cnfAdapterService.healthCheck(healthCheckRequest); + } catch (Exception e) { + HealthCheckResponse errorHealthCheck = new HealthCheckResponse(); + errorHealthCheck.setErrorMessage(e.getMessage()); + callbackClient.sendPostCallback(healthCheckRequest.getCallbackUrl(), errorHealthCheck); + return; + } + callbackClient.sendPostCallback(healthCheckRequest.getCallbackUrl(), healthCheckResponse); + }); + + response.setResult(ResponseEntity.accepted().build()); + return response; + } + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/aai-update/"}, method = RequestMethod.POST, + produces = "application/json") + public DeferredResult<ResponseEntity> aaiUpdate(@RequestBody AaiRequest aaiRequest) { + logger.info("aai-update called."); + DeferredResult<ResponseEntity> response = new DeferredResult<>(); + + ForkJoinPool.commonPool().submit(() -> { + logger.info("Processing aai update"); +// aaiService.aaiUpdate(aaiRequest); + AaiCallbackResponse mockCallbackResponse = new AaiCallbackResponse(); + mockCallbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.COMPLETED); + callbackClient.sendPostCallback(aaiRequest.getCallbackUrl(), mockCallbackResponse); + return response; + }); + + response.setResult(ResponseEntity.accepted().build()); + return response; + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/aai-delete/"}, method = RequestMethod.POST, + produces = "application/json") + public DeferredResult<ResponseEntity> aaiDelete(@RequestBody AaiRequest aaiRequest) { + logger.info("aai-delete called."); + DeferredResult<ResponseEntity> response = new DeferredResult<>(); + + ForkJoinPool.commonPool().submit(() -> { + logger.info("Processing aai delete"); +// aaiService.aaiDelete(aaiRequest); + AaiCallbackResponse mockCallbackResponse = new AaiCallbackResponse(); + mockCallbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.COMPLETED); + callbackClient.sendPostCallback(aaiRequest.getCallbackUrl(), mockCallbackResponse); + return response; + }); + + response.setResult(ResponseEntity.accepted().build()); + return response; + } + + @ResponseBody + @RequestMapping(value = {"/api/cnf-adapter/v1/statuscheck"}, method = RequestMethod.POST, + produces = "application/json") + public DeferredResult<ResponseEntity> statusCheck(@RequestBody CheckInstanceRequest statusCheckRequest) { + logger.info("statusCheck called."); + DeferredResult<ResponseEntity> response = new DeferredResult<>(); + + ForkJoinPool.commonPool().submit(() -> { + logger.info("Processing healthCheck service"); + StatusCheckResponse statusCheckResponse = null; + try { + statusCheckResponse = simpleStatusCheckService.statusCheck(statusCheckRequest); + } catch (BadResponseException e) { + StatusCheckResponse errorStatusCheck = new StatusCheckResponse(); + errorStatusCheck.setErrorMessage(e.getMessage()); + callbackClient.sendPostCallback(statusCheckRequest.getCallbackUrl(), e); + return; + } + callbackClient.sendPostCallback(statusCheckRequest.getCallbackUrl(), statusCheckResponse); + }); + + response.setResult(ResponseEntity.accepted().build()); + return response; } @ResponseBody @@ -161,7 +264,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost(uri +"/v1/rb/definition"); + HttpPost post = new HttpPost(uri + "/v1/rb/definition"); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); String requestBody = objectMapper.writeValueAsString(rB); @@ -169,7 +272,7 @@ public class CnfAdapterRest { post.setEntity(requestEntity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -185,7 +288,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet(uri +"/v1/rb/definition/" + rbName + "/" + rbVersion); + HttpGet req = new HttpGet(uri + "/v1/rb/definition/" + rbName + "/" + rbVersion); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); @@ -202,7 +305,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpDelete req = new HttpDelete(uri +"/v1/rb/definition/" + rbName + "/" + rbVersion); + HttpDelete req = new HttpDelete(uri + "/v1/rb/definition/" + rbName + "/" + rbVersion); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -220,7 +323,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet(uri +"/v1/rb/definition/" + rbName); + HttpGet req = new HttpGet(uri + "/v1/rb/definition/" + rbName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -238,7 +341,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet(uri +"/v1/rb/definition"); + HttpGet req = new HttpGet(uri + "/v1/rb/definition"); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -251,7 +354,7 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/content"}, method = RequestMethod.POST, produces = "multipart/form-data") public String uploadArtifactForRB(@RequestParam("file") MultipartFile file, @PathVariable("rb-name") String rbName, - @PathVariable("rb-version") String rbVersion) throws Exception { + @PathVariable("rb-version") String rbVersion) throws Exception { logger.info("Upload Artifact For RB called."); @@ -266,13 +369,13 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. HttpPost post = - new HttpPost(uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + "/content"); + new HttpPost(uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/content"); post.setHeader("Content-Type", "multipart/form-data"); logger.info(String.valueOf(post)); post.setEntity(entity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -282,21 +385,21 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/profile"}, method = RequestMethod.POST, produces = "application/json") public String createProfile(@RequestBody ProfileEntity fE, @PathVariable("rb-name") String rbName, - @PathVariable("rb-version") String rbVersion) throws Exception { + @PathVariable("rb-version") String rbVersion) throws Exception { logger.info("create Profile called."); // TODO // Below URL should be changed as appropriate multicloud URL. HttpPost post = - new HttpPost(uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile"); + new HttpPost(uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile"); ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(fE); StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); post.setEntity(requestEntity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -306,14 +409,14 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/profile/{pr-name}"}, method = RequestMethod.GET, produces = "application/json") public String getProfile(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, - @PathVariable("pr-name") String prName) throws Exception { + @PathVariable("pr-name") String prName) throws Exception { logger.info("get Profile called."); // TODO // Below URL should be changed as appropriate multicloud URL. HttpGet req = new HttpGet( - uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile/" + prName); + uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile/" + prName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -332,7 +435,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. HttpGet req = - new HttpGet(uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile"); + new HttpGet(uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile"); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -344,14 +447,14 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/profile/{pr-name}"}, method = RequestMethod.DELETE, produces = "application/json") public String deleteProfile(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, - @PathVariable("pr-name") String prName) throws Exception { + @PathVariable("pr-name") String prName) throws Exception { logger.info("delete Profile called."); // TODO // Below URL should be changed as appropriate multicloud URL. HttpDelete req = new HttpDelete( - uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile/" + prName); + uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile/" + prName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -364,8 +467,8 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/profile/{pr-name}/content"}, method = RequestMethod.POST, produces = "multipart/form-data") public String uploadArtifactForProfile(@RequestParam("file") MultipartFile file, - @PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, - @PathVariable("pr-name") String prName) throws Exception { + @PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, + @PathVariable("pr-name") String prName) throws Exception { logger.info("Upload Artifact For Profile called."); @@ -379,7 +482,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost(uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + HttpPost post = new HttpPost(uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/profile/" + prName + "/content"); post.setHeader("Content-Type", "multipart/form-data"); @@ -387,7 +490,7 @@ public class CnfAdapterRest { post.setEntity(entity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -397,14 +500,14 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config"}, method = RequestMethod.POST, produces = "application/json") public String createConfiguration(@RequestBody ConfigurationEntity cE, @PathVariable("rb-name") String rbName, - @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName) + @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName) throws Exception { logger.info("create Configuration called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost(uri +"/v1/definition/" + rbName + "/" + rbVersion + HttpPost post = new HttpPost(uri + "/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + prName + "/config"); ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(cE); @@ -412,7 +515,7 @@ public class CnfAdapterRest { post.setEntity(requestEntity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -423,13 +526,13 @@ public class CnfAdapterRest { value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config/{cfg-name}"}, method = RequestMethod.GET, produces = "application/json") public String getConfiguration(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, - @PathVariable("profile-name") String prName, @PathVariable("cfg-name") String cfgName) throws Exception { + @PathVariable("profile-name") String prName, @PathVariable("cfg-name") String cfgName) throws Exception { logger.info("get Configuration called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet(uri +"/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + HttpGet req = new HttpGet(uri + "/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + prName + "/config/" + cfgName); try (CloseableHttpResponse response = httpClient.execute(req)) { @@ -443,14 +546,14 @@ public class CnfAdapterRest { value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config/{cfg-name}"}, method = RequestMethod.DELETE, produces = "application/json") public String deleteConfiguration(@PathVariable("rb-name") String rbName, - @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName, - @PathVariable("cfg-name") String cfgName) throws Exception { + @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName, + @PathVariable("cfg-name") String cfgName) throws Exception { logger.info("delete Configuration called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpDelete req = new HttpDelete(uri +"/v1/definition/" + rbName + "/" + rbVersion + HttpDelete req = new HttpDelete(uri + "/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + prName + "/config/" + cfgName); try (CloseableHttpResponse response = httpClient.execute(req)) { @@ -465,14 +568,14 @@ public class CnfAdapterRest { value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/config/{cfg-name}"}, method = RequestMethod.PUT, produces = "application/json") public String updateConfiguration(@RequestBody ConfigurationEntity cE, @PathVariable("rb-name") String rbName, - @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName, - @PathVariable("cfg-name") String cfgName) throws Exception { + @PathVariable("rb-version") String rbVersion, @PathVariable("profile-name") String prName, + @PathVariable("cfg-name") String cfgName) throws Exception { logger.info("update Configuration called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPut post = new HttpPut(uri +"/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + HttpPut post = new HttpPut(uri + "/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + prName + "/config/" + cfgName); ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(cE); @@ -480,7 +583,7 @@ public class CnfAdapterRest { post.setEntity(requestEntity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -490,12 +593,12 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/definition/{rb-name}/{rb-version}/profile/{profile-name}/tagit"}, method = RequestMethod.POST, produces = "application/json") public String tagConfigurationValue(@RequestBody Tag tag, @PathVariable("rb-name") String rbName, - @PathVariable("rb-version") String rbVersion, @PathVariable("pr-name") String prName) throws Exception { + @PathVariable("rb-version") String rbVersion, @PathVariable("pr-name") String prName) throws Exception { logger.info("Tag Configuration called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost(uri +"/v1/definition/" + rbName + "/" + rbVersion + HttpPost post = new HttpPost(uri + "/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + prName + "/config/tagit"); ObjectMapper objectMapper = new ObjectMapper(); @@ -504,7 +607,7 @@ public class CnfAdapterRest { post.setEntity(requestEntity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -519,14 +622,14 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost(uri +"/v1/connectivity-info"); + HttpPost post = new HttpPost(uri + "/v1/connectivity-info"); ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(cIE); StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); post.setEntity(requestEntity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -541,7 +644,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet(uri +"/v1/connectivity-info/" + connName); + HttpGet req = new HttpGet(uri + "/v1/connectivity-info/" + connName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -558,7 +661,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpDelete req = new HttpDelete(uri +"/v1/connectivity-info/" + connName); + HttpDelete req = new HttpDelete(uri + "/v1/connectivity-info/" + connName); try (CloseableHttpResponse response = httpClient.execute(req)) { logger.info("response:" + response.getEntity()); @@ -571,21 +674,21 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/config-template"}, method = RequestMethod.POST, produces = "application/json") public String createConfigTemplate(@RequestBody ConfigTemplateEntity tE, @PathVariable("rb-name") String rbName, - @PathVariable("rb-version") String rbVersion) throws Exception { + @PathVariable("rb-version") String rbVersion) throws Exception { logger.info("createConfigTemplate called."); // TODO // Below URL should be changed as appropriate multicloud URL. HttpPost post = new HttpPost( - uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + "/config-template"); + uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/config-template"); ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(tE); StringEntity requestEntity = new StringEntity(requestBody, ContentType.APPLICATION_JSON); post.setEntity(requestEntity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -595,13 +698,13 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/config-template/{tname}"}, method = RequestMethod.GET, produces = "application/json") public String getConfigTemplate(@PathVariable("rb-name") String rbName, - @PathVariable("rb-version") String rbVersion, @PathVariable("tname") String tName) throws Exception { + @PathVariable("rb-version") String rbVersion, @PathVariable("tname") String tName) throws Exception { logger.info("getConfigTemplate called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpGet req = new HttpGet(uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + HttpGet req = new HttpGet(uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/config-template/" + tName); try (CloseableHttpResponse response = httpClient.execute(req)) { @@ -614,13 +717,13 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/config-template/{tname}"}, method = RequestMethod.DELETE, produces = "application/json") public String deleteTemplate(@PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, - @PathVariable("tname") String tName) throws Exception { + @PathVariable("tname") String tName) throws Exception { logger.info("deleteTemplate called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpDelete req = new HttpDelete(uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + HttpDelete req = new HttpDelete(uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/config-template/" + tName); try (CloseableHttpResponse response = httpClient.execute(req)) { @@ -635,8 +738,8 @@ public class CnfAdapterRest { value = {"/api/cnf-adapter/v1/rb/definition/{rb-name}/{rb-version}/config-template/{tname}/content"}, method = RequestMethod.POST, produces = "multipart/form-data") public String uploadTarFileForTemplate(@RequestParam("file") MultipartFile file, - @PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, - @PathVariable("tname") String tName) throws Exception { + @PathVariable("rb-name") String rbName, @PathVariable("rb-version") String rbVersion, + @PathVariable("tname") String tName) throws Exception { logger.info("uploadTarFileForTemplate called."); @@ -650,7 +753,7 @@ public class CnfAdapterRest { // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost(uri +"/v1/rb/definition/" + rbName + "/" + rbVersion + HttpPost post = new HttpPost(uri + "/v1/rb/definition/" + rbName + "/" + rbVersion + "/config-template/" + tName + "/content"); post.setHeader("Content-Type", "multipart/form-data"); @@ -658,7 +761,7 @@ public class CnfAdapterRest { post.setEntity(entity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } @@ -668,13 +771,13 @@ public class CnfAdapterRest { @RequestMapping(value = {"/api/cnf-adapter/v1/definition/{rbName}/{rbVersion}/profile/{prName}/config/rollback"}, method = RequestMethod.DELETE, produces = "application/json") public String rollbackConfiguration(@RequestBody ConfigurationRollbackEntity rE, - @PathVariable("rbName") String rbName, @PathVariable("rbVersion") String rbVersion, - @PathVariable("prName") String prName) throws Exception { + @PathVariable("rbName") String rbName, @PathVariable("rbVersion") String rbVersion, + @PathVariable("prName") String prName) throws Exception { logger.info("rollbackConfiguration called."); // TODO // Below URL should be changed as appropriate multicloud URL. - HttpPost post = new HttpPost(uri +"/v1/definition/" + rbName + "/" + rbVersion + HttpPost post = new HttpPost(uri + "/v1/definition/" + rbName + "/" + rbVersion + "/profile/" + prName + "/config/rollback"); ObjectMapper objectMapper = new ObjectMapper(); @@ -683,7 +786,7 @@ public class CnfAdapterRest { post.setEntity(requestEntity); try (CloseableHttpClient httpClient = HttpClients.createDefault(); - CloseableHttpResponse response = httpClient.execute(post)) { + CloseableHttpResponse response = httpClient.execute(post)) { logger.info("response:" + response.getEntity()); return EntityUtils.toString(response.getEntity()); } diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java index faef1d0..a74a9b3 100644 --- a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java @@ -28,7 +28,11 @@ import javax.ws.rs.core.UriBuilder; import org.apache.http.HttpStatus; import org.onap.so.adapters.cnf.MulticloudConfiguration; import org.onap.so.adapters.cnf.model.BpmnInstanceRequest; +import org.onap.so.adapters.cnf.model.CheckInstanceRequest; import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest; +import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckResponse; +import org.onap.so.adapters.cnf.service.healthcheck.HealthCheckService; +import org.onap.so.adapters.cnf.service.statuscheck.SimpleStatusCheckService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -48,43 +52,26 @@ import com.fasterxml.jackson.databind.JsonMappingException; public class CnfAdapterService { private static final Logger logger = LoggerFactory.getLogger(CnfAdapterService.class); private static final String INSTANCE_CREATE_PATH = "/v1/instance"; - private static final String HEALTH_CHECK = "/v1/healthcheck"; private final RestTemplate restTemplate; + private final HealthCheckService healthCheckService; + private final SimpleStatusCheckService simpleStatusCheckService; private final String uri; @Autowired public CnfAdapterService(RestTemplate restTemplate, + HealthCheckService healthCheckService, + SimpleStatusCheckService simpleStatusCheckService, MulticloudConfiguration multicloudConfiguration) { this.restTemplate = restTemplate; + this.healthCheckService = healthCheckService; + this.simpleStatusCheckService = simpleStatusCheckService; this.uri = multicloudConfiguration.getMulticloudUrl(); } - public String healthCheck() { - + public HealthCheckResponse healthCheck(CheckInstanceRequest healthCheckRequest) throws Exception { logger.info("CnfAdapterService healthCheck called"); - ResponseEntity<String> result = null; - try { - - // String uri = env.getRequiredProperty("multicloud.endpoint"); //TODO: - // This needs to be added as well - // for configuration - String endpoint = UriBuilder.fromUri(uri).path(HEALTH_CHECK).build().toString(); - HttpEntity<?> requestEntity = new HttpEntity<>(getHttpHeaders()); - logger.info("request: " + requestEntity); - result = restTemplate.exchange(endpoint, HttpMethod.GET, requestEntity, String.class); - logger.info("response: " + result); - return result.getBody(); - } catch (HttpClientErrorException e) { - logger.error("Error Calling Multicloud, e"); - if (HttpStatus.SC_NOT_FOUND == e.getStatusCode().value()) { - throw new EntityNotFoundException(e.getResponseBodyAsString()); - } - throw e; - } catch (HttpStatusCodeException e) { - logger.error("Error in Multicloud", e); - throw e; - } + return healthCheckService.healthCheck(healthCheckRequest); } public String createInstance(BpmnInstanceRequest bpmnInstanceRequest) diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiIdGeneratorService.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiIdGeneratorService.java new file mode 100644 index 0000000..2e79b35 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiIdGeneratorService.java @@ -0,0 +1,25 @@ +package org.onap.so.adapters.cnf.service.aai; + +import com.google.common.hash.Hashing; +import org.onap.so.adapters.cnf.model.instantiation.AaiRequest; +import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceGvk; +import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceResourceStatus; +import org.springframework.stereotype.Service; + +import java.nio.charset.StandardCharsets; + +@Service +class AaiIdGeneratorService { + + String generateId(K8sRbInstanceResourceStatus resourceStatus, AaiRequest aaiRequest) { + K8sRbInstanceGvk gvk = resourceStatus.getGvk(); + String originalString = resourceStatus.getName() + gvk.getKind() + gvk.getGroup() + gvk.getVersion() + + aaiRequest.getInstanceId() + aaiRequest.getCloudOwner() + + aaiRequest.getCloudRegion() + aaiRequest.getTenantId(); + + return Hashing.sha256() + .hashString(originalString, StandardCharsets.UTF_8) + .toString(); + } + +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiService.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiService.java new file mode 100644 index 0000000..effecce --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiService.java @@ -0,0 +1,176 @@ +package org.onap.so.adapters.cnf.service.aai; + +import com.google.gson.Gson; +import org.onap.aaiclient.client.aai.AAIResourcesClient; +import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri; +import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory; +import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder; +import org.onap.so.adapters.cnf.client.MulticloudClient; +import org.onap.so.adapters.cnf.model.instantiation.AaiRequest; +import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceGvk; +import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceResourceStatus; +import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceStatus; +import org.onap.so.adapters.cnf.model.statuscheck.K8sStatusMetadata; +import org.onap.so.client.exception.BadResponseException; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class AaiService { + + private final static Gson gson = new Gson(); + private final MulticloudClient multicloudClient; + private final AaiIdGeneratorService aaiIdGeneratorService; + private AAIResourcesClient aaiClient; + + public AaiService(MulticloudClient multicloudClient, AaiIdGeneratorService aaiIdGeneratorService) { + this.multicloudClient = multicloudClient; + this.aaiIdGeneratorService = aaiIdGeneratorService; + } + + public void aaiUpdate(AaiRequest aaiRequest) throws BadResponseException { + String instanceId = aaiRequest.getInstanceId(); + K8sRbInstanceStatus instanceStatus = multicloudClient.getInstanceStatus(instanceId); + + List<K8sRbInstanceResourceStatus> resourcesStatus = instanceStatus.getResourcesStatus(); + List<ParseResult> parsedStatus = resourcesStatus.stream() + .map(status -> parse(status, aaiRequest)) + .collect(Collectors.toList()); + + parsedStatus.forEach(status -> sendUpdateRequestToAai(status, aaiRequest)); + } + + public void aaiDelete(AaiRequest aaiRequest) throws BadResponseException { + String instanceId = aaiRequest.getInstanceId(); + K8sRbInstanceStatus instanceStatus = multicloudClient.getInstanceStatus(instanceId); + + List<K8sRbInstanceResourceStatus> resourcesStatus = instanceStatus.getResourcesStatus(); + List<ParseResult> parsedStatus = resourcesStatus.stream() + .map(status -> parse(status, aaiRequest)) + .collect(Collectors.toList()); + + parsedStatus.forEach(status -> sendDeleteRequestToAai(aaiRequest)); + } + + private void sendDeleteRequestToAai(AaiRequest aaiRequest) { + AAIResourceUri aaiUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion(aaiRequest.getCloudOwner(), aaiRequest.getCloudRegion()) + .tenant(aaiRequest.getTenantId()) + .build()); + getAaiClient().delete(aaiUri); + } + + private void sendUpdateRequestToAai(ParseResult parseResult, AaiRequest aaiRequest) { + AAIResourceUri aaiUri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion(aaiRequest.getCloudOwner(), aaiRequest.getCloudRegion()) + .tenant(aaiRequest.getTenantId()) + .build()); + String payload = gson.toJson(parseResult); + getAaiClient().create(aaiUri, payload); + } + + private AAIResourcesClient getAaiClient() { + if (aaiClient == null) { + aaiClient = new AAIResourcesClient(); + } + return aaiClient; + } + + private ParseResult parse(K8sRbInstanceResourceStatus status, AaiRequest aaiRequest) { + ParseResult result = new ParseResult(); + K8sRbInstanceGvk gvk = status.getGvk(); + K8sStatusMetadata metadata = status.getStatus().getK8sStatusMetadata(); + String id = aaiIdGeneratorService.generateId(status, aaiRequest); + result.setId(id); + result.setName(status.getName()); + result.setGroup(gvk.getGroup()); + result.setVersion(gvk.getVersion()); + result.setKind(gvk.getKind()); + result.setNamespace(metadata.getNamespace()); + Collection<String> labels = new ArrayList<>(); + metadata.getLabels().forEach((key, value) -> { + labels.add(key); + labels.add(value); + }); + result.setLabels(labels); + result.setK8sResourceSelfLink(String.format("http://so-cnf-adapter:8090/api/cnf-adapter/v1/instance/%s/query", aaiRequest.getInstanceId())); + return result; + } + + private class ParseResult { + private String id; + private String name; + private String group; + private String version; + private String kind; + private String namespace; + private Collection<String> labels; + private String k8sResourceSelfLink; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getKind() { + return kind; + } + + public void setKind(String kind) { + this.kind = kind; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public Collection<String> getLabels() { + return labels; + } + + public void setLabels(Collection<String> labels) { + this.labels = labels; + } + + public String getK8sResourceSelfLink() { + return k8sResourceSelfLink; + } + + public void setK8sResourceSelfLink(String k8sResourceSelfLink) { + this.k8sResourceSelfLink = k8sResourceSelfLink; + } + } +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/healthcheck/HealthCheckService.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/healthcheck/HealthCheckService.java new file mode 100644 index 0000000..2f91be8 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/healthcheck/HealthCheckService.java @@ -0,0 +1,147 @@ +package org.onap.so.adapters.cnf.service.healthcheck; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import org.onap.so.adapters.cnf.client.MulticloudClient; +import org.onap.so.adapters.cnf.model.CheckInstanceRequest; +import org.onap.so.adapters.cnf.model.InstanceRequest; +import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckInstance; +import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckInstanceResponse; +import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckResponse; +import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheck; +import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheckSimple; +import org.onap.so.adapters.cnf.service.CnfAdapterService; +import org.onap.so.client.exception.BadResponseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.stream.Collectors; + +import static java.lang.Thread.sleep; +import static java.util.concurrent.Executors.newFixedThreadPool; + +@Service +public class HealthCheckService { + + private static final Logger log = LoggerFactory.getLogger(CnfAdapterService.class); + + private final MulticloudClient instanceApi; + + @Autowired + public HealthCheckService(MulticloudClient multicloudClient) { + this.instanceApi = multicloudClient; + } + + public HealthCheckResponse healthCheck(CheckInstanceRequest healthCheckRequest) throws Exception { + log.info("Health check - START"); + List<HealthCheckInstance> instanceHealthCheckList = startInstanceHealthCheck(healthCheckRequest); + HealthCheckResponse statuses = getStatuses(instanceHealthCheckList); + log.info("Health check - END"); + + return statuses; + } + + private List<HealthCheckInstance> startInstanceHealthCheck(CheckInstanceRequest healthCheckRequest) throws Exception { + log.debug("startInstanceHealthCheck - START"); + List<HealthCheckInstance> healthCheckInstanceList = new ArrayList<>(); + + for (InstanceRequest instance : healthCheckRequest.getInstances()) { + String instanceId = instance.getInstanceId(); + K8sRbInstanceHealthCheckSimple response = instanceApi.startInstanceHealthCheck(instanceId); + log.info("K8sRbInstanceHealthCheckSimple: {}", response); + healthCheckInstanceList.add(new HealthCheckInstance(instanceId, response.getId())); + } + + log.info("healthCheckInstanceList: {}", healthCheckInstanceList); + log.debug("startInstanceHealthCheck - END"); + return healthCheckInstanceList; + } + + private HealthCheckResponse getStatuses(List<HealthCheckInstance> instanceHealthCheckList) throws Exception { + log.debug("getStatuses - START"); + List<HealthCheckThread> threads = instanceHealthCheckList.stream() + .map(HealthCheckThread::new) + .collect(Collectors.toList()); + + int processors = Runtime.getRuntime().availableProcessors(); + ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Health-check-thread-%d").build(); + ExecutorService executorService = newFixedThreadPool(processors, threadFactory); + HealthCheckResponse response = new HealthCheckResponse(); + List<HealthCheckInstanceResponse> healthCheckInstance = null; + healthCheckInstance = executorService.invokeAll(threads).stream() + .map(future -> { + try { + InstanceStatusTuple instanceStatusTuple = future.get(); + String instanceId = instanceStatusTuple.getInstanceId(); + String status = instanceStatusTuple.getStatus(); + String reason = null; + return new HealthCheckInstanceResponse(instanceId, reason, status); + } catch (Exception e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + response.setInstanceResponse(healthCheckInstance); + log.info("Get statuses response: \n {}", response); + log.debug("getStatuses - END"); + return response; + } + + private class HealthCheckThread implements Callable<InstanceStatusTuple> { + + private final HealthCheckInstance healthCheckInstance; + + HealthCheckThread(HealthCheckInstance healthCheckInstance) { + this.healthCheckInstance = healthCheckInstance; + } + + /** + * Approx 5 minutes thread + * If timeout method returns tuple with HeatStackId => Timeout + * @return InstanceStatusTuple + * @throws InterruptedException + * @throws BadResponseException + */ + @Override + public InstanceStatusTuple call() throws InterruptedException, BadResponseException { + log.info("{} started for: {}", Thread.currentThread().getName(), healthCheckInstance); + for (int retry = 0; retry < 30; retry++) { + K8sRbInstanceHealthCheck response = instanceApi.getInstanceHealthCheck(healthCheckInstance.getInstanceId(), healthCheckInstance.getHealthCheckInstance()); + log.debug("Response for instanceId={}: {}", healthCheckInstance, response); + String status = response.getStatus(); + if (!"RUNNING".equals(status.toUpperCase())) { + log.info("Poll status: {} for {}", status, healthCheckInstance); + instanceApi.deleteInstanceHealthCheck(healthCheckInstance.getInstanceId(), healthCheckInstance.getHealthCheckInstance()); + return new InstanceStatusTuple(healthCheckInstance.getInstanceId(), status); + } + sleep(10_000L); + } + return new InstanceStatusTuple(healthCheckInstance.getInstanceId(), "Timeout"); + } + } + + private class InstanceStatusTuple { + private final String instanceId; + private final String status; + + InstanceStatusTuple(String instanceId, String status) { + this.instanceId = instanceId; + this.status = status; + } + + String getInstanceId() { + return instanceId; + } + + String getStatus() { + return status; + } + } + +} diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/statuscheck/SimpleStatusCheckService.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/statuscheck/SimpleStatusCheckService.java new file mode 100644 index 0000000..510d6b8 --- /dev/null +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/statuscheck/SimpleStatusCheckService.java @@ -0,0 +1,56 @@ +package org.onap.so.adapters.cnf.service.statuscheck; + +import org.onap.so.adapters.cnf.client.MulticloudClient; +import org.onap.so.adapters.cnf.model.CheckInstanceRequest; +import org.onap.so.adapters.cnf.model.InstanceRequest; +import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceStatus; +import org.onap.so.adapters.cnf.model.statuscheck.StatusCheckInstanceResponse; +import org.onap.so.adapters.cnf.model.statuscheck.StatusCheckResponse; +import org.onap.so.client.exception.BadResponseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class SimpleStatusCheckService { + + private final Logger log = LoggerFactory.getLogger(SimpleStatusCheckService.class); + private final MulticloudClient instanceApi; + + @Autowired + public SimpleStatusCheckService(MulticloudClient instanceApi) { + this.instanceApi = instanceApi; + } + + public StatusCheckResponse statusCheck(CheckInstanceRequest instanceIds) throws BadResponseException { + log.info("CnfAdapterService statusCheck called"); + StatusCheckResponse result = new StatusCheckResponse(); + + List<StatusCheckInstanceResponse> simpleStatuses = new ArrayList<>(); + for (InstanceRequest instanceRequest : instanceIds.getInstances()) { + String instanceId = instanceRequest.getInstanceId(); + StatusCheckInstanceResponse statusCheck = getStatusCheck(instanceId); + simpleStatuses.add(statusCheck); + } + + result.setInstanceResponse(simpleStatuses); + return result; + } + + private StatusCheckInstanceResponse getStatusCheck(String instanceId) throws BadResponseException { + log.debug("SIMPLE STATUS CHECK - START"); + K8sRbInstanceStatus instanceStatus = instanceApi.getInstanceStatus(instanceId); + boolean isInstanceReady = instanceStatus.isReady(); + log.info("Get status for instanceId: {}", instanceId); + log.info("Instance status: {}", instanceStatus); + StatusCheckInstanceResponse result = new StatusCheckInstanceResponse(instanceId, null, isInstanceReady); + log.debug("SIMPLE STATUS CHECK - END SUCCESS"); + + return result; + } + +} diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestTest.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestTest.java index 979f13b..c85031a 100644 --- a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestTest.java +++ b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/rest/CnfAdapterRestTest.java @@ -28,10 +28,12 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.onap.so.adapters.cnf.MulticloudConfiguration; import org.onap.so.adapters.cnf.model.*; +import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckResponse; import org.onap.so.adapters.cnf.service.CnfAdapterService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; import java.util.HashMap; @@ -61,13 +63,16 @@ public class CnfAdapterRestTest { @Test public void healthCheckTest() throws Exception { - - ResponseEntity<String> response = new ResponseEntity<String>(HttpStatus.OK); + HealthCheckResponse response = new HealthCheckResponse(); + DeferredResult<HealthCheckResponse> deferredResponse = new DeferredResult<>(); + deferredResponse.setResult(response); CnfAdapterService cnfAdapterService = Mockito.mock(CnfAdapterService.class); - Mockito.when(cnfAdapterService.healthCheck()).thenReturn(String.valueOf(response)); - cnfAdapterRest.healthCheck(); + CheckInstanceRequest healthCheckRequest = Mockito.mock(CheckInstanceRequest.class); + Mockito.when(cnfAdapterService.healthCheck(healthCheckRequest)).thenReturn(response); + + cnfAdapterRest.healthCheck(healthCheckRequest); + Assert.assertNotNull(response); - assertEquals(HttpStatus.OK, response.getStatusCode()); } @Test @@ -573,6 +578,3 @@ public class CnfAdapterRestTest { } } } - - - diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java index bdad347..8e8cd5c 100644 --- a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java +++ b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java @@ -48,16 +48,7 @@ public class CnfAdapterServiceTest { @Mock ResponseEntity<String> instanceResponse; - @Test - public void healthCheckTest() throws Exception { - try { - cnfAdapterService.healthCheck(); - } - catch (Exception exp) { - assert(true); - } - - } + @Test public void createInstanceTest() throws Exception { Map<String, String> labels = new HashMap<String, String>(); |