From 04c38573e429568b382664a572c5009603de5972 Mon Sep 17 00:00:00 2001 From: "waqas.ikram" Date: Fri, 2 Aug 2019 17:36:09 +0000 Subject: [PATCH] Adding operations endpoint for sdn-c simulator Change-Id: I02d6e988ff0f307bb8590eb3634505a01d656ea1 Issue-ID: SO-1950 Signed-off-by: waqas.ikram --- .../sdcsimulator/controller/CatalogController.java | 4 +- .../controller/SdcSimulatorController.java | 8 +- .../so-simulators/sdnc-simulator/pom.xml | 20 ++ .../configration/ApplicationConfigration.java | 48 +++++ .../controller/OperationsController.java | 80 ++++++++ .../controller/SdncSimulatorController.java | 8 +- .../onap/so/sdncsimulator/models/InputRequest.java | 52 ++++++ .../so/sdncsimulator/models/OutputRequest.java | 155 ++++++++++++++++ .../providers/AbstractCacheServiceProvider.java | 54 ++++++ .../ServiceOperationsCacheServiceProvider.java | 42 +++++ .../ServiceOperationsCacheServiceProviderimpl.java | 204 +++++++++++++++++++++ .../org/onap/so/sdncsimulator/utils/Constants.java | 13 +- .../onap/so/sdncsimulator/utils/ObjectUtils.java | 42 +++++ .../controller/OperationsControllerTest.java | 161 ++++++++++++++++ .../src/test/resources/test-data/InvalidInput.json | 27 +++ .../src/test/resources/test-data/input.json | 28 +++ 16 files changed, 937 insertions(+), 9 deletions(-) create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/configration/ApplicationConfigration.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/OperationsController.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/InputRequest.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/OutputRequest.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/AbstractCacheServiceProvider.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProvider.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProviderimpl.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/utils/ObjectUtils.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/java/org/onap/so/sdncsimulator/controller/OperationsControllerTest.java create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/resources/test-data/InvalidInput.json create mode 100644 plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/resources/test-data/input.json diff --git a/plans/so/integration-etsi-testing/so-simulators/sdc-simulator/src/main/java/org/onap/so/sdcsimulator/controller/CatalogController.java b/plans/so/integration-etsi-testing/so-simulators/sdc-simulator/src/main/java/org/onap/so/sdcsimulator/controller/CatalogController.java index e9f17762..60c1865d 100644 --- a/plans/so/integration-etsi-testing/so-simulators/sdc-simulator/src/main/java/org/onap/so/sdcsimulator/controller/CatalogController.java +++ b/plans/so/integration-etsi-testing/so-simulators/sdc-simulator/src/main/java/org/onap/so/sdcsimulator/controller/CatalogController.java @@ -28,16 +28,16 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; /** * @author Waqas Ikram (waqas.ikram@est.tech) * */ -@RestController +@Controller @RequestMapping(path = CATALOG_URL) public class CatalogController { private static final Logger LOGGER = LoggerFactory.getLogger(CatalogController.class); diff --git a/plans/so/integration-etsi-testing/so-simulators/sdc-simulator/src/main/java/org/onap/so/sdcsimulator/controller/SdcSimulatorController.java b/plans/so/integration-etsi-testing/so-simulators/sdc-simulator/src/main/java/org/onap/so/sdcsimulator/controller/SdcSimulatorController.java index 4cd564d4..662c0bda 100644 --- a/plans/so/integration-etsi-testing/so-simulators/sdc-simulator/src/main/java/org/onap/so/sdcsimulator/controller/SdcSimulatorController.java +++ b/plans/so/integration-etsi-testing/so-simulators/sdc-simulator/src/main/java/org/onap/so/sdcsimulator/controller/SdcSimulatorController.java @@ -25,20 +25,22 @@ import org.onap.so.sdcsimulator.utils.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; /** * @author Waqas Ikram (waqas.ikram@est.tech) */ -@RestController +@Controller @RequestMapping(path = Constants.BASE_URL) public class SdcSimulatorController { private static final Logger LOGGER = LoggerFactory.getLogger(SdcSimulatorController.class); - @GetMapping(value = "/healthcheck", produces = MediaType.APPLICATION_JSON) + @ResponseBody + @GetMapping(value = "/healthcheck", produces = MediaType.TEXT_PLAIN) @ResponseStatus(code = HttpStatus.OK) public String healthCheck() { LOGGER.info("Running health check ..."); diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/pom.xml b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/pom.xml index 8e947e62..22994ff0 100644 --- a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/pom.xml +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/pom.xml @@ -8,6 +8,26 @@ sdnc-simulator ${project.artifactId} + + 1.5.2 + + + + org.onap.sdnc.northbound + generic-resource-api-client + ${version.generic-resource-api-client} + + + javax.ws.rs + jsr311-api + + + org.json + json + + + + diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/configration/ApplicationConfigration.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/configration/ApplicationConfigration.java new file mode 100644 index 00000000..d51bd023 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/configration/ApplicationConfigration.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.sdncsimulator.configration; + +import static org.onap.so.sdncsimulator.utils.Constants.SERVICE_TOPOLOGY_OPERATION_CACHE; +import java.util.Arrays; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.concurrent.ConcurrentMapCache; +import org.springframework.cache.support.SimpleCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Configuration +public class ApplicationConfigration { + + @Bean + public CacheManager cacheManager() { + final SimpleCacheManager manager = new SimpleCacheManager(); + manager.setCaches(Arrays.asList(getCache(SERVICE_TOPOLOGY_OPERATION_CACHE))); + return manager; + } + + private Cache getCache(final String name) { + return new ConcurrentMapCache(name); + } +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/OperationsController.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/OperationsController.java new file mode 100644 index 00000000..03fbe7ef --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/OperationsController.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.sdncsimulator.controller; + +import static org.onap.so.sdncsimulator.utils.Constants.OPERATIONS_URL; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.MediaType; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServiceOperationInformation; +import org.onap.so.sdncsimulator.models.InputRequest; +import org.onap.so.sdncsimulator.models.OutputRequest; +import org.onap.so.sdncsimulator.providers.ServiceOperationsCacheServiceProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Controller +@RequestMapping(path = OPERATIONS_URL) +public class OperationsController { + + private static final Logger LOGGER = LoggerFactory.getLogger(OperationsController.class); + + private final ServiceOperationsCacheServiceProvider cacheServiceProvider; + + @Autowired + public OperationsController(final ServiceOperationsCacheServiceProvider cacheServiceProvider) { + this.cacheServiceProvider = cacheServiceProvider; + } + + @PostMapping(value = "/GENERIC-RESOURCE-API:service-topology-operation/", + produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public ResponseEntity postServiceOperationInformation( + @RequestBody final InputRequest inputRequest, + final HttpServletRequest request) { + LOGGER.info("Request Received {} ...", inputRequest); + + final GenericResourceApiServiceOperationInformation apiServiceOperationInformation = inputRequest.getInput(); + + if (apiServiceOperationInformation == null) { + return ResponseEntity.badRequest().build(); + } + + final OutputRequest outputRequest = + cacheServiceProvider.putServiceOperationInformation(apiServiceOperationInformation); + + if (outputRequest.getResponseCode().equals(HttpStatus.OK.toString())) { + return ResponseEntity.ok(outputRequest); + } + + return ResponseEntity.badRequest().body(outputRequest); + + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/SdncSimulatorController.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/SdncSimulatorController.java index fbe2d281..98655e10 100644 --- a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/SdncSimulatorController.java +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/controller/SdncSimulatorController.java @@ -24,21 +24,23 @@ import org.onap.so.sdncsimulator.utils.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; /** * @author Waqas Ikram (waqas.ikram@est.tech) * */ -@RestController +@Controller @RequestMapping(path = Constants.BASE_URL) public class SdncSimulatorController { private static final Logger LOGGER = LoggerFactory.getLogger(SdncSimulatorController.class); - @GetMapping(value = "/healthcheck", produces = MediaType.APPLICATION_JSON) + @ResponseBody + @GetMapping(value = "/healthcheck", produces = MediaType.TEXT_PLAIN) @ResponseStatus(code = HttpStatus.OK) public String healthCheck() { LOGGER.info("Running health check ..."); diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/InputRequest.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/InputRequest.java new file mode 100644 index 00000000..d4e83fce --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/InputRequest.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.sdncsimulator.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class InputRequest { + + private T input; + + /** + * @return the input + */ + public T getInput() { + return input; + } + + /** + * @param input the input to set + */ + public void setInput(final T input) { + this.input = input; + } + + @JsonIgnore + @Override + public String toString() { + return "Input [input=" + input + "]"; + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/OutputRequest.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/OutputRequest.java new file mode 100644 index 00000000..75395235 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/models/OutputRequest.java @@ -0,0 +1,155 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.sdncsimulator.models; + +import org.onap.sdnc.northbound.client.model.GenericResourceApiInstanceReference; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@JsonRootName("output") +public class OutputRequest { + + @JsonProperty("response-message") + private String responseMessage; + + @JsonProperty("ack-final-indicator") + private String ackFinalIndicator; + + @JsonProperty("svc-request-id") + private String svcRequestId; + + @JsonProperty("response-code") + private String responseCode; + + @JsonProperty("service-response-information") + private GenericResourceApiInstanceReference serviceResponseInformation = null; + + /** + * @return the responseMessage + */ + public String getResponseMessage() { + return responseMessage; + } + + /** + * @param responseMessage the responseMessage to set + */ + public void setResponseMessage(final String responseMessage) { + this.responseMessage = responseMessage; + } + + /** + * @return the ackFinalIndicator + */ + public String getAckFinalIndicator() { + return ackFinalIndicator; + } + + /** + * @param ackFinalIndicator the ackFinalIndicator to set + */ + public void setAckFinalIndicator(final String ackFinalIndicator) { + this.ackFinalIndicator = ackFinalIndicator; + } + + /** + * @return the svcRequestId + */ + public String getSvcRequestId() { + return svcRequestId; + } + + /** + * @param svcRequestId the svcRequestId to set + */ + public void setSvcRequestId(final String svcRequestId) { + this.svcRequestId = svcRequestId; + } + + /** + * @return the responseCode + */ + public String getResponseCode() { + return responseCode; + } + + /** + * @param responseCode the responseCode to set + */ + public void setResponseCode(final String responseCode) { + this.responseCode = responseCode; + } + + /** + * @return the serviceResponseInformation + */ + public GenericResourceApiInstanceReference getServiceResponseInformation() { + return serviceResponseInformation; + } + + /** + * @param serviceResponseInformation the serviceResponseInformation to set + */ + public void setServiceResponseInformation(final GenericResourceApiInstanceReference serviceResponseInformation) { + this.serviceResponseInformation = serviceResponseInformation; + } + + public OutputRequest responseMessage(final String responseMessage) { + this.responseMessage = responseMessage; + return this; + } + + public OutputRequest ackFinalIndicator(final String ackFinalIndicator) { + this.ackFinalIndicator = ackFinalIndicator; + return this; + } + + public OutputRequest svcRequestId(final String svcRequestId) { + this.svcRequestId = svcRequestId; + return this; + } + + public OutputRequest responseCode(final String responseCode) { + this.responseCode = responseCode; + return this; + } + + public OutputRequest serviceResponseInformation( + final GenericResourceApiInstanceReference serviceResponseInformation) { + this.serviceResponseInformation = serviceResponseInformation; + return this; + } + + + @JsonIgnore + @Override + public String toString() { + return "OutputRequest [responseMessage=" + responseMessage + ", ackFinalIndicator=" + ackFinalIndicator + + ", svcRequestId=" + svcRequestId + ", responseCode=" + responseCode + ", serviceResponseInformation=" + + serviceResponseInformation + "]"; + } + + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/AbstractCacheServiceProvider.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/AbstractCacheServiceProvider.java new file mode 100644 index 00000000..55e6f541 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/AbstractCacheServiceProvider.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.sdncsimulator.providers; + +import java.util.concurrent.ConcurrentHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + */ +public abstract class AbstractCacheServiceProvider { + + private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + + private final CacheManager cacheManager; + + public AbstractCacheServiceProvider(final CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + protected void clearCahce(final String name) { + final Cache cache = cacheManager.getCache(name); + if (cache != null) { + final ConcurrentHashMap nativeCache = (ConcurrentHashMap) cache.getNativeCache(); + LOGGER.info("Clear all entries from cahce: {}", cache.getName()); + nativeCache.clear(); + } + } + + protected Cache getCache(final String name) { + return cacheManager.getCache(name); + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProvider.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProvider.java new file mode 100644 index 00000000..5194d499 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProvider.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.sdncsimulator.providers; + +import java.util.Optional; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServiceModelInfrastructure; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServiceOperationInformation; +import org.onap.so.sdncsimulator.models.OutputRequest; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface ServiceOperationsCacheServiceProvider { + + OutputRequest putServiceOperationInformation( + final GenericResourceApiServiceOperationInformation apiServiceOperationInformation); + + Optional getGenericResourceApiServiceModelInfrastructure( + final String serviceInstanceId); + + void clearAll(); + + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProviderimpl.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProviderimpl.java new file mode 100644 index 00000000..9436d224 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/providers/ServiceOperationsCacheServiceProviderimpl.java @@ -0,0 +1,204 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.sdncsimulator.providers; + +import static org.onap.so.sdncsimulator.utils.Constants.RESTCONF_CONFIG_END_POINT; +import static org.onap.so.sdncsimulator.utils.Constants.SERVICE_TOPOLOGY_OPERATION; +import static org.onap.so.sdncsimulator.utils.Constants.SERVICE_TOPOLOGY_OPERATION_CACHE; +import static org.onap.so.sdncsimulator.utils.Constants.YES; +import static org.onap.so.sdncsimulator.utils.ObjectUtils.getString; +import static org.onap.so.sdncsimulator.utils.ObjectUtils.getStringOrNull; +import static org.onap.so.sdncsimulator.utils.ObjectUtils.isValid; +import java.time.LocalDateTime; +import java.util.Optional; +import org.onap.sdnc.northbound.client.model.GenericResourceApiInstanceReference; +import org.onap.sdnc.northbound.client.model.GenericResourceApiLastActionEnumeration; +import org.onap.sdnc.northbound.client.model.GenericResourceApiLastRpcActionEnumeration; +import org.onap.sdnc.northbound.client.model.GenericResourceApiOnapmodelinformationOnapModelInformation; +import org.onap.sdnc.northbound.client.model.GenericResourceApiOperStatusData; +import org.onap.sdnc.northbound.client.model.GenericResourceApiOrderStatusEnumeration; +import org.onap.sdnc.northbound.client.model.GenericResourceApiRequestStatusEnumeration; +import org.onap.sdnc.northbound.client.model.GenericResourceApiRequestinformationRequestInformation; +import org.onap.sdnc.northbound.client.model.GenericResourceApiRpcActionEnumeration; +import org.onap.sdnc.northbound.client.model.GenericResourceApiSdncrequestheaderSdncRequestHeader; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServiceModelInfrastructure; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServiceOperationInformation; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServicedataServiceData; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServiceinformationServiceInformation; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServicemodelinfrastructureService; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServicestatusServiceStatus; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServicetopologyServiceTopology; +import org.onap.sdnc.northbound.client.model.GenericResourceApiServicetopologyidentifierServiceTopologyIdentifier; +import org.onap.so.sdncsimulator.models.OutputRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class ServiceOperationsCacheServiceProviderimpl extends AbstractCacheServiceProvider + implements ServiceOperationsCacheServiceProvider { + + + private static final Logger LOGGER = LoggerFactory.getLogger(ServiceOperationsCacheServiceProviderimpl.class); + + @Autowired + public ServiceOperationsCacheServiceProviderimpl(final CacheManager cacheManager) { + super(cacheManager); + } + + @Override + public OutputRequest putServiceOperationInformation(final GenericResourceApiServiceOperationInformation input) { + + final GenericResourceApiSdncrequestheaderSdncRequestHeader requestHeader = input.getSdncRequestHeader(); + final String svcRequestId = requestHeader != null ? requestHeader.getSvcRequestId() : null; + + final GenericResourceApiServiceinformationServiceInformation serviceInformation = input.getServiceInformation(); + if (serviceInformation != null && isValid(serviceInformation.getServiceInstanceId())) { + final Cache cache = getCache(SERVICE_TOPOLOGY_OPERATION_CACHE); + final String serviceInstanceId = serviceInformation.getServiceInstanceId(); + LOGGER.info("Adding GenericResourceApiServiceOperationInformation to cache with key: {}", + serviceInstanceId); + + final GenericResourceApiServiceModelInfrastructure serviceModelInfrastructure = + new GenericResourceApiServiceModelInfrastructure(); + + final GenericResourceApiServicemodelinfrastructureService service = getServiceItem(input); + serviceModelInfrastructure.addServiceItem(service); + cache.put(serviceInstanceId, serviceModelInfrastructure); + + final GenericResourceApiServicestatusServiceStatus serviceStatus = service.getServiceStatus(); + + return new OutputRequest().ackFinalIndicator(serviceStatus.getFinalIndicator()) + .responseCode(serviceStatus.getResponseCode()).responseMessage(serviceStatus.getResponseMessage()) + .svcRequestId(svcRequestId).serviceResponseInformation(new GenericResourceApiInstanceReference() + .instanceId(serviceInstanceId).objectPath(RESTCONF_CONFIG_END_POINT + serviceInstanceId)); + + } + return new OutputRequest().ackFinalIndicator(YES).responseCode(HttpStatus.BAD_REQUEST.toString()) + .responseMessage("Service instance not found").svcRequestId(svcRequestId); + } + + @Override + public Optional getGenericResourceApiServiceModelInfrastructure( + final String serviceInstanceId) { + final Cache cache = getCache(SERVICE_TOPOLOGY_OPERATION_CACHE); + + final GenericResourceApiServiceModelInfrastructure value = + cache.get(serviceInstanceId, GenericResourceApiServiceModelInfrastructure.class); + if (value != null) { + return Optional.of(value); + } + return Optional.empty(); + } + + @Override + public void clearAll() { + clearCahce(SERVICE_TOPOLOGY_OPERATION_CACHE); + } + + private GenericResourceApiServicemodelinfrastructureService getServiceItem( + final GenericResourceApiServiceOperationInformation input) { + + final GenericResourceApiServicedataServiceData apiServicedataServiceData = + new GenericResourceApiServicedataServiceData(); + + apiServicedataServiceData.requestInformation(input.getRequestInformation()); + apiServicedataServiceData.serviceRequestInput(input.getServiceRequestInput()); + apiServicedataServiceData.serviceInformation(input.getServiceInformation()); + apiServicedataServiceData.serviceTopology(getServiceTopology(input)); + apiServicedataServiceData.sdncRequestHeader(input.getSdncRequestHeader()); + apiServicedataServiceData.serviceLevelOperStatus(getServiceLevelOperStatus(input)); + + final GenericResourceApiServicestatusServiceStatus serviceStatus = + getServiceStatus(getSvcAction(input.getSdncRequestHeader()), getAction(input.getRequestInformation()), + HttpStatus.OK.toString()); + + return new GenericResourceApiServicemodelinfrastructureService().serviceData(apiServicedataServiceData) + .serviceStatus(serviceStatus); + } + + private String getAction(final GenericResourceApiRequestinformationRequestInformation input) { + return getString(input.getRequestAction(), ""); + } + + private String getSvcAction(final GenericResourceApiSdncrequestheaderSdncRequestHeader input) { + return input != null ? getStringOrNull(input.getSvcAction()) : null; + } + + private GenericResourceApiServicestatusServiceStatus getServiceStatus(final String rpcAction, final String action, + final String responseCode) { + return new GenericResourceApiServicestatusServiceStatus().finalIndicator(YES) + .rpcAction(GenericResourceApiRpcActionEnumeration.fromValue(rpcAction)) + .rpcName(SERVICE_TOPOLOGY_OPERATION).responseTimestamp(LocalDateTime.now().toString()) + .responseCode(responseCode).requestStatus(GenericResourceApiRequestStatusEnumeration.SYNCCOMPLETE) + .responseMessage("").action(action); + } + + private GenericResourceApiOperStatusData getServiceLevelOperStatus( + final GenericResourceApiServiceOperationInformation input) { + return new GenericResourceApiOperStatusData().orderStatus(GenericResourceApiOrderStatusEnumeration.CREATED) + .lastAction(GenericResourceApiLastActionEnumeration + .fromValue(getRequestAction(input.getRequestInformation()))) + .lastRpcAction(GenericResourceApiLastRpcActionEnumeration + .fromValue(getSvcAction(input.getSdncRequestHeader()))); + } + + private String getRequestAction(final GenericResourceApiRequestinformationRequestInformation input) { + return input != null ? getStringOrNull(input.getRequestAction()) : null; + } + + private GenericResourceApiServicetopologyServiceTopology getServiceTopology( + final GenericResourceApiServiceOperationInformation input) { + final GenericResourceApiOnapmodelinformationOnapModelInformation modelInformation = + input.getServiceInformation() != null ? input.getServiceInformation().getOnapModelInformation() : null; + return new GenericResourceApiServicetopologyServiceTopology().onapModelInformation(modelInformation) + .serviceTopologyIdentifier(getServiceTopologyIdentifier(input)); + } + + private GenericResourceApiServicetopologyidentifierServiceTopologyIdentifier getServiceTopologyIdentifier( + final GenericResourceApiServiceOperationInformation input) { + final GenericResourceApiServicetopologyidentifierServiceTopologyIdentifier identifier = + new GenericResourceApiServicetopologyidentifierServiceTopologyIdentifier(); + + if (input.getServiceInformation() != null) { + final GenericResourceApiServiceinformationServiceInformation serviceInformation = + input.getServiceInformation(); + identifier.globalCustomerId(serviceInformation.getGlobalCustomerId()) + .serviceType(input.getServiceInformation().getSubscriptionServiceType()) + .serviceInstanceId(input.getServiceInformation().getServiceInstanceId());; + } + + if (input.getServiceRequestInput() != null) { + identifier.serviceInstanceName(input.getServiceRequestInput().getServiceInstanceName()); + } + + return identifier; + + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/utils/Constants.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/utils/Constants.java index 32f31356..2d774edd 100644 --- a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/utils/Constants.java +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/utils/Constants.java @@ -24,9 +24,20 @@ package org.onap.so.sdncsimulator.utils; * */ public class Constants { - public static final String BASE_URL = "/restconf/"; + + public static final String BASE_URL = "/restconf"; + + public static final String OPERATIONS_URL = BASE_URL + "/operations"; + + public static final String SERVICE_TOPOLOGY_OPERATION_CACHE = "service-topology-operation-cache"; public static final String HEALTHY = "healthy"; + public static final String YES = "Y"; + + public static final String SERVICE_TOPOLOGY_OPERATION = "service-topology-operation"; + + public static final String RESTCONF_CONFIG_END_POINT = "restconf/config/GENERIC-RESOURCE-API:services/service/"; + private Constants() {} } diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/utils/ObjectUtils.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/utils/ObjectUtils.java new file mode 100644 index 00000000..833da414 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/main/java/org/onap/so/sdncsimulator/utils/ObjectUtils.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.sdncsimulator.utils; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class ObjectUtils { + + public static boolean isValid(final String value) { + return value != null && !value.isEmpty(); + } + + public static String getStringOrNull(final Object obj) { + return getString(obj, null); + } + + public static String getString(final Object obj, String defaultValue) { + return obj != null ? obj.toString() : defaultValue; + } + + private ObjectUtils() {} + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/java/org/onap/so/sdncsimulator/controller/OperationsControllerTest.java b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/java/org/onap/so/sdncsimulator/controller/OperationsControllerTest.java new file mode 100644 index 00000000..36e12089 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/java/org/onap/so/sdncsimulator/controller/OperationsControllerTest.java @@ -0,0 +1,161 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.so.sdncsimulator.controller; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.sdnc.northbound.client.model.GenericResourceApiInstanceReference; +import org.onap.so.sdncsimulator.models.InputRequest; +import org.onap.so.sdncsimulator.models.OutputRequest; +import org.onap.so.sdncsimulator.providers.ServiceOperationsCacheServiceProvider; +import org.onap.so.sdncsimulator.utils.Constants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ActiveProfiles("test") +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@Configuration +public class OperationsControllerTest { + + private static final String SVC_REQUEST_ID = "04fc9f50-87b8-430d-a232-ef24bd6c4150"; + + private static final String SERVICE_INSTANCE_ID = "ccece8fe-13da-456a-baf6-41b3a4a2bc2b"; + + private static final String SERVICE_TOPOLOGY_OPERATION_URL = "/GENERIC-RESOURCE-API:service-topology-operation/"; + + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate restTemplate; + + @Autowired + private ServiceOperationsCacheServiceProvider cacheServiceProvider; + + @Test + public void test_postServiceOperationInformation_successfullyAddedToCache() throws Exception { + + final HttpEntity httpEntity = new HttpEntity<>(getRequestInput(), getHttpHeaders()); + final ResponseEntity responseEntity = + restTemplate.exchange(getUrl(), HttpMethod.POST, httpEntity, OutputRequest.class); + + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertTrue(responseEntity.hasBody()); + final OutputRequest actualObject = responseEntity.getBody(); + assertNotNull(actualObject); + + assertEquals(HttpStatus.OK.toString(), actualObject.getResponseCode()); + assertEquals(Constants.YES, actualObject.getAckFinalIndicator()); + assertEquals(SVC_REQUEST_ID, actualObject.getSvcRequestId()); + assertNotNull(actualObject.getServiceResponseInformation()); + + final GenericResourceApiInstanceReference acutalReference = actualObject.getServiceResponseInformation(); + assertEquals(Constants.RESTCONF_CONFIG_END_POINT + SERVICE_INSTANCE_ID, acutalReference.getObjectPath()); + assertEquals(SERVICE_INSTANCE_ID, acutalReference.getInstanceId()); + assertTrue( + cacheServiceProvider.getGenericResourceApiServiceModelInfrastructure(SERVICE_INSTANCE_ID).isPresent()); + } + + @Test + public void test_postServiceOperationInformation_NullInputRequest_badRequest() throws Exception { + + final HttpEntity httpEntity = new HttpEntity<>(new InputRequest<>(), getHttpHeaders()); + final ResponseEntity responseEntity = + restTemplate.exchange(getUrl(), HttpMethod.POST, httpEntity, OutputRequest.class); + + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + } + + @Test + public void test_postServiceOperationInformation_NullServiceInstanceId_badRequest() throws Exception { + + final HttpEntity httpEntity = new HttpEntity<>(getInvalidRequestInput(), getHttpHeaders()); + final ResponseEntity responseEntity = + restTemplate.exchange(getUrl(), HttpMethod.POST, httpEntity, OutputRequest.class); + + assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); + assertTrue(responseEntity.hasBody()); + final OutputRequest actualObject = responseEntity.getBody(); + + assertEquals(HttpStatus.BAD_REQUEST.toString(), actualObject.getResponseCode()); + assertEquals(SVC_REQUEST_ID, actualObject.getSvcRequestId()); + assertEquals(Constants.YES, actualObject.getAckFinalIndicator()); + + } + + private HttpHeaders getHttpHeaders() { + final HttpHeaders requestHeaders = new HttpHeaders(); + requestHeaders.setContentType(MediaType.APPLICATION_JSON); + return requestHeaders; + } + + + private String getUrl() { + return "http://localhost:" + port + Constants.OPERATIONS_URL + SERVICE_TOPOLOGY_OPERATION_URL; + } + + private String getRequestInput() throws IOException { + return getFileAsString(getFile("test-data/input.json").toPath()); + } + + private String getInvalidRequestInput() throws IOException { + return getFileAsString(getFile("test-data/InvalidInput.json").toPath()); + } + + private String getFileAsString(final Path path) throws IOException { + return new String(Files.readAllBytes(path)); + } + + private static File getFile(final String file) throws IOException { + return new ClassPathResource(file).getFile(); + } + + @After + public void after() { + cacheServiceProvider.clearAll(); + } + +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/resources/test-data/InvalidInput.json b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/resources/test-data/InvalidInput.json new file mode 100644 index 00000000..6f2d27d4 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/resources/test-data/InvalidInput.json @@ -0,0 +1,27 @@ +{ + "input": { + "request-information": { + "request-action": "CreateServiceInstance", + "source": "MSO", + "request-id": "33ebd358-a189-4664-90f5-cf9e23658e0a" + }, + "sdnc-request-header": { + "svc-request-id": "04fc9f50-87b8-430d-a232-ef24bd6c4150", + "svc-action": "assign" + }, + "service-information": { + "onap-model-information": { + "model-name": "Sol004Zip3Service", + "model-version": "2.0", + "model-uuid": "c112a499-6148-488b-ba82-3f5938cf26d2", + "model-invariant-uuid": "e9acd081-9c89-4b4d-bcb3-e0e2b9715b2a" + }, + "subscription-service-type": "vCPE", + "service-id": "ccece8fe-13da-456a-baf6-41b3a4a2bc2b", + "global-customer-id": "NordixDemoCustomer" + }, + "service-request-input": { + "service-instance-name": "ServiceTest_24_07_2019" + } + } +} diff --git a/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/resources/test-data/input.json b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/resources/test-data/input.json new file mode 100644 index 00000000..8d42b620 --- /dev/null +++ b/plans/so/integration-etsi-testing/so-simulators/sdnc-simulator/src/test/resources/test-data/input.json @@ -0,0 +1,28 @@ +{ + "input": { + "request-information": { + "request-action": "CreateServiceInstance", + "source": "MSO", + "request-id": "33ebd358-a189-4664-90f5-cf9e23658e0a" + }, + "sdnc-request-header": { + "svc-request-id": "04fc9f50-87b8-430d-a232-ef24bd6c4150", + "svc-action": "assign" + }, + "service-information": { + "onap-model-information": { + "model-name": "Sol004Zip3Service", + "model-version": "2.0", + "model-uuid": "c112a499-6148-488b-ba82-3f5938cf26d2", + "model-invariant-uuid": "e9acd081-9c89-4b4d-bcb3-e0e2b9715b2a" + }, + "subscription-service-type": "vCPE", + "service-id": "ccece8fe-13da-456a-baf6-41b3a4a2bc2b", + "global-customer-id": "NordixDemoCustomer", + "service-instance-id": "ccece8fe-13da-456a-baf6-41b3a4a2bc2b" + }, + "service-request-input": { + "service-instance-name": "ServiceTest_24_07_2019" + } + } +} -- 2.16.6