From 0cff84e3ec149a17aad794fa1e7de0980a38807e Mon Sep 17 00:00:00 2001 From: aosull01 Date: Mon, 13 Aug 2018 14:49:43 +0100 Subject: EXTAPI-102 Initial commit Issue-ID: EXTAPI-102 Change-Id: I8a24d9ea73ecfc9c386be12bd35f4d6141d6f2e9 Signed-off-by: aosull01 Co-authored-by: MariosIakovidis Co-authored-by: Prabhu201713 --- .../java/org/onap/nbi/OnapComponentsUrlPaths.java | 3 + .../org/onap/nbi/apis/serviceorder/SoClient.java | 117 +++++++++++ .../serviceorder/model/ResourceSpecification.java | 101 ++++++++++ .../consumer/CreateE2EServiceInstanceResponse.java | 30 +++ .../consumer/DeleteE2EServiceInstanceResponse.java | 35 ++++ .../consumer/GetE2ERequestStatusResponse.java | 30 +++ .../model/consumer/LocationConstraintsModel.java | 45 +++++ .../model/consumer/MSODeleteE2EPayload.java | 45 +++++ .../serviceorder/model/consumer/MSOE2EPayload.java | 38 ++++ .../model/consumer/OperationStatus.java | 213 +++++++++++++++++++++ .../model/consumer/ParametersModel.java | 56 ++++++ .../serviceorder/model/consumer/ResourceModel.java | 87 +++++++++ .../serviceorder/model/consumer/ServiceModel.java | 100 ++++++++++ .../model/consumer/ServiceResponse.java | 42 ++++ .../consumer/VnfLocationConstraintsModel.java | 35 ++++ .../apis/serviceorder/utils/E2EServiceUtils.java | 35 ++++ .../workflow/CheckOrderConsistenceManager.java | 8 +- .../serviceorder/workflow/SOTaskProcessor.java | 177 ++++++++++++++++- src/main/resources/jolt/getServiceCatalog.json | 4 +- src/test/java/org/onap/nbi/apis/ApiTest.java | 133 +++++++++++++ .../apis/assertions/ServiceOrderAssertions.java | 81 ++++++++ .../mappings/so_e2e_delete_service_instance.json | 15 ++ src/test/resources/mappings/so_get_e2e.json | 25 +++ src/test/resources/mappings/so_get_e2e_delete.json | 25 +++ .../so_post_e2e_create_service_instance.json | 18 ++ 25 files changed, 1488 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/ResourceSpecification.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/CreateE2EServiceInstanceResponse.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/DeleteE2EServiceInstanceResponse.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/GetE2ERequestStatusResponse.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/LocationConstraintsModel.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/MSODeleteE2EPayload.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/MSOE2EPayload.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/OperationStatus.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ParametersModel.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ResourceModel.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ServiceModel.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ServiceResponse.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/VnfLocationConstraintsModel.java create mode 100644 src/main/java/org/onap/nbi/apis/serviceorder/utils/E2EServiceUtils.java create mode 100644 src/test/resources/mappings/so_e2e_delete_service_instance.json create mode 100644 src/test/resources/mappings/so_get_e2e.json create mode 100644 src/test/resources/mappings/so_get_e2e_delete.json create mode 100644 src/test/resources/mappings/so_post_e2e_create_service_instance.json diff --git a/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java b/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java index 69cc5be..1df7558 100644 --- a/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java +++ b/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java @@ -45,4 +45,7 @@ public final class OnapComponentsUrlPaths { public static final String MSO_CREATE_SERVICE_INSTANCE_PATH = "/ecomp/mso/infra/serviceInstances/v6"; public static final String MSO_GET_REQUEST_STATUS_PATH = "/ecomp/mso/infra/orchestrationRequests/v6/"; public static final String MSO_DELETE_REQUEST_STATUS_PATH = "/ecomp/mso/infra/serviceInstances/v6/"; + public static final String MSO_CREATE_E2ESERVICE_INSTANCE_PATH = "/ecomp/mso/infra/e2eServiceInstances/v3"; + public static final String MSO_DELETE_E2ESERVICE_INSTANCE_PATH = "/ecomp/mso/infra/e2eServiceInstances/v3/"; + public static final String MSO_GET_E2EREQUEST_STATUS_PATH = "/ecomp/mso/infra/e2eServiceInstances/v3/$serviceId/operations/$operationId"; } diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/SoClient.java b/src/main/java/org/onap/nbi/apis/serviceorder/SoClient.java index 5dda00a..f9724f9 100644 --- a/src/main/java/org/onap/nbi/apis/serviceorder/SoClient.java +++ b/src/main/java/org/onap/nbi/apis/serviceorder/SoClient.java @@ -13,9 +13,15 @@ package org.onap.nbi.apis.serviceorder; import org.onap.nbi.OnapComponentsUrlPaths; +import org.onap.nbi.apis.serviceorder.model.consumer.CreateE2EServiceInstanceResponse; import org.onap.nbi.apis.serviceorder.model.consumer.CreateServiceInstanceResponse; +import org.onap.nbi.apis.serviceorder.model.consumer.DeleteE2EServiceInstanceResponse; +import org.onap.nbi.apis.serviceorder.model.consumer.GetE2ERequestStatusResponse; import org.onap.nbi.apis.serviceorder.model.consumer.GetRequestStatusResponse; +import org.onap.nbi.apis.serviceorder.model.consumer.MSODeleteE2EPayload; +import org.onap.nbi.apis.serviceorder.model.consumer.MSOE2EPayload; import org.onap.nbi.apis.serviceorder.model.consumer.MSOPayload; +import org.onap.nbi.apis.serviceorder.model.consumer.ServiceResponse; import org.onap.nbi.exceptions.BackendFunctionalException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,6 +83,30 @@ public class SoClient { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } + + public ResponseEntity callE2ECreateServiceInstance(MSOE2EPayload msoPayloadE2E) { + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Calling SO CreateServiceInstanceE2E with msoPayload : " + msoPayloadE2E.toString()); + } + + String url = soHostname + OnapComponentsUrlPaths.MSO_CREATE_E2ESERVICE_INSTANCE_PATH; + + try { + ResponseEntity response = restTemplate.exchange(url, HttpMethod.POST, + new HttpEntity<>(msoPayloadE2E, buildRequestHeader()), CreateE2EServiceInstanceResponse.class); + + logE2EResponsePost(url, response); + return response; + + } catch (BackendFunctionalException e) { + LOGGER.error("error on calling " + url + " ," + e); + return new ResponseEntity<>(e.getHttpStatus()); + } catch (ResourceAccessException e) { + LOGGER.error("error on calling " + url + " ," + e); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } public ResponseEntity callDeleteServiceInstance(MSOPayload msoPayload, String serviceId) { @@ -103,6 +133,43 @@ public class SoClient { } + public ResponseEntity callE2EDeleteServiceInstance(String globalSubscriberId, String serviceType, + String serviceInstanceId) { + + String url = soHostname + OnapComponentsUrlPaths.MSO_DELETE_E2ESERVICE_INSTANCE_PATH + serviceInstanceId; + MSODeleteE2EPayload msoDeleteE2EPayload = new MSODeleteE2EPayload(); + msoDeleteE2EPayload.setGlobalSubscriberId(globalSubscriberId); + msoDeleteE2EPayload.setServiceType(serviceType); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Calling SO DeleteE2EServiceInstance with url : " + url + " MSODeleteE2EPayload : " + msoDeleteE2EPayload.toString() ); + } + + try { + ResponseEntity deleteresponse = restTemplate.exchange(url, HttpMethod.DELETE, + new HttpEntity<>(msoDeleteE2EPayload, buildRequestHeader()), DeleteE2EServiceInstanceResponse.class); + + // For E2E Services , Create and Delete Service responses are different, to maintain consistentcy with ServiceInstances + // Copy contents of DeleteE2EServiceInstanceResponse to CreateE2EServiceInstanceResponse + CreateE2EServiceInstanceResponse dummyresponse = new CreateE2EServiceInstanceResponse(); + ServiceResponse serviceResponse = new ServiceResponse(); + dummyresponse.setService(serviceResponse); + dummyresponse.getService().setOperationId(deleteresponse.getBody().getOperationId()); + dummyresponse.getService().setServiceId(serviceInstanceId); + + ResponseEntity response = new ResponseEntity(dummyresponse, deleteresponse.getStatusCode()); + logE2EResponsePost(url, response); + return response; + + } catch (BackendFunctionalException e) { + LOGGER.error("error on calling " + url + " ," + e); + return new ResponseEntity<>(e.getHttpStatus()); + } catch (ResourceAccessException e) { + LOGGER.error("error on calling " + url + " ," + e); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + private void logResponsePost(String url, ResponseEntity response) { LOGGER.info(RESPONSE_STATUS + response.getStatusCodeValue()); if (LOGGER.isDebugEnabled()) { @@ -115,6 +182,17 @@ public class SoClient { } } + private void logE2EResponsePost(String url, ResponseEntity response) { + LOGGER.info(RESPONSE_STATUS + response.getStatusCodeValue()); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("response body : {}", response.getBody().toString()); + } + + if (LOGGER.isWarnEnabled() && !response.getStatusCode().equals(HttpStatus.CREATED)) { + LOGGER.warn("HTTP call SO on {} returns {} , {}", url, response.getStatusCodeValue(), + response.getBody().toString()); + } + } public GetRequestStatusResponse callGetRequestStatus(String requestId) { String url = soHostname + OnapComponentsUrlPaths.MSO_GET_REQUEST_STATUS_PATH + requestId; @@ -132,6 +210,30 @@ public class SoClient { } } +public GetE2ERequestStatusResponse callE2EGetRequestStatus(String operationId, String serviceId) { + + StringBuilder callURL = + new StringBuilder().append(soHostname).append(OnapComponentsUrlPaths.MSO_GET_E2EREQUEST_STATUS_PATH); + String callUrlFormated = callURL.toString().replace("$serviceId", serviceId); + callUrlFormated = callUrlFormated.replace("$operationId", operationId); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Calling SO callE2EGetRequestStatus with url : " + callUrlFormated ); + } + + try { + + ResponseEntity response = restTemplate.exchange(callUrlFormated, HttpMethod.GET, + new HttpEntity<>(buildRequestHeader()), GetE2ERequestStatusResponse.class); + logE2EResponseGet(callUrlFormated, response); + return response.getBody(); + + } catch (BackendFunctionalException|ResourceAccessException e) { + LOGGER.error(ERROR_ON_CALLING + callUrlFormated + " ," + e); + return null; + } + } + private void logResponseGet(String url, ResponseEntity response) { if (response != null) { if (LOGGER.isDebugEnabled()) { @@ -146,6 +248,21 @@ public class SoClient { LOGGER.info("no response calling url {}", url); } } + + private void logE2EResponseGet(String url, ResponseEntity response) { + if(response!=null){ + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("response body : {}", response.getBody().toString()); + } + LOGGER.info("response status : {}", response.getStatusCodeValue()); + if (LOGGER.isWarnEnabled() && !response.getStatusCode().equals(HttpStatus.OK)) { + LOGGER.warn("HTTP call SO on {} returns {} , {}", url, response.getStatusCodeValue(), + response.getBody().toString()); + } + } else { + LOGGER.info("no response calling url {}",url); + } + } private HttpHeaders buildRequestHeader() { HttpHeaders httpHeaders = new HttpHeaders(); diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/ResourceSpecification.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/ResourceSpecification.java new file mode 100644 index 0000000..61473b9 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/ResourceSpecification.java @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ResourceSpecification { + + @JsonProperty("id") + private String id = null; + + @JsonProperty("name") + private String name = null; + + @JsonProperty("version") + private String version = null; + + @JsonProperty("instanceName") + private String instanceName = null; + + @JsonProperty("resourceInvariantUUID") + private String resourceInvariantUUID = null; + + @JsonProperty("resourceType") + private String resourceType = null; + + @JsonProperty("@type") + private String type = null; + + 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 getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getInstanceName() { + return instanceName; + } + + public void setInstanceName(String instanceName) { + this.instanceName = instanceName; + } + + public String getResourceInvariantUUID() { + return resourceInvariantUUID; + } + + public void setResourceInvariantUUID(String resourceInvariantUUID) { + this.resourceInvariantUUID = resourceInvariantUUID; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + + + + +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/CreateE2EServiceInstanceResponse.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/CreateE2EServiceInstanceResponse.java new file mode 100644 index 0000000..5c41166 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/CreateE2EServiceInstanceResponse.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018 Vodafone Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.nbi.apis.serviceorder.model.consumer; + +public class CreateE2EServiceInstanceResponse { + + public ServiceResponse getService() { + return service; + } + + public void setService(ServiceResponse service) { + this.service = service; + } + + private ServiceResponse service; + +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/DeleteE2EServiceInstanceResponse.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/DeleteE2EServiceInstanceResponse.java new file mode 100644 index 0000000..ab74338 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/DeleteE2EServiceInstanceResponse.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.model.consumer; + +public class DeleteE2EServiceInstanceResponse { + + private String operationId; + + public String getOperationId() { + return operationId; + } + + public void setOperationId(String operationId) { + this.operationId = operationId; + } + + @Override + public String toString() { + return "DeleteE2EServiceInstanceResponse{" + + "operationId='" + operationId + '\'' + + '}'; + } + +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/GetE2ERequestStatusResponse.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/GetE2ERequestStatusResponse.java new file mode 100644 index 0000000..42a6170 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/GetE2ERequestStatusResponse.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018 Vodafone Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.nbi.apis.serviceorder.model.consumer; + +public class GetE2ERequestStatusResponse { + + protected OperationStatus operation; + + public OperationStatus getOperation() { + return operation; + } + + public void setOperation(OperationStatus operation) { + this.operation = operation; + } + +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/LocationConstraintsModel.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/LocationConstraintsModel.java new file mode 100644 index 0000000..4b604ae --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/LocationConstraintsModel.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.onap.nbi.apis.serviceorder.model.consumer; + +public class LocationConstraintsModel { + + private String vnfProfileId; + + private VnfLocationConstraintsModel locationConstraints; + + + public String getVnfProfileId() { + return vnfProfileId; + } + + public void setVnfProfileId(String vnfProfileId) { + this.vnfProfileId = vnfProfileId; + } + + public VnfLocationConstraintsModel getLocationConstraints() { + return locationConstraints; + } + + public void setLocationConstraints(VnfLocationConstraintsModel locationConstraints) { + this.locationConstraints = locationConstraints; + } + + @Override + public String toString() { + return "LocationConstraintsModel{" + + "vnfProfileId='" + vnfProfileId + '\'' + + locationConstraints + '}'; + } + +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/MSODeleteE2EPayload.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/MSODeleteE2EPayload.java new file mode 100644 index 0000000..3ab4eb6 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/MSODeleteE2EPayload.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.model.consumer; + +public class MSODeleteE2EPayload { + + private String globalSubscriberId; + + private String serviceType; + + public String getGlobalSubscriberId() { + return globalSubscriberId; + } + + public void setGlobalSubscriberId(String globalSubscriberId) { + this.globalSubscriberId = globalSubscriberId; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + @Override + public String toString() { + return "MSODeleteE2EPayload{" + + "globalSubscriberId='" + globalSubscriberId+ '\'' + + ", serviceType='" + serviceType + '\'' + + '}'; + } +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/MSOE2EPayload.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/MSOE2EPayload.java new file mode 100644 index 0000000..69ce398 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/MSOE2EPayload.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.model.consumer; + +public class MSOE2EPayload { + + private ServiceModel service; + + public MSOE2EPayload(ServiceModel service) { + this.service = service; + } + + public ServiceModel getService() { + return service; + } + + public void setService(ServiceModel service) { + this.service = service; + } + + @Override + public String toString() { + return "MSOPayloadE2E{" + + "service=" + service + + '}'; + } +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/OperationStatus.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/OperationStatus.java new file mode 100644 index 0000000..2cd7393 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/OperationStatus.java @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2018 Vodafone Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.nbi.apis.serviceorder.model.consumer; + +import java.io.Serializable; +import java.sql.Timestamp; + +public class OperationStatus implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String serviceId = null; + + private String operationId = null; + + private String serviceName = null; + + private String operation = null; + + private String userId = null; + + private String result = null; + + private String operationContent = null; + + private String progress = "0"; + + private String reason = null; + + private Timestamp operateAt = null; + + private Timestamp finishedAt = null; + + + public String getServiceId() { + return serviceId; + } + + + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + + + public String getOperationId() { + return operationId; + } + + + public void setOperationId(String operationId) { + this.operationId = operationId; + } + + + public String getOperation() { + return operation; + } + + + public void setOperation(String operation) { + this.operation = operation; + } + + + public String getUserId() { + return userId; + } + + + public void setUserId(String userId) { + this.userId = userId; + } + + + public String getResult() { + return result; + } + + + public void setResult(String result) { + this.result = result; + } + + + public String getOperationContent() { + return operationContent; + } + + + public void setOperationContent(String operationContent) { + this.operationContent = operationContent; + } + + + public String getProgress() { + return progress; + } + + + public void setProgress(String progress) { + this.progress = progress; + } + + + public String getReason() { + return reason; + } + + + public void setReason(String reason) { + this.reason = reason; + } + + + public Timestamp getOperateAt() { + return operateAt; + } + + + public void setOperateAt(Timestamp operateAt) { + this.operateAt = operateAt; + } + + + public Timestamp getFinishedAt() { + return finishedAt; + } + + + public void setFinishedAt(Timestamp finishedAt) { + this.finishedAt = finishedAt; + } + + + + /** + * @return Returns the serviceName. + */ + public String getServiceName() { + return serviceName; + } + + + + /** + * @param serviceName The serviceName to set. + */ + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + + /** + *
+ * + * @return + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((operationId == null) ? 0 : operationId.hashCode()); + result = prime * result + ((serviceId == null) ? 0 : serviceId.hashCode()); + return result; + } + + + /** + *
+ * + * @param obj + * @return + */ + @Override + public boolean equals(Object obj) { + if(this == obj) + return true; + if(obj == null) + return false; + if(getClass() != obj.getClass()) + return false; + OperationStatus other = (OperationStatus)obj; + if(operationId == null) { + if(other.operationId != null) + return false; + } else if(!operationId.equals(other.operationId)) + return false; + if(serviceId == null) { + if(other.serviceId != null) + return false; + } else if(!serviceId.equals(other.serviceId)) + return false; + return true; + } + + +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ParametersModel.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ParametersModel.java new file mode 100644 index 0000000..8a49c9c --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ParametersModel.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.model.consumer; + +import java.util.List; +import java.util.Map; + +public class ParametersModel { + + private List locationConstraints; + + private List resources; + + private Map requestInputs; + + public List getLocationConstraints(){ + return locationConstraints; + } + + public void setLocationConstraints(List locationConstraints) { + this.locationConstraints = locationConstraints; + } + + public List getResources(){ + return resources; + } + + public void setResources(List resources) { + this.resources = resources; + } + + public Map getRequestInputs() { + return requestInputs; + } + + public void setRequestInputs(Map requestInputs) { + this.requestInputs = requestInputs; + } + + @Override + public String toString() { + return "ParametersModel{" + "locationConstraints=" + locationConstraints + ", resources=" + resources + ", requestInputs=" + + requestInputs + '}'; + } +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ResourceModel.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ResourceModel.java new file mode 100644 index 0000000..0aabb63 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ResourceModel.java @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.model.consumer; + +import java.util.*; + +public class ResourceModel { + + private String resourceName; + + private String resourceInvariantUuid; + + private String resourceUuid; + + //private String resourceCustomizationUuid; + + private ParametersModel parameters; + + + public ResourceModel (Map info) { + setResourceName((String)info.get("name")); + setResourceInvariantUuid((String)info.get("resourceInvariantUUID")); + setResourceUuid((String)info.get("id")); + //setResourceCustomizationUuid((String)info.get("modelCustomizationId")); + } + + public String getResourceName() { + return resourceName; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getResourceInvariantUuid() { + return resourceInvariantUuid; + } + + public void setResourceInvariantUuid(String resourceInvariantUuid) { + this.resourceInvariantUuid = resourceInvariantUuid; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + /* + public String getResourceCustomizationUuid() { + return resourceCustomizationUuid; + } + + public void setResourceCustomizationUuid(String resourceCustomizationUuid) { + this.resourceCustomizationUuid = resourceCustomizationUuid; + } + */ + public ParametersModel getParameters() { + return parameters; + } + + public void setParameters(ParametersModel parameters) { + this.parameters = parameters; + } + + @Override + public String toString() { + return "ResourceModel{" + + "resourceName='" + resourceName + '\'' + + ", resourceInvariantUuid='" + resourceInvariantUuid + '\'' + + ", resourceUuid='" + resourceUuid + '\'' + + ", parameters='" + parameters + '}'; + } +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ServiceModel.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ServiceModel.java new file mode 100644 index 0000000..f9d475d --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ServiceModel.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.model.consumer; + +public class ServiceModel { + + private String name; + + private String description; + + private String serviceInvariantUuid; + + private String serviceUuid; + + private String globalSubscriberId; + + private String serviceType; + + private ParametersModel parameters; + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getServiceInvariantUuid() { + return serviceInvariantUuid; + } + + public void setServiceInvariantUuid(String serviceInvariantUuid) { + this.serviceInvariantUuid = serviceInvariantUuid; + } + + public String getServiceUuid() { + return serviceUuid; + } + + public void setServiceUuid(String serviceUuid) { + this.serviceUuid = serviceUuid; + } + + public String getGlobalSubscriberId() { + return globalSubscriberId; + } + + public void setGlobalSubscriberId(String globalSubscriberId) { + this.globalSubscriberId = globalSubscriberId; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public ParametersModel getParameters() { + return parameters; + } + + public void setParameters(ParametersModel parameters) { + this.parameters = parameters; + } + + @Override + public String toString() { + return "ServiceModel{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", serviceInvariantUuid='" + serviceInvariantUuid + '\'' + + ", serviceUuid='" + serviceUuid + '\'' + + ", globalSubscriberId='" + globalSubscriberId + '\'' + + ", serviceType='" + serviceType + '\'' + + ", parameters='" + parameters + '}'; + } +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ServiceResponse.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ServiceResponse.java new file mode 100644 index 0000000..18ecc19 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/ServiceResponse.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.model.consumer; + +public class ServiceResponse { + + private String operationId = null; + private String serviceId = null; + + public String getOperationId() { + return operationId; + } + + public void setOperationId(String operationId) { + this.operationId = operationId; + } + + public String getServiceId() { + return serviceId; + } + + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + + @Override + public String toString() { + return "service{" + "operationId='" + operationId + '\'' + ", serviceId='" + serviceId + '\'' + '}'; + } + +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/VnfLocationConstraintsModel.java b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/VnfLocationConstraintsModel.java new file mode 100644 index 0000000..99f5a7c --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/model/consumer/VnfLocationConstraintsModel.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.model.consumer; + +public class VnfLocationConstraintsModel { + + private String vimId; + + + public String getVimId() { + return vimId; + } + + public void setVimId(String vimId) { + this.vimId = vimId; + } + + @Override + public String toString() { + return "VnfLocationConstraintsModel{" + + "vimId='" + vimId + '\'' + + '}'; + } +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/utils/E2EServiceUtils.java b/src/main/java/org/onap/nbi/apis/serviceorder/utils/E2EServiceUtils.java new file mode 100644 index 0000000..d667ad8 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/utils/E2EServiceUtils.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 Huawei + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.onap.nbi.apis.serviceorder.utils; + +import java.util.Map; + +import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderItemInfo; + +public class E2EServiceUtils { + public static boolean isE2EService(ServiceOrderItemInfo serviceOrderItemInfo){ + Map sdcInfos = serviceOrderItemInfo.getCatalogResponse(); + boolean e2eService = false; + if(sdcInfos.get("category")!=null){ + String category = ((String)sdcInfos.get("category")).toLowerCase(); + // Until SO comes up with one consolidated API for Service CRUD, ExtAPI has to be handle SO (serviceInstance and e2eServiceInstances )APIs for service CRUD + // All E2E Services are required to be created in SDC under category "E2E Services" until SO fixes the multiple API issue. + if(category.startsWith("e2e")) { + e2eService = true; + } + } + return e2eService; + } + +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/workflow/CheckOrderConsistenceManager.java b/src/main/java/org/onap/nbi/apis/serviceorder/workflow/CheckOrderConsistenceManager.java index e868bc6..88db614 100644 --- a/src/main/java/org/onap/nbi/apis/serviceorder/workflow/CheckOrderConsistenceManager.java +++ b/src/main/java/org/onap/nbi/apis/serviceorder/workflow/CheckOrderConsistenceManager.java @@ -18,6 +18,7 @@ import org.onap.nbi.apis.serviceorder.model.consumer.SubscriberInfo; import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderInfo; import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderItemInfo; import org.onap.nbi.apis.serviceorder.service.ServiceOrderService; +import org.onap.nbi.apis.serviceorder.utils.E2EServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -101,7 +102,8 @@ public class CheckOrderConsistenceManager { private void handleServiceOrderItemInAdd(ServiceOrderInfo serviceOrderInfo, ServiceOrder serviceOrder, ServiceOrderItem serviceOrderItem, ServiceOrderItemInfo serviceOrderItemInfo) { - if (shouldAcceptServiceOrderItemToAdd(serviceOrderItem, serviceOrder, serviceOrderInfo.getServiceOrderId())) { + boolean e2eService= E2EServiceUtils.isE2EService(serviceOrderItemInfo); + if (shouldAcceptServiceOrderItemToAdd(serviceOrderItem, serviceOrder, serviceOrderInfo.getServiceOrderId(), e2eService)) { serviceOrderInfo.addServiceOrderItemInfos(serviceOrderItem.getId(), serviceOrderItemInfo); } else { serviceOrderInfo.setIsServiceOrderRejected(true); @@ -110,14 +112,14 @@ public class CheckOrderConsistenceManager { } private boolean shouldAcceptServiceOrderItemToAdd(ServiceOrderItem serviceOrderItem, - ServiceOrder serviceOrder, String serviceOrderId) { + ServiceOrder serviceOrder, String serviceOrderId, Boolean e2eService) { if (!StringUtils.isEmpty(serviceOrderItem.getService().getId())) { LOGGER .warn("serviceOrderItem {} for serviceorder {} rejected cause service.id must be empty in add action", serviceOrderItem.getId(), serviceOrderId); serviceOrderService.addOrderItemMessage(serviceOrder,serviceOrderItem, "103"); return false; - } else if (!serviceOrderConsumerService.isTenantIdPresentInAAI(serviceOrder)) { + } else if (!e2eService && !serviceOrderConsumerService.isTenantIdPresentInAAI(serviceOrder)) { LOGGER.warn("serviceOrderItem {} for serviceOrder {} rejected cause tenantId not found in AAI", serviceOrderItem.getId(), serviceOrderId); serviceOrderService.addOrderItemMessage(serviceOrder,serviceOrderItem, "107"); diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/workflow/SOTaskProcessor.java b/src/main/java/org/onap/nbi/apis/serviceorder/workflow/SOTaskProcessor.java index a11863c..3f9b556 100644 --- a/src/main/java/org/onap/nbi/apis/serviceorder/workflow/SOTaskProcessor.java +++ b/src/main/java/org/onap/nbi/apis/serviceorder/workflow/SOTaskProcessor.java @@ -22,6 +22,7 @@ import org.onap.nbi.apis.serviceorder.model.orchestrator.ExecutionTask; import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderInfo; import org.onap.nbi.apis.serviceorder.repositories.ExecutionTaskRepository; import org.onap.nbi.apis.serviceorder.service.ServiceOrderService; +import org.onap.nbi.apis.serviceorder.utils.E2EServiceUtils; import org.onap.nbi.apis.serviceorder.utils.JsonEntityConverter; import org.onap.nbi.exceptions.TechnicalException; import org.slf4j.Logger; @@ -81,18 +82,29 @@ public class SOTaskProcessor { ServiceOrder serviceOrder = serviceOrderService.findServiceOrderById(serviceOrderInfo.getServiceOrderId()); ServiceOrderItem serviceOrderItem = getServiceOrderItem(executionTask, serviceOrder); - + boolean e2eService = E2EServiceUtils.isE2EService(serviceOrderInfo.getServiceOrderItemInfos().get(serviceOrderItem.getId())); + if (StateType.ACKNOWLEDGED == serviceOrderItem.getState()) { + if (e2eService) { + ResponseEntity response = postE2EServiceOrderItem(serviceOrderInfo, + serviceOrderItem, serviceOrder); + updateE2EServiceOrderItem(response, serviceOrderItem, serviceOrder); + } else { - ResponseEntity response = postServiceOrderItem(serviceOrderInfo,serviceOrder, - serviceOrderItem); - updateServiceOrderItem(response, serviceOrderItem,serviceOrder); + ResponseEntity response = postServiceOrderItem(serviceOrderInfo,serviceOrder, + serviceOrderItem); + updateServiceOrderItem(response, serviceOrderItem,serviceOrder); + } } if (executionTask.getNbRetries() > 0 && StateType.FAILED != serviceOrderItem.getState() ) { // TODO lancer en asynchrone - pollSoRequestStatus(serviceOrder,serviceOrderItem); + if (e2eService) + pollE2ESoRequestStatus(serviceOrder, serviceOrderItem); + else + pollSoRequestStatus(serviceOrder, serviceOrderItem); + if (serviceOrderItem.getState().equals(StateType.COMPLETED)) { updateSuccessTask(executionTask); } else { @@ -120,6 +132,18 @@ public class SOTaskProcessor { return response; } + private ResponseEntity postE2EServiceOrderItem(ServiceOrderInfo serviceOrderInfo, + ServiceOrderItem serviceOrderItem, ServiceOrder serviceOrder) { + ResponseEntity response; + try { + response = postE2ESORequest(serviceOrderItem, serviceOrderInfo, serviceOrder); + } catch (NullPointerException e) { + LOGGER.error("Unable to create service instance for serviceOrderItem.id=" + serviceOrderItem.getId(), e); + response = null; + } + return response; + } + private ServiceOrderItem getServiceOrderItem(ExecutionTask executionTask, ServiceOrder serviceOrder) { for (ServiceOrderItem item : serviceOrder.getOrderItem()) { if (item.getId().equals(executionTask.getOrderItemId())) { @@ -169,6 +193,27 @@ public class SOTaskProcessor { return response; } + private ResponseEntity postE2ESORequest(ServiceOrderItem serviceOrderItem, + ServiceOrderInfo serviceOrderInfo, ServiceOrder serviceOrder) { + ServiceModel service = buildE2ESoRequest(serviceOrderItem, serviceOrderInfo.getServiceOrderItemInfos().get(serviceOrderItem.getId()).getCatalogResponse(), serviceOrderInfo.getSubscriberInfo(), serviceOrder); + MSOE2EPayload msoE2EPayload = new MSOE2EPayload(service); + ResponseEntity response = null; + switch (serviceOrderItem.getAction()) { + case ADD: + response = soClient.callE2ECreateServiceInstance(msoE2EPayload); + break; + case DELETE: + response = soClient.callE2EDeleteServiceInstance(service.getGlobalSubscriberId(), service.getServiceType(),serviceOrderItem.getService().getId()); + break; + default: + break; + } + if(response!=null && response.getStatusCode()== HttpStatus.INTERNAL_SERVER_ERROR) { + serviceOrderService.addOrderMessage(serviceOrder, "502"); + } + return response; + } + private void updateServiceOrder(ServiceOrder serviceOrder) { boolean atLeastOneCompleted = false; boolean atLeastOneNotFinished = false; @@ -250,6 +295,47 @@ public class SOTaskProcessor { } } + private void pollE2ESoRequestStatus(ServiceOrder serviceOrder, ServiceOrderItem orderItem) throws InterruptedException { + boolean stopPolling = false; + String operationId = orderItem.getRequestId(); + String serviceId = orderItem.getService().getId(); + int nbRetries = 0; + GetE2ERequestStatusResponse response = null; + final String ERROR = "error"; + final String FINISHED = "finished"; + final String PROCESSING = "processing"; + String result = null; + while (!stopPolling) { + response = soClient.callE2EGetRequestStatus(operationId, serviceId); + if (response != null) { + result = response.getOperation().getResult(); + if (PROCESSING.equals(result)) { + nbRetries++; + serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS); + Thread.sleep(1000); + LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId()); + } else if (ERROR.equals(result)) { + serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED); + stopPolling = true; + LOGGER.debug("orderitem id {} failed, response from request status {}",orderItem.getId(),response.getOperation().getResult()); + } else if (FINISHED.equals(result)) { + serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.COMPLETED); + stopPolling = true; + LOGGER.debug("orderitem id {} completed"); + } + } else { + serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS); + stopPolling = true; + LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId()); + } + if (nbRetries == 3) { + stopPolling = true; + LOGGER.debug("orderitem id {} stop polling from getrequeststatus, 3 retries done",orderItem.getId()); + + } + } + } + /** * Build SO CREATE request from the ServiceOrder and catalog informations from SDC * @@ -302,6 +388,57 @@ public class SOTaskProcessor { return requestDetails; } + + /** + * Build E2E SO CREATE request from the ServiceOrder and catalog informations from SDC + * + * @param serviceOrderItem + * @param serviceOrder + * @param sdcInfos + * @return + */ + //ServiceOrderItem serviceOrderItem --> orderItem? + private ServiceModel buildE2ESoRequest(ServiceOrderItem serviceOrderItem, Map sdcInfos, + SubscriberInfo subscriberInfo, ServiceOrder serviceOrder) { + + subscriberInfo.getGlobalSubscriberId(); + ServiceModel service = new ServiceModel(); + service.setName(serviceOrderItem.getService().getName()); + service.setDescription(serviceOrder.getDescription()); + service.setServiceUuid(serviceOrderItem.getService().getServiceSpecification().getId()); + service.setServiceInvariantUuid((String) sdcInfos.get("invariantUUID")); + service.setGlobalSubscriberId(subscriberInfo.getGlobalSubscriberId()); + service.setServiceType((String) sdcInfos.get("name")); + + ParametersModel parameters = new ParametersModel(); + ArrayList resources = new ArrayList(); + + ArrayList resourceObjects = (ArrayList)sdcInfos.get("resourceSpecification"); + + for(int i = 0; i < resourceObjects.size(); i++) { + + ResourceModel resourceModel = new ResourceModel((Map)resourceObjects.get(i)); + ParametersModel resourceParameters = new ParametersModel(); + resourceModel.setParameters(resourceParameters); + resources.add(resourceModel); + + } + parameters.setResources(resources); + List userParams = retrieveUserParamsFromServiceCharacteristics(serviceOrderItem.getService().getServiceCharacteristic()); + + // If there are ServiceCharacteristics add them to requestInputs + if (!userParams.isEmpty()){ + Map requestInputs = new HashMap(); + for (int i = 0; i < userParams.size(); i++) { + requestInputs.put(userParams.get(i).getName(), userParams.get(i).getValue()); + } + + parameters.setRequestInputs(requestInputs); + } + service.setParameters(parameters); + + return service; + } /** * Build a list of UserParams for the SO request by browsing a list of ServiceCharacteristics from SDC @@ -351,6 +488,36 @@ public class SOTaskProcessor { } } + /** + * Update E2EServiceOrderItem with SO response by using serviceOrderRepository with the serviceOrderId + * @param response + * @param orderItem + * @param serviceOrder + */ + private void updateE2EServiceOrderItem(ResponseEntity response, + ServiceOrderItem orderItem, ServiceOrder serviceOrder) { + + if (response==null || !response.getStatusCode().is2xxSuccessful()) { + LOGGER.warn("response ko for serviceOrderItem.id=" + orderItem.getId()); + serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED); + } + else { + CreateE2EServiceInstanceResponse createE2EServiceInstanceResponse = response.getBody(); + if (createE2EServiceInstanceResponse != null && !orderItem.getState().equals(StateType.FAILED)) { + orderItem.getService().setId(createE2EServiceInstanceResponse.getService().getServiceId()); + orderItem.setRequestId(createE2EServiceInstanceResponse.getService().getOperationId()); + } + + if (!response.getStatusCode().is2xxSuccessful() || response.getBody() == null + || response.getBody().getService().getOperationId() == null || response.getBody().getService().getServiceId() == null) { + serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED); + LOGGER.warn("order item {} failed , status {} , response {}",orderItem.getId(),response.getStatusCode(),response.getBody()); + } else { + serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS); + } + } + } + /** * Update an executionTask in database when it's process with a success * diff --git a/src/main/resources/jolt/getServiceCatalog.json b/src/main/resources/jolt/getServiceCatalog.json index 6fdadd6..d227ec4 100644 --- a/src/main/resources/jolt/getServiceCatalog.json +++ b/src/main/resources/jolt/getServiceCatalog.json @@ -8,7 +8,7 @@ "invariantUUID": "invariantUUID", "toscaModelURL": "toscaModelURL", "toscaResourceName": "toscaResourceName", - "category ": "category", + "category": "category", "subcategory": "subcategory", "distributionStatus": "distributionStatus", "version": "version", @@ -72,4 +72,4 @@ } } } -] \ No newline at end of file +] diff --git a/src/test/java/org/onap/nbi/apis/ApiTest.java b/src/test/java/org/onap/nbi/apis/ApiTest.java index 033f3be..f18c5f8 100644 --- a/src/test/java/org/onap/nbi/apis/ApiTest.java +++ b/src/test/java/org/onap/nbi/apis/ApiTest.java @@ -776,6 +776,43 @@ public class ApiTest { } + @Test + public void testE2EExecutionTaskSuccess() throws Exception { + + ExecutionTask executionTaskA = ServiceOrderAssertions.setUpBddForE2EExecutionTaskSucess(serviceOrderRepository, + executionTaskRepository, ActionType.ADD); + ExecutionTask executionTaskB; + + + SoTaskProcessor.processOrderItem(executionTaskA); + ServiceOrder serviceOrderChecked = serviceOrderRepository.findOne("test"); + assertThat(serviceOrderChecked.getState()).isEqualTo(StateType.INPROGRESS); + for (ServiceOrderItem serviceOrderItem : serviceOrderChecked.getOrderItem()) { + if (serviceOrderItem.getId().equals("A")) { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.COMPLETED); + } else { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.ACKNOWLEDGED); + } + } + + executionTaskB = getExecutionTask("B"); + assertThat(executionTaskB.getReliedTasks()).isNullOrEmpty(); + executionTaskA = getExecutionTask("A"); + assertThat(executionTaskA).isNull(); + + SoTaskProcessor.processOrderItem(executionTaskB); + serviceOrderChecked = serviceOrderRepository.findOne("test"); + assertThat(serviceOrderChecked.getState()).isEqualTo(StateType.COMPLETED); + for (ServiceOrderItem serviceOrderItem : serviceOrderChecked.getOrderItem()) { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.COMPLETED); + + } + + assertThat(executionTaskRepository.count()).isEqualTo(0); + + + + } @Test public void testExecutionTaskDeleteSuccess() throws Exception { @@ -813,6 +850,44 @@ public class ApiTest { + } + + @Test + public void testE2EExecutionTaskDeleteSuccess() throws Exception { + + ExecutionTask executionTaskA = ServiceOrderAssertions.setUpBddForE2EExecutionTaskSucess(serviceOrderRepository, + executionTaskRepository, ActionType.DELETE); + ExecutionTask executionTaskB; + + + SoTaskProcessor.processOrderItem(executionTaskA); + ServiceOrder serviceOrderChecked = serviceOrderRepository.findOne("test"); + assertThat(serviceOrderChecked.getState()).isEqualTo(StateType.INPROGRESS); + for (ServiceOrderItem serviceOrderItem : serviceOrderChecked.getOrderItem()) { + if (serviceOrderItem.getId().equals("A")) { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.COMPLETED); + } else { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.ACKNOWLEDGED); + } + } + + executionTaskB = getExecutionTask("B"); + assertThat(executionTaskB.getReliedTasks()).isNullOrEmpty(); + executionTaskA = getExecutionTask("A"); + assertThat(executionTaskA).isNull(); + + SoTaskProcessor.processOrderItem(executionTaskB); + serviceOrderChecked = serviceOrderRepository.findOne("test"); + assertThat(serviceOrderChecked.getState()).isEqualTo(StateType.COMPLETED); + for (ServiceOrderItem serviceOrderItem : serviceOrderChecked.getOrderItem()) { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.COMPLETED); + + } + + assertThat(executionTaskRepository.count()).isEqualTo(0); + + + } @@ -856,8 +931,45 @@ public class ApiTest { } + @Test + public void testE2EExecutionTaskFailed() throws Exception { + + ExecutionTask executionTaskA = ServiceOrderAssertions.setUpBddForE2EExecutionTaskSucess(serviceOrderRepository, + executionTaskRepository, ActionType.ADD); + + removeWireMockMapping("/ecomp/mso/infra/e2eServiceInstances/v3/serviceId/operations/operationId"); + + + SoTaskProcessor.processOrderItem(executionTaskA); + ServiceOrder serviceOrderChecked = serviceOrderRepository.findOne("test"); + assertThat(serviceOrderChecked.getState()).isEqualTo(StateType.INPROGRESS); + for (ServiceOrderItem serviceOrderItem : serviceOrderChecked.getOrderItem()) { + if (serviceOrderItem.getId().equals("A")) { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.INPROGRESS); + } else { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.ACKNOWLEDGED); + } + } + executionTaskA = getExecutionTask("A"); + assertThat(executionTaskA.getNbRetries()).isEqualTo(2); + SoTaskProcessor.processOrderItem(executionTaskA); + executionTaskA = getExecutionTask("A"); + SoTaskProcessor.processOrderItem(executionTaskA); + executionTaskA = getExecutionTask("A"); + SoTaskProcessor.processOrderItem(executionTaskA); + + serviceOrderChecked = serviceOrderRepository.findOne("test"); + assertThat(serviceOrderChecked.getState()).isEqualTo(StateType.FAILED); + for (ServiceOrderItem serviceOrderItem : serviceOrderChecked.getOrderItem()) { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.FAILED); + + } + + assertThat(executionTaskRepository.count()).isEqualTo(0); + } + @Test public void testExecutionTaskFailedNoSoResponse() throws Exception { @@ -890,6 +1002,27 @@ public class ApiTest { removeWireMockMapping("/ecomp/mso/infra/orchestrationRequests/v6/requestId"); + SoTaskProcessor.processOrderItem(executionTaskA); + ServiceOrder serviceOrderChecked = serviceOrderRepository.findOne("test"); + assertThat(serviceOrderChecked.getState()).isEqualTo(StateType.FAILED); + for (ServiceOrderItem serviceOrderItem : serviceOrderChecked.getOrderItem()) { + assertThat(serviceOrderItem.getState()).isEqualTo(StateType.FAILED); + } + + assertThat(executionTaskRepository.count()).isEqualTo(0); + + } + + @Test + public void testE2EExecutionTaskFailedNoSoAndStatusResponse() throws Exception { + + ExecutionTask executionTaskA = ServiceOrderAssertions.setUpBddForE2EExecutionTaskSucess(serviceOrderRepository, + executionTaskRepository, ActionType.ADD); + + removeWireMockMapping("/ecomp/mso/infra/e2eServiceInstances/v3"); + removeWireMockMapping("/ecomp/mso/infra/e2eServiceInstances/v3/serviceId/operations/operationId"); + + SoTaskProcessor.processOrderItem(executionTaskA); ServiceOrder serviceOrderChecked = serviceOrderRepository.findOne("test"); assertThat(serviceOrderChecked.getState()).isEqualTo(StateType.FAILED); diff --git a/src/test/java/org/onap/nbi/apis/assertions/ServiceOrderAssertions.java b/src/test/java/org/onap/nbi/apis/assertions/ServiceOrderAssertions.java index 90fd852..65686d2 100644 --- a/src/test/java/org/onap/nbi/apis/assertions/ServiceOrderAssertions.java +++ b/src/test/java/org/onap/nbi/apis/assertions/ServiceOrderAssertions.java @@ -23,11 +23,14 @@ import org.onap.nbi.apis.serviceorder.model.ActionType; import org.onap.nbi.apis.serviceorder.model.OrderItemRelationship; import org.onap.nbi.apis.serviceorder.model.OrderRelationship; import org.onap.nbi.apis.serviceorder.model.RelatedParty; +import org.onap.nbi.apis.serviceorder.model.ResourceSpecification; import org.onap.nbi.apis.serviceorder.model.Service; +import org.onap.nbi.apis.serviceorder.model.ServiceCharacteristic; import org.onap.nbi.apis.serviceorder.model.ServiceOrder; import org.onap.nbi.apis.serviceorder.model.ServiceOrderItem; import org.onap.nbi.apis.serviceorder.model.ServiceSpecificationRef; import org.onap.nbi.apis.serviceorder.model.StateType; +import org.onap.nbi.apis.serviceorder.model.Value; import org.onap.nbi.apis.serviceorder.model.consumer.SubscriberInfo; import org.onap.nbi.apis.serviceorder.model.orchestrator.ExecutionTask; import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderInfo; @@ -178,6 +181,7 @@ public class ServiceOrderAssertions { sdcResponse.put("invariantUUID", "uuid"); sdcResponse.put("name", "vFW"); sdcResponse.put("version", "v1"); + sdcResponse.put("category", "NonE2E"); ServiceOrderInfo serviceOrderInfo = new ServiceOrderInfo(); serviceOrderInfo.setServiceOrderId("test"); @@ -212,6 +216,83 @@ public class ServiceOrderAssertions { return executionTaskA; } + public static ExecutionTask setUpBddForE2EExecutionTaskSucess(ServiceOrderRepository serviceOrderRepository, + ExecutionTaskRepository executionTaskRepository, + ActionType actionType) { + ServiceOrder testServiceOrder = createTestServiceOrder(actionType); + + for (ServiceOrderItem serviceOrderItem : testServiceOrder.getOrderItem()) { + serviceOrderItem.setState(StateType.ACKNOWLEDGED); + List serviceCharacteristics = new ArrayList(); + ServiceCharacteristic serviceCharacteristic1 = new ServiceCharacteristic(); + serviceCharacteristic1.setName("access-site-id"); + Value value1 = new Value(); + value1.setServiceCharacteristicValue("1234765"); + serviceCharacteristic1.setValue(value1); + serviceCharacteristics.add(serviceCharacteristic1); + ServiceCharacteristic serviceCharacteristic2 = new ServiceCharacteristic(); + serviceCharacteristic2.setName("provider-site-id"); + Value value2 = new Value(); + value2.setServiceCharacteristicValue("654321"); + serviceCharacteristic2.setValue(value2); + serviceCharacteristics.add(serviceCharacteristic2); + serviceOrderItem.getService().setServiceCharacteristic(serviceCharacteristics); + } + + testServiceOrder.setState(StateType.ACKNOWLEDGED); + testServiceOrder.setId("test"); + serviceOrderRepository.save(testServiceOrder); + + LinkedHashMap sdcResponse = new LinkedHashMap<>(); + sdcResponse.put("invariantUUID", "uuid"); + sdcResponse.put("name", "vFW"); + sdcResponse.put("version", "v1"); + sdcResponse.put("category", "E2E Service"); + + List resourceSpecs = new ArrayList<>(); + ResourceSpecification resourceSpecificationA = new ResourceSpecification(); + resourceSpecificationA.setId("2e3feeb0-8e36-46c6-862c-236d9c626438"); + resourceSpecificationA.setInstanceName("vFW-vSINK"); + resourceSpecificationA.setName("vFW-SINK"); + resourceSpecificationA.setType("ONAPresource"); + resourceSpecificationA.setVersion("2.0"); + resourceSpecificationA.setResourceInvariantUUID("6e3feeb0-8e36-46c6-862c-236d9c626438"); + resourceSpecs.add(resourceSpecificationA); + + sdcResponse.put("resourceSpecification", resourceSpecs ); + + ServiceOrderInfo serviceOrderInfo = new ServiceOrderInfo(); + serviceOrderInfo.setServiceOrderId("test"); + SubscriberInfo subscriberInfo = new SubscriberInfo(); + subscriberInfo.setGlobalSubscriberId("6490"); + subscriberInfo.setSubscriberName("edgar"); + serviceOrderInfo.setSubscriberInfo(subscriberInfo); + + ServiceOrderItemInfo serviceOrderItemInfoA = new ServiceOrderItemInfo(); + serviceOrderItemInfoA.setId("A"); + serviceOrderItemInfoA.setCatalogResponse(sdcResponse); + + ServiceOrderItemInfo serviceOrderItemInfoB = new ServiceOrderItemInfo(); + serviceOrderItemInfoB.setId("B"); + serviceOrderItemInfoB.setCatalogResponse(sdcResponse); + serviceOrderInfo.addServiceOrderItemInfos("A", serviceOrderItemInfoA); + serviceOrderInfo.addServiceOrderItemInfos("B", serviceOrderItemInfoB); + + String json = JsonEntityConverter.convertServiceOrderInfoToJson(serviceOrderInfo); + + ExecutionTask executionTaskA = new ExecutionTask(); + executionTaskA.setNbRetries(3); + executionTaskA.setOrderItemId("A"); + executionTaskA.setServiceOrderInfoJson(json); + executionTaskA = executionTaskRepository.save(executionTaskA); + ExecutionTask executionTaskB = new ExecutionTask(); + executionTaskB.setNbRetries(3); + executionTaskB.setOrderItemId("B"); + executionTaskB.setReliedTasks(String.valueOf(executionTaskA.getInternalId())); + executionTaskB.setServiceOrderInfoJson(json); + executionTaskRepository.save(executionTaskB); + return executionTaskA; + } } diff --git a/src/test/resources/mappings/so_e2e_delete_service_instance.json b/src/test/resources/mappings/so_e2e_delete_service_instance.json new file mode 100644 index 0000000..0b0615c --- /dev/null +++ b/src/test/resources/mappings/so_e2e_delete_service_instance.json @@ -0,0 +1,15 @@ +{ + "request": { + "method": "DELETE", + "url": "/ecomp/mso/infra/e2eServiceInstances/v3/e4688e5f-61a0-4f8b-ae02-a2fbde623bcb" + }, + "response": { + "status": 202, + "headers": { + "Content-Type": "application/json" + }, + "jsonBody": { + "operationId": "operationId" + } + } +} diff --git a/src/test/resources/mappings/so_get_e2e.json b/src/test/resources/mappings/so_get_e2e.json new file mode 100644 index 0000000..e3bb36e --- /dev/null +++ b/src/test/resources/mappings/so_get_e2e.json @@ -0,0 +1,25 @@ +{ +"request": { + "method": "GET", + "url": "/ecomp/mso/infra/e2eServiceInstances/v3/serviceId/operations/operationId" + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "jsonBody": { + "operation": { + "operationId": "operationid", + "operation": "create", + "result": "finished", + "reason": "", + "userid": "", + "operationContent": "Creating E2E SOTN Service", + "progress": 100, + "operateAt": "", + "finishedAt": "" + } + } + } +} diff --git a/src/test/resources/mappings/so_get_e2e_delete.json b/src/test/resources/mappings/so_get_e2e_delete.json new file mode 100644 index 0000000..f6bc117 --- /dev/null +++ b/src/test/resources/mappings/so_get_e2e_delete.json @@ -0,0 +1,25 @@ +{ + "request": { + "method": "GET", + "url": "/ecomp/mso/infra/e2eServiceInstances/v3/e4688e5f-61a0-4f8b-ae02-a2fbde623bcb/operations/operationId" + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "jsonBody": { + "operation": { + "operationId": "operationid", + "operation": "create", + "result": "finished", + "reason": "", + "userid": "", + "operationContent": "Creating E2E SOTN Service", + "progress": 100, + "operateAt": "", + "finishedAt": "" + } + } + } +} diff --git a/src/test/resources/mappings/so_post_e2e_create_service_instance.json b/src/test/resources/mappings/so_post_e2e_create_service_instance.json new file mode 100644 index 0000000..a5b7cce --- /dev/null +++ b/src/test/resources/mappings/so_post_e2e_create_service_instance.json @@ -0,0 +1,18 @@ +{ + "request": { + "method": "POST", + "url": "/ecomp/mso/infra/e2eServiceInstances/v3" + }, + "response": { + "status": 201, + "headers": { + "Content-Type": "application/json" + }, + "jsonBody": { + "service": { + "serviceId": "serviceId", + "operationId": "operationId" + } + } + } +} -- cgit 1.2.3-korg