summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthieuGeerebaert <matthieu.geerebaert@orange.com>2018-03-28 13:36:26 +0200
committerMatthieuGeerebaert <matthieu.geerebaert@orange.com>2018-04-03 23:35:04 +0200
commit99bf586a6eb9799c4f33e43976d741f2807ea287 (patch)
tree817406c30c99f366c000afc3fe0963b6b32499e7
parent65fd3da0ea090f3c1fc82cea0c49547dbf362fcf (diff)
Add serviceCatalog rest services
- Add get and find serviceSpecification operations - Add API exceptions management - Consumes SDC apis - Add tests - Fix pom.xml conflict Change-Id: Id103d83dc8a981885100daabe868cdf18a922975 Issue-ID: EXTAPI-39 Signed-off-by: MatthieuGeerebaert <matthieu.geerebaert@orange.com>
-rw-r--r--pom.xml162
-rw-r--r--src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java29
-rw-r--r--src/main/java/org/onap/nbi/apis/RestConfiguration.java18
-rw-r--r--src/main/java/org/onap/nbi/apis/servicecatalog/SdcClient.java145
-rw-r--r--src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java46
-rw-r--r--src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationService.java51
-rw-r--r--src/main/java/org/onap/nbi/apis/servicecatalog/ToscaInfosProcessor.java249
-rw-r--r--src/main/java/org/onap/nbi/apis/servicecatalog/jolt/FindServiceSpecJsonTransformer.java36
-rw-r--r--src/main/java/org/onap/nbi/apis/servicecatalog/jolt/GetServiceSpecJsonTransformer.java37
-rw-r--r--src/main/java/org/onap/nbi/exceptions/ApiError.java67
-rw-r--r--src/main/java/org/onap/nbi/exceptions/ApiException.java33
-rw-r--r--src/main/java/org/onap/nbi/exceptions/ApiExceptionHandler.java46
-rw-r--r--src/main/java/org/onap/nbi/exceptions/BackendErrorHandler.java24
-rw-r--r--src/main/java/org/onap/nbi/exceptions/BackendFunctionalException.java22
-rw-r--r--src/main/java/org/onap/nbi/exceptions/TechnicalException.java26
-rw-r--r--src/main/java/org/onap/nbi/exceptions/ValidationException.java32
-rw-r--r--src/main/resources/application-localhost.properties7
-rw-r--r--src/main/resources/application.properties3
-rw-r--r--src/main/resources/jolt/findServiceCatalog.json28
-rw-r--r--src/main/resources/jolt/getServiceCatalog.json77
-rw-r--r--src/test/java/org/onap/nbi/apis/resources/ApiTest.java89
-rw-r--r--src/test/java/org/onap/nbi/apis/resources/ServiceCatalogAssertions.java135
-rw-r--r--src/test/java/org/onap/nbi/apis/resources/StatusResourceTest.java (renamed from src/test/java/org/onap/nbi/apis/status/StatusTest.java)5
-rw-r--r--src/test/resources/application.properties13
-rw-r--r--src/test/resources/mappings/sdc_find.json244
-rw-r--r--src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439.json213
-rw-r--r--src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439_tosca.json10
-rw-r--r--src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439_withoutTosca.json213
28 files changed, 2001 insertions, 59 deletions
diff --git a/pom.xml b/pom.xml
index b537ac2..2d04270 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,10 +20,10 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <nexusproxy>https://nexus.onap.org</nexusproxy>
- <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
- <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
- <stagingNexusPath>/content/repositories/staging/</stagingNexusPath>
+ <nexusproxy>https://nexus.onap.org</nexusproxy>
+ <snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
+ <releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
+ <stagingNexusPath>/content/repositories/staging/</stagingNexusPath>
<java.version>1.8</java.version>
</properties>
@@ -34,37 +34,37 @@
<url>http://download.java.net/maven/2/</url>
<layout>default</layout>
</repository>
- <repository>
- <id>ecomp-snapshots</id>
- <name>Snapshot Repository</name>
- <url>${nexusproxy}/${snapshotNexusPath}</url>
- </repository>
- <repository>
- <id>ecomp-staging</id>
- <name>Staging Repository</name>
- <url>${nexusproxy}/${stagingNexusPath}</url>
- </repository>
+ <repository>
+ <id>ecomp-snapshots</id>
+ <name>Snapshot Repository</name>
+ <url>${nexusproxy}/${snapshotNexusPath}</url>
+ </repository>
+ <repository>
+ <id>ecomp-staging</id>
+ <name>Staging Repository</name>
+ <url>${nexusproxy}/${stagingNexusPath}</url>
+ </repository>
</repositories>
- <distributionManagement>
- <repository>
- <id>ecomp-releases</id>
- <name>Release Repository</name>
- <url>${nexusproxy}/${releaseNexusPath}</url>
- </repository>
- <snapshotRepository>
- <id>ecomp-snapshots</id>
- <name>Snapshot Repository</name>
- <url>${nexusproxy}/${snapshotNexusPath}</url>
- </snapshotRepository>
- </distributionManagement>
-
+ <distributionManagement>
+ <repository>
+ <id>ecomp-releases</id>
+ <name>Release Repository</name>
+ <url>${nexusproxy}/${releaseNexusPath}</url>
+ </repository>
+ <snapshotRepository>
+ <id>ecomp-snapshots</id>
+ <name>Snapshot Repository</name>
+ <url>${nexusproxy}/${snapshotNexusPath}</url>
+ </snapshotRepository>
+ </distributionManagement>
+
<licenses>
<license>
<name>Apache2</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
- </licenses>
+ </licenses>
<dependencies>
@@ -90,17 +90,67 @@
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
-
- <!-- test -->
-
+
+ <!-- jackson -->
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ <version>2.8.0</version>
+ </dependency>
+
+ <!-- jolt -->
+
+ <dependency>
+ <groupId>com.bazaarvoice.jolt</groupId>
+ <artifactId>jolt-core</artifactId>
+ <version>0.1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.bazaarvoice.jolt</groupId>
+ <artifactId>json-utils</artifactId>
+ <version>0.1.0</version>
+ </dependency>
+
+ <!-- test -->
+
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
-
+
+ <!-- wiremock -->
+
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-contract-wiremock</artifactId>
+ <version>1.0.0.RELEASE</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>9.4.7.RC0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlets</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<!-- runtime dev -->
-
+
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
@@ -115,29 +165,29 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.sonatype.plugins</groupId>
- <artifactId>nexus-staging-maven-plugin</artifactId>
- <version>1.6.7</version>
- <extensions>true</extensions>
- <configuration>
- <nexusUrl>${nexusproxy}</nexusUrl>
- <stagingProfileId>176c31dfe190a</stagingProfileId>
- <serverId>ecomp-staging</serverId>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-site-plugin</artifactId>
- <version>3.6</version>
- <dependencies>
- <dependency>
- <groupId>org.apache.maven.wagon</groupId>
- <artifactId>wagon-webdav-jackrabbit</artifactId>
- <version>2.10</version>
- </dependency>
- </dependencies>
- </plugin>
+ <plugin>
+ <groupId>org.sonatype.plugins</groupId>
+ <artifactId>nexus-staging-maven-plugin</artifactId>
+ <version>1.6.7</version>
+ <extensions>true</extensions>
+ <configuration>
+ <nexusUrl>${nexusproxy}</nexusUrl>
+ <stagingProfileId>176c31dfe190a</stagingProfileId>
+ <serverId>ecomp-staging</serverId>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.6</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-webdav-jackrabbit</artifactId>
+ <version>2.10</version>
+ </dependency>
+ </dependencies>
+ </plugin>
</plugins>
</build>
</project>
diff --git a/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java b/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java
new file mode 100644
index 0000000..5ee6528
--- /dev/null
+++ b/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java
@@ -0,0 +1,29 @@
+package org.onap.nbi;
+
+/**
+ * Contains ONAP SDC and AAI urlPaths
+ *
+ */
+public final class OnapComponentsUrlPaths {
+
+ private OnapComponentsUrlPaths() {}
+
+ // SDC
+ public static final String SDC_ROOT_URL = "/sdc/v1/catalog/services/";
+ public static final String SDC_GET_PATH = "/metadata";
+ public static final String SDC_TOSCA_PATH = "/toscaModel";
+
+ // AAI
+ public static final String AAI_GET_TENANTS_PATH =
+ "/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/$cloudOwner/$lcpCloudRegionId/tenants";
+ public static final String AAI_GET_CUSTOMER_PATH = "/aai/v11/business/customers/customer/";
+ public static final String AAI_GET_SERVICES_FOR_CUSTOMER_PATH =
+ "/aai/v11/business/customers/customer/$customerId/service-subscriptions";
+ public static final String AAI_PUT_SERVICE_FOR_CUSTOMER_PATH =
+ "/aai/v11/business/customers/customer/$customerId/service-subscriptions/service-subscription/";
+ public static final String AAI_GET_SERVICE_FOR_CUSTOMER_PATH =
+ "/aai/v11/business/customers/customer/$customerId/service-subscriptions/service-subscription/$serviceSpecName/service-instances/service-instance/$serviceId";
+ public static final String AAI_GET_SERVICE_INSTANCES_PATH =
+ "/aai/v11/business/customers/customer/$customerId/service-subscriptions/service-subscription/$serviceSpecName/service-instances/";
+
+}
diff --git a/src/main/java/org/onap/nbi/apis/RestConfiguration.java b/src/main/java/org/onap/nbi/apis/RestConfiguration.java
new file mode 100644
index 0000000..8152d6f
--- /dev/null
+++ b/src/main/java/org/onap/nbi/apis/RestConfiguration.java
@@ -0,0 +1,18 @@
+package org.onap.nbi.apis;
+
+import org.onap.nbi.exceptions.BackendErrorHandler;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestConfiguration {
+
+ @Bean
+ public RestTemplate restTemplate(RestTemplateBuilder builder) {
+ RestTemplate restTemplate = builder.build();
+ restTemplate.setErrorHandler(new BackendErrorHandler());
+ return restTemplate;
+ }
+}
diff --git a/src/main/java/org/onap/nbi/apis/servicecatalog/SdcClient.java b/src/main/java/org/onap/nbi/apis/servicecatalog/SdcClient.java
new file mode 100644
index 0000000..abc8bda
--- /dev/null
+++ b/src/main/java/org/onap/nbi/apis/servicecatalog/SdcClient.java
@@ -0,0 +1,145 @@
+package org.onap.nbi.apis.servicecatalog;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.io.IOUtils;
+import org.onap.nbi.OnapComponentsUrlPaths;
+import org.onap.nbi.exceptions.BackendFunctionalException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+/**
+ * @author user
+ *
+ */
+@Service
+public class SdcClient {
+
+ public static final String HTTP_CALL_SDC_ON = "HTTP call SDC on ";
+ @Autowired
+ private RestTemplate restTemplate;
+
+ @Value("${sdc.host}")
+ private String sdcHost;
+
+ @Value("${sdc.header.ecompInstanceId}")
+ private String ecompInstanceId;
+
+ @Value("${sdc.header.authorization}")
+ private String sdcHeaderAuthorization;
+
+ private static final String HEADER_ECOMP_INSTANCE_ID = "x-ecomp-instanceid";
+ private static final String HEADER_AUTHORIZATION = "Authorization";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SdcClient.class);
+
+
+ public LinkedHashMap callGet(String id) {
+ StringBuilder callURL = new StringBuilder().append(sdcHost).append(OnapComponentsUrlPaths.SDC_ROOT_URL).append(id)
+ .append(OnapComponentsUrlPaths.SDC_GET_PATH);
+
+ ResponseEntity<Object> response = callSdc(callURL.toString());
+ return (LinkedHashMap) response.getBody();
+
+ }
+
+ public List<LinkedHashMap> callFind(MultiValueMap<String, String> parametersMap) {
+
+ UriComponentsBuilder callURL = UriComponentsBuilder.fromHttpUrl(sdcHost + OnapComponentsUrlPaths.SDC_ROOT_URL);
+ if (parametersMap != null) {
+ Map<String, String> stringStringMap = parametersMap.toSingleValueMap();
+ for (String key : stringStringMap.keySet()) {
+ if (!key.equals("fields")) {
+ callURL.queryParam(key, stringStringMap.get(key));
+ }
+ }
+ }
+
+ ResponseEntity<Object> response = callSdc(callURL.build().encode().toUri().toString());
+ return (List<LinkedHashMap>) response.getBody();
+
+ }
+
+
+ public File callGetWithAttachment(String toscaModelUrl) {
+ StringBuilder callURL = new StringBuilder().append(sdcHost).append(toscaModelUrl);
+
+ String fileName = System.currentTimeMillis() + "tosca.csar";
+ ResponseEntity<byte[]> response = callSdcWithAttachment(callURL.toString());
+ File toscaFile = new File(fileName);
+ try {
+ FileOutputStream toscaFileStream = new FileOutputStream(toscaFile);
+ if (response != null) {
+ IOUtils.write(response.getBody(), toscaFileStream);
+ }
+ toscaFileStream.close();
+ } catch (IOException e) {
+ LOGGER.error("cannot get TOSCA File for url " + toscaModelUrl);
+ }
+ return toscaFile;
+
+ }
+
+ private HttpEntity<String> buildRequestHeader() {
+ HttpHeaders httpHeaders = new HttpHeaders();
+ httpHeaders.add(HEADER_ECOMP_INSTANCE_ID, ecompInstanceId);
+ httpHeaders.add(HEADER_AUTHORIZATION, sdcHeaderAuthorization);
+ HttpEntity<String> entity = new HttpEntity<>("parameters", httpHeaders);
+
+ return entity;
+ }
+
+
+ private ResponseEntity<Object> callSdc(String callURL) {
+ ResponseEntity<Object> response =
+ restTemplate.exchange(callURL, HttpMethod.GET, buildRequestHeader(), Object.class);
+ LOGGER.debug("response body : " + response.getBody().toString());
+ LOGGER.info("response status : " + response.getStatusCodeValue());
+ loggDebugIfResponseKo(callURL, response);
+ return response;
+ }
+
+ private void loggDebugIfResponseKo(String callURL, ResponseEntity<Object> response) {
+ if (!response.getStatusCode().equals(HttpStatus.OK)) {
+ LOGGER.warn(HTTP_CALL_SDC_ON + callURL + " returns " + response.getStatusCodeValue() + ", "
+ + response.getBody().toString());
+ }
+ }
+
+ private ResponseEntity<byte[]> callSdcWithAttachment(String callURL) {
+ try {
+ ResponseEntity<byte[]> response =
+ restTemplate.exchange(callURL.toString(), HttpMethod.GET, buildRequestHeader(), byte[].class);
+ LOGGER.info("response status : " + response.getStatusCodeValue());
+ if (!response.getStatusCode().equals(HttpStatus.OK)) {
+ LOGGER.warn(HTTP_CALL_SDC_ON + callURL.toString() + " returns " + response.getStatusCodeValue() + ", "
+ + response.getBody().toString());
+ }
+ return response;
+
+ } catch (BackendFunctionalException e) {
+ LOGGER.error(HTTP_CALL_SDC_ON + callURL.toString() + " error " + e);
+
+ return null;
+ }
+ }
+
+
+}
+
+
diff --git a/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java b/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java
new file mode 100644
index 0000000..512b088
--- /dev/null
+++ b/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java
@@ -0,0 +1,46 @@
+package org.onap.nbi.apis.servicecatalog;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import org.onap.nbi.commons.JsonRepresentation;
+import org.onap.nbi.commons.Resource;
+import org.onap.nbi.commons.ResourceManagement;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.MultiValueMap;
+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.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/serviceSpecification")
+public class ServiceSpecificationResource extends ResourceManagement<Resource> {
+
+
+ @Autowired
+ ServiceSpecificationService serviceSpecificationService;
+
+ @GetMapping(value = "/{serviceSpecId}", produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<Object> getServiceSpecification(@PathVariable String serviceSpecId,
+ @RequestParam MultiValueMap<String, String> params) {
+ LinkedHashMap response = serviceSpecificationService.get(serviceSpecId);
+ JsonRepresentation filter = new JsonRepresentation(params);
+ if (response.get("serviceSpecCharacteristic") != null) {
+ return this.getResponse(response, filter);
+ } else {
+ return this.getPartialResponse(response, filter);
+
+ }
+ }
+
+ @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<Object> findServiceSpecification(@RequestParam MultiValueMap<String, String> params) {
+ List<LinkedHashMap> response = serviceSpecificationService.find(params);
+ JsonRepresentation filter = new JsonRepresentation(params);
+ return this.findResponse(response, filter, null);
+ }
+
+}
diff --git a/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationService.java b/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationService.java
new file mode 100644
index 0000000..3b56819
--- /dev/null
+++ b/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationService.java
@@ -0,0 +1,51 @@
+package org.onap.nbi.apis.servicecatalog;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import org.onap.nbi.apis.servicecatalog.jolt.FindServiceSpecJsonTransformer;
+import org.onap.nbi.apis.servicecatalog.jolt.GetServiceSpecJsonTransformer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.MultiValueMap;
+
+@Service
+public class ServiceSpecificationService {
+
+ @Autowired
+ SdcClient sdcClient;
+
+ @Autowired
+ GetServiceSpecJsonTransformer getServiceSpecJsonTransformer;
+
+ @Autowired
+ FindServiceSpecJsonTransformer findServiceSpecJsonTransformer;
+
+ @Autowired
+ ToscaInfosProcessor toscaInfosProcessor;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ServiceSpecificationService.class);
+
+
+ public LinkedHashMap get(String serviceSpecId) {
+ LinkedHashMap sdcResponse = sdcClient.callGet(serviceSpecId);
+ LinkedHashMap serviceCatalogResponse = (LinkedHashMap) getServiceSpecJsonTransformer.transform(sdcResponse);
+ LinkedHashMap toscaInfosTopologyTemplate = toscaInfosProcessor.getToscaInfos(serviceCatalogResponse);
+ if (toscaInfosTopologyTemplate != null) {
+ LOGGER.debug("tosca file found, retrieving informations");
+ toscaInfosProcessor.buildResponseWithToscaInfos(toscaInfosTopologyTemplate, serviceCatalogResponse);
+ } else {
+ LOGGER.debug("no tosca file found, partial response");
+ }
+ return serviceCatalogResponse;
+ }
+
+
+ public List<LinkedHashMap> find(MultiValueMap<String, String> parametersMap) {
+ List<LinkedHashMap> sdcResponse = sdcClient.callFind(parametersMap);
+ List<LinkedHashMap> serviceCatalogResponse =
+ (List<LinkedHashMap>) findServiceSpecJsonTransformer.transform(sdcResponse);
+ return serviceCatalogResponse;
+ }
+}
diff --git a/src/main/java/org/onap/nbi/apis/servicecatalog/ToscaInfosProcessor.java b/src/main/java/org/onap/nbi/apis/servicecatalog/ToscaInfosProcessor.java
new file mode 100644
index 0000000..4bfbd7b
--- /dev/null
+++ b/src/main/java/org/onap/nbi/apis/servicecatalog/ToscaInfosProcessor.java
@@ -0,0 +1,249 @@
+package org.onap.nbi.apis.servicecatalog;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.io.FileUtils;
+import org.onap.nbi.exceptions.TechnicalException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+
+@Service
+public class ToscaInfosProcessor {
+
+ @Autowired
+ SdcClient sdcClient;
+
+ final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); // jackson databind
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ToscaInfosProcessor.class);
+
+ public void buildResponseWithToscaInfos(LinkedHashMap toscaInfosTopologyTemplate,
+ LinkedHashMap serviceCatalogResponse) {
+ if (toscaInfosTopologyTemplate.get("inputs") != null) {
+ ArrayList serviceSpecCharacteristic = new ArrayList();
+ LinkedHashMap toscaInfos = (LinkedHashMap) toscaInfosTopologyTemplate.get("inputs");
+ for (Object key : toscaInfos.keySet()) {
+ String keyString = (String) key;
+ LinkedHashMap inputParameter = (LinkedHashMap) toscaInfos.get(key);
+ LinkedHashMap mapParameter = new LinkedHashMap();
+ String parameterType = (String) inputParameter.get("type");
+ mapParameter.put("name", keyString);
+ mapParameter.put("description", inputParameter.get("description"));
+ mapParameter.put("valueType", parameterType);
+ mapParameter.put("@type", "ONAPserviceCharacteristic");
+ mapParameter.put("required", inputParameter.get("required"));
+ mapParameter.put("status", inputParameter.get("status"));
+ List<LinkedHashMap> serviceSpecCharacteristicValues =
+ buildServiceSpecCharacteristicsValues(inputParameter, parameterType);
+ mapParameter.put("serviceSpecCharacteristicValue", serviceSpecCharacteristicValues);
+ serviceSpecCharacteristic.add(mapParameter);
+ }
+
+ serviceCatalogResponse.put("serviceSpecCharacteristic", serviceSpecCharacteristic);
+ }
+ LinkedHashMap node_templates = (LinkedHashMap) toscaInfosTopologyTemplate.get("node_templates");
+
+ List<LinkedHashMap> resourceSpecifications =
+ (List<LinkedHashMap>) serviceCatalogResponse.get("resourceSpecification");
+ for (LinkedHashMap resourceSpecification : resourceSpecifications) {
+ String id = (String) resourceSpecification.get("id");
+ LOGGER.debug("get tosca infos for service id: " + id);
+ LinkedHashMap toscaInfosFromResourceId = getToscaInfosFromResourceUUID(node_templates, id);
+ resourceSpecification.put("modelCustomizationId", toscaInfosFromResourceId.get("customizationUUID"));
+ resourceSpecification.put("modelCustomizationName", toscaInfosFromResourceId.get("name"));
+
+ }
+ }
+
+ private List<LinkedHashMap> buildServiceSpecCharacteristicsValues(LinkedHashMap parameter, String parameterType) {
+ List<LinkedHashMap> serviceSpecCharacteristicValues = new ArrayList<>();
+ if (!"map".equalsIgnoreCase(parameterType) && !"list".equalsIgnoreCase(parameterType)) {
+ LOGGER.debug("get tosca infos for serviceSpecCharacteristicValues of type map or string : " + parameter);
+ Object aDefault = parameter.get("default");
+ if (parameter.get("entry_schema") != null) {
+ ArrayList entry_schema = (ArrayList) parameter.get("entry_schema");
+ if (CollectionUtils.isNotEmpty(entry_schema)) {
+ buildCharacteristicValuesFormShema(parameterType, serviceSpecCharacteristicValues, aDefault,
+ entry_schema);
+ }
+ }
+ }
+ return serviceSpecCharacteristicValues;
+ }
+
+ private void buildCharacteristicValuesFormShema(String parameterType,
+ List<LinkedHashMap> serviceSpecCharacteristicValues, Object aDefault, ArrayList entry_schema) {
+ LinkedHashMap constraints = (LinkedHashMap) entry_schema.get(0);
+ if (constraints != null) {
+ ArrayList constraintsList = (ArrayList) constraints.get("constraints");
+ if (CollectionUtils.isNotEmpty(constraintsList)) {
+ LinkedHashMap valuesMap = (LinkedHashMap) constraintsList.get(0);
+ if (valuesMap != null) {
+ List<Object> values = (List<Object>) valuesMap.get("valid_values");
+ for (Object value : values) {
+ String stringValue = value.toString();
+ LinkedHashMap serviceSpecCharacteristicValue = new LinkedHashMap();
+ serviceSpecCharacteristicValue.put("isDefault",
+ aDefault != null && aDefault.toString().equals(stringValue));
+ serviceSpecCharacteristicValue.put("value", stringValue);
+ serviceSpecCharacteristicValue.put("valueType", parameterType);
+ serviceSpecCharacteristicValues.add(serviceSpecCharacteristicValue);
+ }
+ }
+ }
+ }
+ }
+
+
+ private LinkedHashMap getToscaInfosFromResourceUUID(LinkedHashMap node_templates, String name) {
+ for (Object nodeTemplateObject : node_templates.values()) {
+ LinkedHashMap nodeTemplate = (LinkedHashMap) nodeTemplateObject;
+ LinkedHashMap metadata = (LinkedHashMap) nodeTemplate.get("metadata");
+ String metadataUUID = (String) metadata.get("UUID");
+ String metadataType = (String) metadata.get("type");
+ if ("VF".equalsIgnoreCase(metadataType) && name.equalsIgnoreCase(metadataUUID)) {
+ return metadata;
+ }
+ }
+ return null;
+ }
+
+
+ public LinkedHashMap getToscaInfos(LinkedHashMap sdcResponse) {
+ String toscaModelUrl = (String) sdcResponse.get("toscaModelURL");
+ String serviceId = (String) sdcResponse.get("uuid");
+ File toscaFile = sdcClient.callGetWithAttachment(toscaModelUrl);
+ Timestamp timestamp = new Timestamp(System.currentTimeMillis());
+ String tempFolderName = serviceId + timestamp;
+ File folderTemp = null;
+ LinkedHashMap topology_template = null;
+ try {
+ unZipArchive(toscaFile.getName(), tempFolderName);
+ folderTemp = new File(tempFolderName);
+ LOGGER.debug("temp folder for tosca files : " + folderTemp.getName());
+
+ LinkedHashMap toscaMetaFileHashMap = parseToscaFile(tempFolderName + "/TOSCA-Metadata/TOSCA.meta");
+ if (toscaMetaFileHashMap.get("Entry-Definitions") == null) {
+ throw new NullPointerException("no Entry-Definitions node in TOSCA.meta");
+ }
+ String toscaFilePath = (String) toscaMetaFileHashMap.get("Entry-Definitions");
+ LinkedHashMap toscaFileHashMap = parseToscaFile(tempFolderName + "/" + toscaFilePath);
+
+ if (toscaFileHashMap.get("topology_template") == null) {
+ throw new NullPointerException("no topology_template node in tosca file");
+ }
+ topology_template = (LinkedHashMap) toscaFileHashMap.get("topology_template");
+
+ } catch (NullPointerException e) {
+ LOGGER.error("unable to parse tosca file for id : " + serviceId + ", " + e.getMessage());
+ return null;
+ } finally {
+ try {
+ LOGGER.debug("deleting temp folder for tosca files : " + folderTemp.getName());
+ FileUtils.deleteDirectory(folderTemp);
+ LOGGER.debug("deleting tosca archive : " + toscaFile.getName());
+ FileUtils.forceDelete(toscaFile);
+ return topology_template;
+ } catch (IOException e) {
+ LOGGER.error("unable to delete temp directory tosca file for id : " + serviceId);
+ return null;
+
+ }
+ }
+ }
+
+
+ private LinkedHashMap parseToscaFile(String fileName) {
+
+ File toscaFile = new File(fileName);
+ if (toscaFile == null) {
+ throw new TechnicalException("unable to find file : " + fileName);
+ }
+ try {
+ return (LinkedHashMap) mapper.readValue(toscaFile, Object.class);
+ } catch (IOException e) {
+ LOGGER.error("unable to parse tosca file : " + fileName);
+ LOGGER.error(e.getMessage());
+ throw new TechnicalException("Unable to parse tosca file : " + fileName);
+
+ } catch (NullPointerException e) {
+ LOGGER.error("unable to find tosca file : " + fileName);
+ LOGGER.error(e.getMessage());
+ throw new TechnicalException("unable to find tosca file : " + fileName);
+ }
+ }
+
+
+ /**
+ * Unzip it
+ *
+ * @param zipFile input zip file
+ * @param outputFolder zip file output folder
+ */
+ private void unZipArchive(String zipFile, String outputFolder) {
+
+ byte[] buffer = new byte[1024];
+
+ try {
+
+ // create output directory is not exists
+ File folder = new File(outputFolder);
+ if (!folder.exists()) {
+ folder.mkdir();
+ }
+
+ // get the zip file content
+ try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
+ // get the zipped file list entry
+ ZipEntry ze = zis.getNextEntry();
+
+ while (ze != null) {
+
+ String fileName = ze.getName();
+ File newFile = new File(outputFolder + File.separator + fileName);
+
+ LOGGER.debug("File to unzip : " + newFile.getAbsoluteFile());
+
+ // create all non exists folders
+ // else you will hit FileNotFoundException for compressed folder
+ new File(newFile.getParent()).mkdirs();
+
+ try (FileOutputStream fos = new FileOutputStream(newFile)) {
+
+ int len;
+ while ((len = zis.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
+ }
+
+ fos.close();
+ }
+ ze = zis.getNextEntry();
+ }
+
+ zis.closeEntry();
+ zis.close();
+ }
+
+ LOGGER.debug("Done");
+
+ } catch (IOException ex) {
+ LOGGER.error("Error while unzipping ToscaModel archive from ONAP : " + ex.getMessage());
+ throw new TechnicalException("Error while unzipping ToscaModel archive from ONAP");
+ }
+ }
+
+
+}
diff --git a/src/main/java/org/onap/nbi/apis/servicecatalog/jolt/FindServiceSpecJsonTransformer.java b/src/main/java/org/onap/nbi/apis/servicecatalog/jolt/FindServiceSpecJsonTransformer.java
new file mode 100644
index 0000000..b32f9fc
--- /dev/null
+++ b/src/main/java/org/onap/nbi/apis/servicecatalog/jolt/FindServiceSpecJsonTransformer.java
@@ -0,0 +1,36 @@
+package org.onap.nbi.apis.servicecatalog.jolt;
+
+import com.bazaarvoice.jolt.Chainr;
+import com.bazaarvoice.jolt.JsonUtils;
+import com.bazaarvoice.jolt.exception.JoltException;
+import org.onap.nbi.exceptions.TechnicalException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class FindServiceSpecJsonTransformer {
+
+ private Chainr chainr;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(FindServiceSpecJsonTransformer.class);
+
+ public FindServiceSpecJsonTransformer() {
+ List<Object> specs = JsonUtils.classpathToList("/jolt/findServiceCatalog.json");
+ this.chainr = Chainr.fromSpec(specs);
+ }
+
+ public Object transform(Object serviceSpec) {
+ Object output = null;
+ try {
+ output = chainr.transform(serviceSpec);
+ } catch (JoltException joE) {
+ LOGGER.error("Unable to transform SDC response with JOLT Transformer : " + joE.getMessage());
+ throw new TechnicalException("Error while parsing ONAP response");
+ }
+ return output;
+ }
+
+}
diff --git a/src/main/java/org/onap/nbi/apis/servicecatalog/jolt/GetServiceSpecJsonTransformer.java b/src/main/java/org/onap/nbi/apis/servicecatalog/jolt/GetServiceSpecJsonTransformer.java
new file mode 100644
index 0000000..784ed6f
--- /dev/null
+++ b/src/main/java/org/onap/nbi/apis/servicecatalog/jolt/GetServiceSpecJsonTransformer.java
@@ -0,0 +1,37 @@
+package org.onap.nbi.apis.servicecatalog.jolt;
+
+import com.bazaarvoice.jolt.Chainr;
+import com.bazaarvoice.jolt.JsonUtils;
+import com.bazaarvoice.jolt.exception.JoltException;
+import org.onap.nbi.exceptions.TechnicalException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class GetServiceSpecJsonTransformer {
+
+ private Chainr chainr;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(GetServiceSpecJsonTransformer.class);
+
+
+ public GetServiceSpecJsonTransformer() {
+ List<Object> specs = JsonUtils.classpathToList("/jolt/getServiceCatalog.json");
+ this.chainr = Chainr.fromSpec(specs);
+ }
+
+ public Object transform(Object serviceSpec) {
+ Object output = null;
+ try {
+ output = chainr.transform(serviceSpec);
+ } catch (JoltException joE) {
+ LOGGER.error("Unable to transform SDC response with JOLT Transformer : " + joE.getMessage());
+ throw new TechnicalException("Error while parsing ONAP response");
+ }
+ return output;
+ }
+
+}
diff --git a/src/main/java/org/onap/nbi/exceptions/ApiError.java b/src/main/java/org/onap/nbi/exceptions/ApiError.java
new file mode 100644
index 0000000..5e030f8
--- /dev/null
+++ b/src/main/java/org/onap/nbi/exceptions/ApiError.java
@@ -0,0 +1,67 @@
+package org.onap.nbi.exceptions;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "Error", propOrder = {
+ "code",
+ "message",
+ "description",
+ "infoURL"
+})
+public class ApiError {
+ @XmlElement(required = true)
+ protected String code;
+ @XmlElement(required = true)
+ protected String message;
+ @XmlElement(required = true)
+ private String description;
+ @XmlElement(required = true)
+ protected String infoURL;
+
+ public ApiError() {
+ }
+
+ public ApiError(String code, String message, String description, String infoURL) {
+ this.code = code;
+ this.message = message;
+ this.description = description;
+ this.infoURL = infoURL;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getInfoURL() {
+ return infoURL;
+ }
+
+ public void setInfoURL(String infoURL) {
+ this.infoURL = infoURL;
+ }
+}
+
diff --git a/src/main/java/org/onap/nbi/exceptions/ApiException.java b/src/main/java/org/onap/nbi/exceptions/ApiException.java
new file mode 100644
index 0000000..d07d9db
--- /dev/null
+++ b/src/main/java/org/onap/nbi/exceptions/ApiException.java
@@ -0,0 +1,33 @@
+package org.onap.nbi.exceptions;
+
+import java.io.Serializable;
+
+public class ApiException extends RuntimeException implements Serializable {
+
+ protected final String localisationClass;
+ protected final String localisationMethod;
+
+ public ApiException() {
+ super();
+ localisationClass = "";
+ localisationMethod = "";
+ }
+
+ public ApiException(String message) {
+ super(message);
+ localisationClass = "";
+ localisationMethod = "";
+ }
+
+ public ApiException(String message, Throwable cause) {
+ super(message, cause);
+ localisationClass = "";
+ localisationMethod = "";
+ }
+
+ public ApiException(Throwable cause) {
+ super(cause);
+ localisationClass = "";
+ localisationMethod = "";
+ }
+}
diff --git a/src/main/java/org/onap/nbi/exceptions/ApiExceptionHandler.java b/src/main/java/org/onap/nbi/exceptions/ApiExceptionHandler.java
new file mode 100644
index 0000000..1f109cb
--- /dev/null
+++ b/src/main/java/org/onap/nbi/exceptions/ApiExceptionHandler.java
@@ -0,0 +1,46 @@
+package org.onap.nbi.exceptions;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.client.RestClientException;
+
+@ControllerAdvice
+public class ApiExceptionHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApiExceptionHandler.class);
+
+
+ @ExceptionHandler(BackendFunctionalException.class)
+ @ResponseBody
+ public ResponseEntity<ApiError> backendExceptionHandler(final BackendFunctionalException exception) {
+ ApiError apiError = new ApiError(String.valueOf(exception.getHttpStatus().value()), exception.getMessage(), "", "");
+ return new ResponseEntity<ApiError>(apiError, exception.getHttpStatus());
+ }
+
+ @ExceptionHandler(TechnicalException.class)
+ @ResponseBody
+ public ResponseEntity<ApiError> technicalExceptionHandler(final TechnicalException exception) {
+ ApiError apiError = new ApiError(String.valueOf(exception.getHttpStatus().value()), exception.getMessage(), "", "");
+ return new ResponseEntity<ApiError>(apiError, exception.getHttpStatus());
+ }
+
+ @ExceptionHandler(RestClientException.class)
+ @ResponseBody
+ public ResponseEntity<ApiError> RestClientExceptionHandler(final RestClientException exception) {
+ ApiError apiError = new ApiError("500", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), "Unable to " +
+ "reach ONAP services", "");
+ return new ResponseEntity<ApiError>(apiError, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ @ExceptionHandler(ValidationException.class)
+ @ResponseBody
+ public ResponseEntity<ApiError> ValidationExceptionHandler(final ValidationException exception) {
+ ApiError apiError = new ApiError("400", HttpStatus.BAD_REQUEST.getReasonPhrase(), exception.getMessages(), "");
+ return new ResponseEntity<ApiError>(apiError, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+}
diff --git a/src/main/java/org/onap/nbi/exceptions/BackendErrorHandler.java b/src/main/java/org/onap/nbi/exceptions/BackendErrorHandler.java
new file mode 100644
index 0000000..34c4ac5
--- /dev/null
+++ b/src/main/java/org/onap/nbi/exceptions/BackendErrorHandler.java
@@ -0,0 +1,24 @@
+package org.onap.nbi.exceptions;
+
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.web.client.DefaultResponseErrorHandler;
+import org.springframework.web.client.ResponseErrorHandler;
+
+import java.io.IOException;
+
+public class BackendErrorHandler implements ResponseErrorHandler {
+
+ private ResponseErrorHandler errorHandler = new DefaultResponseErrorHandler();
+
+ @Override
+ public boolean hasError(ClientHttpResponse response) throws IOException {
+ return errorHandler.hasError(response);
+ }
+
+ @Override
+ public void handleError(ClientHttpResponse response) throws IOException {
+ if (response.getStatusCode() != null) {
+ throw new BackendFunctionalException(response.getStatusCode(), response.getStatusText());
+ }
+ }
+}
diff --git a/src/main/java/org/onap/nbi/exceptions/BackendFunctionalException.java b/src/main/java/org/onap/nbi/exceptions/BackendFunctionalException.java
new file mode 100644
index 0000000..176186f
--- /dev/null
+++ b/src/main/java/org/onap/nbi/exceptions/BackendFunctionalException.java
@@ -0,0 +1,22 @@
+package org.onap.nbi.exceptions;
+
+import org.springframework.http.HttpStatus;
+
+public class BackendFunctionalException extends ApiException {
+
+ private HttpStatus httpStatus;
+
+ public BackendFunctionalException(HttpStatus httpStatus, String message) {
+ super(message);
+ this.httpStatus = httpStatus;
+ }
+
+ public BackendFunctionalException() {
+ super();
+ }
+
+ public HttpStatus getHttpStatus() {
+ return httpStatus;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/nbi/exceptions/TechnicalException.java b/src/main/java/org/onap/nbi/exceptions/TechnicalException.java
new file mode 100644
index 0000000..a2abe3e
--- /dev/null
+++ b/src/main/java/org/onap/nbi/exceptions/TechnicalException.java
@@ -0,0 +1,26 @@
+package org.onap.nbi.exceptions;
+
+import org.springframework.http.HttpStatus;
+
+public class TechnicalException extends ApiException {
+
+ private HttpStatus httpStatus;
+
+ public TechnicalException(String message) {
+ super(message);
+ this.httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
+ }
+
+ public TechnicalException() {
+ super();
+ }
+
+ public HttpStatus getHttpStatus() {
+ return httpStatus;
+ }
+
+ public void setHttpStatus(HttpStatus httpStatus) {
+ this.httpStatus = httpStatus;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/nbi/exceptions/ValidationException.java b/src/main/java/org/onap/nbi/exceptions/ValidationException.java
new file mode 100644
index 0000000..316e8f2
--- /dev/null
+++ b/src/main/java/org/onap/nbi/exceptions/ValidationException.java
@@ -0,0 +1,32 @@
+package org.onap.nbi.exceptions;
+
+import org.springframework.validation.FieldError;
+import org.springframework.validation.ObjectError;
+
+import java.util.List;
+
+public class ValidationException extends ApiException {
+
+ private String messages;
+
+ public ValidationException(List<ObjectError> listErrors) {
+ super();
+ StringBuilder sb = new StringBuilder();
+ for (ObjectError error : listErrors) {
+ if (error instanceof FieldError) {
+ sb.append(((FieldError) error).getField())
+ .append(" ")
+ .append(((FieldError) error).getDefaultMessage())
+ .append(". ");
+ } else {
+ sb.append(" ").append(error.getDefaultMessage()).append(". ");
+ }
+ }
+ messages = sb.toString();
+
+ }
+
+ public String getMessages() {
+ return messages;
+ }
+}
diff --git a/src/main/resources/application-localhost.properties b/src/main/resources/application-localhost.properties
new file mode 100644
index 0000000..58b13f6
--- /dev/null
+++ b/src/main/resources/application-localhost.properties
@@ -0,0 +1,7 @@
+# LOGGING
+logging.level.org.onap.nbi=DEBUG
+
+# SDC
+sdc.host=http://127.0.0.1:8090
+sdc.header.ecompInstanceId=Rene
+sdc.header.authorization=Basic YWFpOktwOGJKNFNYc3pNMFdYbGhhazNlSGxjc2UyZ0F3ODR2YW9HR21KdlV5MlU=
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 1d8ff27..10e0d7d 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -3,4 +3,5 @@ server.contextPath=/nbi/api/v1
server.port = 8080
# LOGGING
-logging.level.org.onap.nbi=WARN
+logging.level.=WARN
+
diff --git a/src/main/resources/jolt/findServiceCatalog.json b/src/main/resources/jolt/findServiceCatalog.json
new file mode 100644
index 0000000..ffe5fe3
--- /dev/null
+++ b/src/main/resources/jolt/findServiceCatalog.json
@@ -0,0 +1,28 @@
+[
+ {
+ "operation": "shift",
+ "spec": {
+ "*": {
+ "uuid": "[&1].id",
+ "description": "[&1].description",
+ "name": "[&1].name",
+ "invariantUUID": "[&1].invariantUUID",
+ "category": "[&1].category",
+ "distributionStatus": "[&1].distributionStatus",
+ "version": "[&1].version",
+ "lifecycleState": "[&1].lifecycleStatus",
+ "lastUpdaterUserId": "[&1].relatedParty.id"
+ }
+ }
+ },
+ {
+ "operation": "default",
+ "spec": {
+ "*": {
+ "relatedParty": {
+ "role": "lastUpdater"
+ }
+ }
+ }
+ }
+] \ No newline at end of file
diff --git a/src/main/resources/jolt/getServiceCatalog.json b/src/main/resources/jolt/getServiceCatalog.json
new file mode 100644
index 0000000..cac223e
--- /dev/null
+++ b/src/main/resources/jolt/getServiceCatalog.json
@@ -0,0 +1,77 @@
+[
+ {
+ "operation": "shift",
+ "spec": {
+ "uuid": "id",
+ "name": "name",
+ "description": "description",
+ "invariantUUID": "invariantUUID",
+ "toscaModelURL": "toscaModelURL",
+ "toscaResourceName": "toscaResourceName",
+ "category ": "category",
+ "subcategory": "subcategory",
+ "distributionStatus": "distributionStatus",
+ "version": "version",
+ "lifecycleState":"lifecycleStatus" ,
+ "artifacts" : {
+ "*": {
+ "artifactUUID": "attachment[&1].id",
+ "artifactName": "attachment[&1].name",
+ "artifactDescription": "attachment[&1].description",
+ "artifactLabel": "attachment[&1].artifactLabel",
+ "artifactGroupType": "attachment[&1].artifactGroupType",
+ "artifactTimeout": "attachment[&1].artifactTimeout",
+ "artifactChecksum": "attachment[&1].artifactChecksum",
+ "artifactVersion": "attachment[&1].artifactVersion",
+ "generatedFromUUID": "attachment[&1].generatedFromUUID",
+ "artifactURL": "attachment[&1].url",
+ "artifactType": "attachment[&1].mimeType"
+ }
+
+ },
+ "lastUpdaterUserId" : "relatedParty.id",
+ "lastUpdaterFullName" : "relatedParty.name",
+ "resources" : {
+ "*": {
+ "resourceUUID": "resourceSpecification[&1].id",
+ "resourceVersion": "resourceSpecification[&1].version",
+ "resourceName": "resourceSpecification[&1].name",
+ "resourceInstanceName": "resourceSpecification[&1].instanceName",
+ "resourceInvariantUUID": "resourceSpecification[&1].resourceInvariantUUID",
+ "resourceType": "resourceSpecification[&1].resourceType"
+ }
+
+ }
+
+
+
+ }
+ },
+ {
+ "operation": "modify-overwrite-beta",
+ "spec": {
+ "href": "=concat('serviceSpecification/',@(1,id))"
+ }
+ },
+ {
+ "operation": "default",
+ "spec": {
+ "@type": "ONAPservice",
+ "attachment[]" : {
+ "*": {
+ "@type": "ONAPartifact"
+ }
+
+ },
+ "relatedParty" : {
+ "role": "lastUpdater"
+ },
+ "resourceSpecification[]" : {
+ "*": {
+ "@type": "ONAPresource"
+ }
+
+ }
+ }
+ }
+] \ No newline at end of file
diff --git a/src/test/java/org/onap/nbi/apis/resources/ApiTest.java b/src/test/java/org/onap/nbi/apis/resources/ApiTest.java
new file mode 100644
index 0000000..05d332c
--- /dev/null
+++ b/src/test/java/org/onap/nbi/apis/resources/ApiTest.java
@@ -0,0 +1,89 @@
+package org.onap.nbi.apis.resources;
+
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.nbi.apis.servicecatalog.ServiceSpecificationResource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.embedded.LocalServerPort;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import com.github.tomakehurst.wiremock.WireMockServer;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+public class ApiTest {
+
+ @LocalServerPort
+ int randomServerPort;
+
+ String realServerPort;
+
+
+ static public WireMockServer wireMockServer = new WireMockServer(8091);
+
+ @Autowired
+ ServiceSpecificationResource serviceSpecificationResource;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ wireMockServer.start();
+ }
+
+ @AfterClass
+ public static void tearsDown() throws Exception {
+ wireMockServer.stop();
+
+ }
+
+ @After
+ public void tearsDownUpPort() throws Exception {
+ wireMockServer.resetToDefaultMappings();
+ }
+
+ @Test
+ @Ignore
+ public void testServiceResourceGetCatalog() throws Exception {
+
+ ResponseEntity<Object> resource =
+ serviceSpecificationResource.getServiceSpecification("1e3feeb0-8e36-46c6-862c-236d9c626439", null);
+ ServiceCatalogAssertions.assertGetServiceCatalog(resource);
+
+ }
+
+ @Test
+ public void testServiceCatalogGetResourceWithoutTosca() throws Exception {
+
+ ResponseEntity<Object> resource = serviceSpecificationResource
+ .getServiceSpecification("1e3feeb0-8e36-46c6-862c-236d9c626439_withoutTosca", null);
+ ServiceCatalogAssertions.asserGetServiceCatalogWithoutTosca(resource);
+
+ }
+
+ @Test
+ public void testServiceCatalogFind() throws Exception {
+
+ ResponseEntity<Object> resource = serviceSpecificationResource.findServiceSpecification(null);
+ ServiceCatalogAssertions.assertFindServiceCatalog(resource);
+
+ }
+
+
+ @Test
+ public void testServiceCatalogFindWithFilter() throws Exception {
+
+ MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+ params.add("fields", "name");
+ ResponseEntity<Object> resource = serviceSpecificationResource.findServiceSpecification(params);
+ ServiceCatalogAssertions.assertFindServiceCatalogWIthFilter(resource);
+
+ }
+
+}
diff --git a/src/test/java/org/onap/nbi/apis/resources/ServiceCatalogAssertions.java b/src/test/java/org/onap/nbi/apis/resources/ServiceCatalogAssertions.java
new file mode 100644
index 0000000..19e2a2a
--- /dev/null
+++ b/src/test/java/org/onap/nbi/apis/resources/ServiceCatalogAssertions.java
@@ -0,0 +1,135 @@
+package org.onap.nbi.apis.resources;
+
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+public class ServiceCatalogAssertions {
+
+
+ public static void assertGetServiceCatalog(ResponseEntity<Object> resource) {
+ assertThat(resource.getStatusCode()).isEqualTo(HttpStatus.OK);
+ LinkedHashMap service = (LinkedHashMap) resource.getBody();
+ assertThat(service.get("id")).isEqualTo("1e3feeb0-8e36-46c6-862c-236d9c626439");
+ assertThat(service.get("name")).isEqualTo("vFW");
+ assertThat(service.get("invariantUUID")).isEqualTo("b58a118e-eeb9-4f6e-bdca-e292f84d17df");
+ assertThat(service.get("toscaModelURL")).isEqualTo("/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/toscaModel");
+ assertThat(service.get("distributionStatus")).isEqualTo("DISTRIBUTED");
+ assertThat(service.get("version")).isEqualTo("2.0");
+ assertThat(service.get("lifecycleStatus")).isEqualTo("CERTIFIED");
+ assertThat(service.get("@type")).isEqualTo("ONAPservice");
+ assertThat(((ArrayList) service.get("attachment")).size()).isEqualTo(5);
+ LinkedHashMap relatedParty = (LinkedHashMap) service.get("relatedParty");
+ assertThat(relatedParty.get("name")).isEqualTo("Joni Mitchell");
+ assertThat(relatedParty.get("role")).isEqualTo("lastUpdater");
+
+
+ assertThat(((ArrayList) service.get("resourceSpecification")).size()).isEqualTo(2);
+ LinkedHashMap resource1 = (LinkedHashMap) ((ArrayList) service.get("resourceSpecification")).get(0);
+ assertThat(resource1.get("name")).isEqualTo("vFW-vSINK");
+ assertThat(resource1.get("instanceName")).isEqualTo("vFW-vSINK 0");
+ assertThat(resource1.get("resourceInvariantUUID")).isEqualTo("18b90934-aa82-456f-938e-e74a07a426f3");
+ assertThat(resource1.get("@type")).isEqualTo("ONAPresource");
+ assertThat(resource1.get("modelCustomizationId")).isEqualTo("f7ae574e-fd5f-41e7-9b21-75e001561c96");
+ assertThat(resource1.get("modelCustomizationName")).isEqualTo("vFW-vSINK");
+
+ assertThat(((ArrayList) service.get("serviceSpecCharacteristic")).size()).isEqualTo(4);
+ ArrayList serviceSPecCharacteristics = (ArrayList) service.get("serviceSpecCharacteristic");
+ for (Object serviceSPecCharacteristic : serviceSPecCharacteristics) {
+ LinkedHashMap serviceSPecCharacteristicMap = (LinkedHashMap) serviceSPecCharacteristic;
+ if (serviceSPecCharacteristicMap.get("name").toString().equals("cpus")) {
+ assertThat(serviceSPecCharacteristicMap.get("valueType")).isEqualTo("integer");
+ assertThat(serviceSPecCharacteristicMap.get("@type")).isEqualTo("ONAPserviceCharacteristic");
+ ArrayList serviceSpecCharacteristicValues = (ArrayList) serviceSPecCharacteristicMap.get("serviceSpecCharacteristicValue");
+ for (Object serviceSpecCharacteristicValue : serviceSpecCharacteristicValues) {
+ LinkedHashMap serviceSpecCharacteristicValueMap = (LinkedHashMap) serviceSpecCharacteristicValue;
+ if (serviceSpecCharacteristicValueMap.get("value").toString().equals("2")) {
+ assertThat(serviceSpecCharacteristicValueMap.get("isDefault")).isEqualTo(true);
+ assertThat(serviceSpecCharacteristicValueMap.get("valueType")).isEqualTo("integer");
+ } else {
+ assertThat(serviceSpecCharacteristicValueMap.get("isDefault")).isEqualTo(false);
+ assertThat(serviceSpecCharacteristicValueMap.get("valueType")).isEqualTo("integer");
+ }
+ }
+ }
+ }
+ }
+
+
+
+ public static void asserGetServiceCatalogWithoutTosca(ResponseEntity<Object> resource) {
+ assertThat(resource.getStatusCode()).isEqualTo(HttpStatus.PARTIAL_CONTENT);
+ LinkedHashMap service = (LinkedHashMap) resource.getBody();
+ assertThat(service.get("id")).isEqualTo("1e3feeb0-8e36-46c6-862c-236d9c626439");
+ assertThat(service.get("name")).isEqualTo("vFW");
+ assertThat(service.get("invariantUUID")).isEqualTo("b58a118e-eeb9-4f6e-bdca-e292f84d17df");
+ assertThat(service.get("toscaModelURL")).isEqualTo("/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439toto/toscaModel");
+ assertThat(service.get("distributionStatus")).isEqualTo("DISTRIBUTED");
+ assertThat(service.get("version")).isEqualTo("2.0");
+ assertThat(service.get("lifecycleStatus")).isEqualTo("CERTIFIED");
+ assertThat(service.get("@type")).isEqualTo("ONAPservice");
+ assertThat(((ArrayList) service.get("attachment")).size()).isEqualTo(5);
+ LinkedHashMap relatedParty = (LinkedHashMap) service.get("relatedParty");
+ assertThat(relatedParty.get("name")).isEqualTo("Joni Mitchell");
+ assertThat(relatedParty.get("role")).isEqualTo("lastUpdater");
+
+
+ assertThat(((ArrayList) service.get("resourceSpecification")).size()).isEqualTo(2);
+ LinkedHashMap resource1 = (LinkedHashMap) ((ArrayList) service.get("resourceSpecification")).get(0);
+ assertThat(resource1.get("name")).isEqualTo("vFW-vSINK");
+ assertThat(resource1.get("instanceName")).isEqualTo("vFW-vSINK 0");
+ assertThat(resource1.get("resourceInvariantUUID")).isEqualTo("18b90934-aa82-456f-938e-e74a07a426f3");
+ assertThat(resource1.get("@type")).isEqualTo("ONAPresource");
+ assertThat(resource1.get("modelCustomizationId")).isNull();
+ assertThat(resource1.get("modelCustomizationName")).isNull();
+
+ assertThat(service.get("serviceSpecCharacteristic")).isNull();
+ }
+
+
+
+
+ public static void assertFindServiceCatalog(ResponseEntity<Object> resource) {
+ assertThat(resource.getStatusCode()).isEqualTo(HttpStatus.OK);
+ ArrayList body = (ArrayList) resource.getBody();
+ assertThat(body.size()).isEqualTo(21);
+ LinkedHashMap service1 = (LinkedHashMap) body.get(0);
+ assertThat(service1.get("id")).isEqualTo("446afaf6-79b5-420e-aff8-7551b00bb510");
+ assertThat(service1.get("name")).isEqualTo("FreeRadius-service");
+ assertThat(service1.get("invariantUUID")).isEqualTo("7e4781e8-6c6e-41c5-b889-6a321d5f2490");
+ assertThat(service1.get("category")).isEqualTo("Network L4+");
+ assertThat(service1.get("distributionStatus")).isEqualTo("DISTRIBUTED");
+ assertThat(service1.get("version")).isEqualTo("1.0");
+ assertThat(service1.get("lifecycleStatus")).isEqualTo("CERTIFIED");
+ LinkedHashMap relatedParty = (LinkedHashMap) service1.get("relatedParty");
+ assertThat(relatedParty.get("role")).isEqualTo("lastUpdater");
+ }
+
+
+
+ public static void assertFindServiceCatalogWIthFilter(ResponseEntity<Object> resource) {
+ assertThat(resource.getStatusCode()).isEqualTo(HttpStatus.OK);
+ ArrayList body = (ArrayList) resource.getBody();
+ assertThat(body.size()).isEqualTo(21);
+
+
+ ObjectNode service1 = (ObjectNode) body.get(0);
+ assertThat(service1.get("id")).isNull();
+ assertThat(service1.get("name").asText()).isEqualTo("FreeRadius-service");
+ assertThat(service1.get("invariantUUID")).isNull();
+ assertThat(service1.get("category")).isNull();
+ assertThat(service1.get("distributionStatus")).isNull();
+ assertThat(service1.get("version")).isNull();
+ assertThat(service1.get("lifecycleStatus")).isNull();
+ assertThat(service1.get("relatedParty")).isNull();
+ }
+
+}
+
diff --git a/src/test/java/org/onap/nbi/apis/status/StatusTest.java b/src/test/java/org/onap/nbi/apis/resources/StatusResourceTest.java
index d262e15..40e11c2 100644
--- a/src/test/java/org/onap/nbi/apis/status/StatusTest.java
+++ b/src/test/java/org/onap/nbi/apis/resources/StatusResourceTest.java
@@ -1,10 +1,11 @@
-package org.onap.nbi.apis.status;
+package org.onap.nbi.apis.resources;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.onap.nbi.apis.status.StatusResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpStatus;
@@ -16,7 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-public class StatusTest {
+public class StatusResourceTest {
@Autowired
StatusResource statusResource;
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
new file mode 100644
index 0000000..5d18ec8
--- /dev/null
+++ b/src/test/resources/application.properties
@@ -0,0 +1,13 @@
+# SERVER
+server.contextPath=/nbi/api/v1
+server.port = 8080
+
+# LOGGING
+logging.level.org.onap.nbi=DEBUG
+logging.level.org.springframework.cloud.contract.wiremock=DEBUG
+
+# SDC
+sdc.host=http://127.0.0.1:8091
+sdc.header.ecompInstanceId=Rene
+sdc.header.authorization=Basic YWFpOktwOGJKNFNYc3pNMFdYbGhhazNlSGxjc2UyZ0F3ODR2YW9HR21KdlV5MlU=
+
diff --git a/src/test/resources/mappings/sdc_find.json b/src/test/resources/mappings/sdc_find.json
new file mode 100644
index 0000000..e992f2b
--- /dev/null
+++ b/src/test/resources/mappings/sdc_find.json
@@ -0,0 +1,244 @@
+{
+ "request": {
+ "method": "GET",
+ "urlPath": "/sdc/v1/catalog/services/"
+ },
+ "response": {
+ "status": 200,
+ "jsonBody": [{
+ "uuid": "446afaf6-79b5-420e-aff8-7551b00bb510",
+ "invariantUUID": "7e4781e8-6c6e-41c5-b889-6a321d5f2490",
+ "name": "FreeRadius-service",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/446afaf6-79b5-420e-aff8-7551b00bb510/toscaModel",
+ "category": "Network L4+",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "35911438-4621-439b-a23d-3e07680c724b",
+ "invariantUUID": "ca2f0af5-95e4-4058-b037-5c0de0f80bfa",
+ "name": "vIMS",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/35911438-4621-439b-a23d-3e07680c724b/toscaModel",
+ "category": "E2E Service",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "8cdc744a-9327-47cc-a9de-67d8d46b816f",
+ "invariantUUID": "d2b9c343-c41a-4f85-ae36-c53cd4b7abcc",
+ "name": "vIMSservice3",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/8cdc744a-9327-47cc-a9de-67d8d46b816f/toscaModel",
+ "category": "VoIP Call Control",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "fcea1d5b-c8de-4355-8fda-64e0d84494e6",
+ "invariantUUID": "b58a118e-eeb9-4f6e-bdca-e292f84d17df",
+ "name": "vFW-service-2VF-based",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/fcea1d5b-c8de-4355-8fda-64e0d84494e6/toscaModel",
+ "category": "Network Service",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "9d356a71-ac7a-40f0-b2b2-b302c8b4ef63",
+ "invariantUUID": "4526a034-e4fc-4ea3-87d0-8b8fca4a93b1",
+ "name": "serviceFRDBS",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/9d356a71-ac7a-40f0-b2b2-b302c8b4ef63/toscaModel",
+ "category": "Network L4+",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "b821e80a-40a5-4fab-ac5d-3d49a54c4db3",
+ "invariantUUID": "9765d74e-c8f2-4982-bc90-548c854cbde6",
+ "name": "EricDebeau",
+ "version": "0.1",
+ "toscaModelURL": "/sdc/v1/catalog/services/b821e80a-40a5-4fab-ac5d-3d49a54c4db3/toscaModel",
+ "category": "Network L4+",
+ "lifecycleState": "NOT_CERTIFIED_CHECKIN",
+ "lastUpdaterUserId": "cs0008",
+ "distributionStatus": "DISTRIBUTION_NOT_APPROVED"
+ },
+ {
+ "uuid": "cc3ec088-227c-49e2-b4c3-237214b88c84",
+ "invariantUUID": "e1685613-136b-4990-a590-d0651a640a68",
+ "name": "vMRFaaS4",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/cc3ec088-227c-49e2-b4c3-237214b88c84/toscaModel",
+ "category": "Network Service",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "10be4044-8217-4397-8b62-85c58688d4ba",
+ "invariantUUID": "a62a335f-a6e3-40dd-8b60-de8410301240",
+ "name": "OPL_FWtest1_service",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/10be4044-8217-4397-8b62-85c58688d4ba/toscaModel",
+ "category": "Network L4+",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "3dd3923d-1681-4f5b-99bb-f695ab147004",
+ "invariantUUID": "026e8046-4d3a-41d9-b4c2-6793186fd83d",
+ "name": "vFW",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/3dd3923d-1681-4f5b-99bb-f695ab147004/toscaModel",
+ "category": "Network Service",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "d15de0e3-d8fe-4cc3-a0b1-809ea95cbac8",
+ "invariantUUID": "6046d5f5-b39e-4306-a47e-0762c88d8b93",
+ "name": "1f298e99-082b-4a7f-a579",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/d15de0e3-d8fe-4cc3-a0b1-809ea95cbac8/toscaModel",
+ "category": "Network L1-3",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "f5ab9333-692f-42bc-b5dc-3ed753aa0d14",
+ "invariantUUID": "83a9f465-24d2-4dd3-98b8-328481cf9340",
+ "name": "c55011b0-f26c-43dd-9a62",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/f5ab9333-692f-42bc-b5dc-3ed753aa0d14/toscaModel",
+ "category": "Network L1-3",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "33826edf-fddd-4891-b726-8f16ea0e020c",
+ "invariantUUID": "0475334e-e141-42b3-b3ee-4df049c3cd53",
+ "name": "ccfc0cb4-bdff-4ae2-aa0e",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/33826edf-fddd-4891-b726-8f16ea0e020c/toscaModel",
+ "category": "Network L1-3",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "340bf137-8c6c-4d5b-b185-19364dfc74ed",
+ "invariantUUID": "7e4781e8-6c6e-41c5-b889-6a321d5f2490",
+ "name": "FreeRadius-service",
+ "version": "2.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/340bf137-8c6c-4d5b-b185-19364dfc74ed/toscaModel",
+ "category": "Network L4+",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "d0cac11e-332f-47e8-86d8-cb0b82655bb9",
+ "invariantUUID": "ca2f0af5-95e4-4058-b037-5c0de0f80bfa",
+ "name": "vIMS",
+ "version": "2.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/d0cac11e-332f-47e8-86d8-cb0b82655bb9/toscaModel",
+ "category": "E2E Service",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "e245a0a2-34fc-46c7-912c-bd39305275c1",
+ "invariantUUID": "29db0b2c-a877-45e8-8175-4ac526d87eee",
+ "name": "vMRFaaS",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/e245a0a2-34fc-46c7-912c-bd39305275c1/toscaModel",
+ "category": "Network L4+",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "b9e06990-99e2-480f-96ac-c6e50c83f2bb",
+ "invariantUUID": "008943ad-73be-4d57-9105-962c4cb16a71",
+ "name": "vMRFaas2",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/b9e06990-99e2-480f-96ac-c6e50c83f2bb/toscaModel",
+ "category": "Network L4+",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "98d95267-5e0f-4531-abf8-f14b90031dc5",
+ "invariantUUID": "709d157b-52fb-4250-976e-7133dff5c347",
+ "name": "NewFreeRadius-service",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/98d95267-5e0f-4531-abf8-f14b90031dc5/toscaModel",
+ "category": "Network L4+",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "d8d2429b-0863-462c-adc7-cd38d77331ed",
+ "invariantUUID": "e1685613-136b-4990-a590-d0651a640a68",
+ "name": "vMRFaaS4",
+ "version": "1.1",
+ "toscaModelURL": "/sdc/v1/catalog/services/d8d2429b-0863-462c-adc7-cd38d77331ed/toscaModel",
+ "category": "Network Service",
+ "lifecycleState": "NOT_CERTIFIED_CHECKOUT",
+ "lastUpdaterUserId": "cs0008",
+ "distributionStatus": "DISTRIBUTION_NOT_APPROVED"
+ },
+ {
+ "uuid": "9cfc73ad-795d-42ad-8a4f-54e6b3f33ef9",
+ "invariantUUID": "79f0574e-caf8-4bac-8189-909b2127e9e9",
+ "name": "vMRFaaS3",
+ "version": "1.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/9cfc73ad-795d-42ad-8a4f-54e6b3f33ef9/toscaModel",
+ "category": "Network Service",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "af1ac9db-9d8b-4ca0-964c-58755826b59a",
+ "invariantUUID": "d2b9c343-c41a-4f85-ae36-c53cd4b7abcc",
+ "name": "vIMSservice3",
+ "version": "2.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/af1ac9db-9d8b-4ca0-964c-58755826b59a/toscaModel",
+ "category": "VoIP Call Control",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ },
+ {
+ "uuid": "1e3feeb0-8e36-46c6-862c-236d9c626439",
+ "invariantUUID": "b58a118e-eeb9-4f6e-bdca-e292f84d17df",
+ "name": "vFW-service-2VF-based",
+ "version": "2.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/toscaModel",
+ "category": "Network Service",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED"
+ }
+ ],
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ }
+}
diff --git a/src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439.json b/src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439.json
new file mode 100644
index 0000000..3aeff82
--- /dev/null
+++ b/src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439.json
@@ -0,0 +1,213 @@
+{
+ "request": {
+ "method": "GET",
+ "urlPath": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/metadata"
+ },
+ "response": {
+ "status": 200,
+ "jsonBody": {
+ "uuid": "1e3feeb0-8e36-46c6-862c-236d9c626439",
+ "invariantUUID": "b58a118e-eeb9-4f6e-bdca-e292f84d17df",
+ "name": "vFW",
+ "version": "2.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/toscaModel",
+ "category": "Network Service",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED",
+ "lastUpdaterFullName": "Joni Mitchell",
+ "resources": [{
+ "resourceInstanceName": "vFW-vSINK 0",
+ "resourceName": "vFW-vSINK",
+ "resourceInvariantUUID": "18b90934-aa82-456f-938e-e74a07a426f3",
+ "resourceVersion": "2.0",
+ "resoucreType": "VF",
+ "resourceUUID": "89a6b4c5-3973-4c19-b651-fae3713ca8d5",
+ "artifacts": [{
+ "artifactName": "vf-license-model.xml",
+ "artifactType": "VF_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/f6fa3f94-f5cd-4233-a7b2-b5e8dc2e1ec6",
+ "artifactDescription": "VF license file",
+ "artifactChecksum": "NDQ2NzIxNzgyMjZhNTc1NDNlMWU0ODI1ZmIyNjc3Zjg=",
+ "artifactUUID": "f6fa3f94-f5cd-4233-a7b2-b5e8dc2e1ec6",
+ "artifactVersion": "1",
+ "artifactLabel": "vflicense",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "vfwvsink0_modules.json",
+ "artifactType": "VF_MODULES_METADATA",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/d0aaecf9-6ffb-4b4b-81fd-c59c1e8e6fb6",
+ "artifactDescription": "Auto-generated VF Modules information artifact",
+ "artifactChecksum": "ZGIyOWY3YzE0MTM2MjlhMjY1ZjkzNDg3YjE2ZmQxY2Y=",
+ "artifactUUID": "d0aaecf9-6ffb-4b4b-81fd-c59c1e8e6fb6",
+ "artifactVersion": "1",
+ "artifactLabel": "vfModulesMetadata",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "base_vfw.yaml",
+ "artifactType": "HEAT",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/c94e8eec-b1a7-431c-ab6f-2fda5f0ee920",
+ "artifactDescription": "created from csar",
+ "artifactTimeout": 60,
+ "artifactChecksum": "YTY0MDg5ODUwZDE4YzQyYWI0NjE5Y2NjYmM3ZDg5ZGE=",
+ "artifactUUID": "c94e8eec-b1a7-431c-ab6f-2fda5f0ee920",
+ "artifactVersion": "4",
+ "artifactLabel": "heat1",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "vendor-license-model.xml",
+ "artifactType": "VENDOR_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/423d2c66-6c3a-4257-9342-7b57ebf9dd54",
+ "artifactDescription": " Vendor license file",
+ "artifactChecksum": "YTNhYTc3ZGE4ZWViMmYzOThkOGQ3ZTVjZGNmNmU0ZmQ=",
+ "artifactUUID": "423d2c66-6c3a-4257-9342-7b57ebf9dd54",
+ "artifactVersion": "1",
+ "artifactLabel": "vendorlicense",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "base_vfw.env",
+ "artifactType": "HEAT_ENV",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/a1a58cc9-8225-4b6f-b81a-02fa3c7fb6ec",
+ "artifactDescription": "Auto-generated HEAT Environment deployment artifact",
+ "artifactChecksum": "ZmVkM2MwODhlZjcwNWY5MDk5ZGEyMjI5ZTAyYWRjNjY=",
+ "artifactUUID": "a1a58cc9-8225-4b6f-b81a-02fa3c7fb6ec",
+ "artifactVersion": "2",
+ "generatedFromUUID": "32591489-33c9-4461-a47c-7c463250788d.heat1",
+ "artifactLabel": "heat1env",
+ "artifactGroupType": "DEPLOYMENT"
+ }
+ ]
+ },
+ {
+ "resourceInstanceName": "vPkG 0",
+ "resourceName": "vPkG",
+ "resourceInvariantUUID": "8d8a20c0-746c-4d5e-a1a2-fa49fa5786ad",
+ "resourceVersion": "2.0",
+ "resoucreType": "VF",
+ "resourceUUID": "31961e27-2a2c-4beb-87c9-bfe0067088f5",
+ "artifacts": [{
+ "artifactName": "vf-license-model.xml",
+ "artifactType": "VF_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/7af6cc3b-2ba3-4164-9d7d-65b3b46a71f4",
+ "artifactDescription": "VF license file",
+ "artifactChecksum": "MWM5NDlmNjdhZTdmZTA5MzIzY2RhYjcxZmFkYzQyZDM=",
+ "artifactUUID": "7af6cc3b-2ba3-4164-9d7d-65b3b46a71f4",
+ "artifactVersion": "1",
+ "artifactLabel": "vflicense",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "vpkg0_modules.json",
+ "artifactType": "VF_MODULES_METADATA",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/37b16173-bd54-447f-a5a2-1a5e24db8afb",
+ "artifactDescription": "Auto-generated VF Modules information artifact",
+ "artifactChecksum": "ZDA3MWQ3MTE3MTA1MzNkY2M1ODQ4YTUxN2YwMDk0MmM=",
+ "artifactUUID": "37b16173-bd54-447f-a5a2-1a5e24db8afb",
+ "artifactVersion": "1",
+ "artifactLabel": "vfModulesMetadata",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "base_vpkg.yaml",
+ "artifactType": "HEAT",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/43184998-c107-40a7-92f6-00ba74de8539",
+ "artifactDescription": "created from csar",
+ "artifactTimeout": 60,
+ "artifactChecksum": "NDZhY2U0YTExZjllNTFmZjc4ZTE4YzU2Zjk1ZDc2MWI=",
+ "artifactUUID": "43184998-c107-40a7-92f6-00ba74de8539",
+ "artifactVersion": "4",
+ "artifactLabel": "heat1",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "vendor-license-model.xml",
+ "artifactType": "VENDOR_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/6cd5f968-20aa-4b86-9a50-97db5e4ca806",
+ "artifactDescription": " Vendor license file",
+ "artifactChecksum": "YTNhYTc3ZGE4ZWViMmYzOThkOGQ3ZTVjZGNmNmU0ZmQ=",
+ "artifactUUID": "6cd5f968-20aa-4b86-9a50-97db5e4ca806",
+ "artifactVersion": "1",
+ "artifactLabel": "vendorlicense",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "base_vpkg.env",
+ "artifactType": "HEAT_ENV",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/60944038-d382-4aa6-b387-7b87c9c9df19",
+ "artifactDescription": "Auto-generated HEAT Environment deployment artifact",
+ "artifactChecksum": "OGU0OGFlZTFiZDdhYmQ0MmM0MjAyY2U5YjljYWViYTA=",
+ "artifactUUID": "60944038-d382-4aa6-b387-7b87c9c9df19",
+ "artifactVersion": "2",
+ "generatedFromUUID": "0d3918df-ea14-4fc3-a5c9-34032eaae573.heat1",
+ "artifactLabel": "heat1env",
+ "artifactGroupType": "DEPLOYMENT"
+ }
+ ]
+ }
+ ],
+ "artifacts": [{
+ "artifactName": "AAI-vFW-service-2VF-based-service-2.0.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/2e6cd967-93c2-4f53-82bd-c56ab98e8df7",
+ "artifactDescription": "AAI Service Model",
+ "artifactChecksum": "ZTY5ZTJmYTY4YzE2NGUxMTQxNWNkN2QzMmI4MWIzNDU=",
+ "artifactUUID": "2e6cd967-93c2-4f53-82bd-c56ab98e8df7",
+ "artifactVersion": "1",
+ "artifactLabel": "aaiservice1603481860",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "AAI-Vpkg..base_vpkg..module-0-resource-2.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/ad600a09-edde-4356-bb0a-9e638a671d06",
+ "artifactDescription": "AAI Resource Model",
+ "artifactChecksum": "MzQyMjczOGVmYzM1OWQ1NmFhZjBhOWUxM2JjMmYxZTQ=",
+ "artifactUUID": "ad600a09-edde-4356-bb0a-9e638a671d06",
+ "artifactVersion": "1",
+ "artifactLabel": "aairesource529289386",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "AAI-vFW-vSINK-resource-2.0.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/413a631e-69c4-453b-ab68-fac09b390259",
+ "artifactDescription": "AAI Resource Model",
+ "artifactChecksum": "ZWRmMzQzYzc0MThlYjQ1YjY2ZTFkYzJmMjAyNzQ1YWU=",
+ "artifactUUID": "413a631e-69c4-453b-ab68-fac09b390259",
+ "artifactVersion": "1",
+ "artifactLabel": "aairesource1461475898",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "AAI-vPkG-resource-2.0.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/aee30754-eec4-4820-ae3a-790b80b76e81",
+ "artifactDescription": "AAI Resource Model",
+ "artifactChecksum": "OGQ4ZTdhYjkyZDRkYmFiZTBhNWU4MDc4YTM2YjY1NmI=",
+ "artifactUUID": "aee30754-eec4-4820-ae3a-790b80b76e81",
+ "artifactVersion": "1",
+ "artifactLabel": "aairesource936479495",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "AAI-VfwVsink..base_vfw..module-0-resource-2.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/ac9a3bbf-a052-4176-abff-fe2d2741194a",
+ "artifactDescription": "AAI Resource Model",
+ "artifactChecksum": "OWIzNjVhNmI2ZWYyZThlMjk1NjA2MDFhZTU3MGQ0ZDU=",
+ "artifactUUID": "ac9a3bbf-a052-4176-abff-fe2d2741194a",
+ "artifactVersion": "1",
+ "artifactLabel": "aairesource1106409880",
+ "artifactGroupType": "DEPLOYMENT"
+ }
+ ]
+ },
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ }
+} \ No newline at end of file
diff --git a/src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439_tosca.json b/src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439_tosca.json
new file mode 100644
index 0000000..2090397
--- /dev/null
+++ b/src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439_tosca.json
@@ -0,0 +1,10 @@
+{
+ "request": {
+ "method": "GET",
+ "urlPath": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/toscaModel"
+ },
+ "response": {
+ "status": 200,
+ "bodyFileName": "response"
+ }
+} \ No newline at end of file
diff --git a/src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439_withoutTosca.json b/src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439_withoutTosca.json
new file mode 100644
index 0000000..567503a
--- /dev/null
+++ b/src/test/resources/mappings/sdc_get_1e3feeb0-8e36-46c6-862c-236d9c626439_withoutTosca.json
@@ -0,0 +1,213 @@
+{
+ "request": {
+ "method": "GET",
+ "urlPath": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439_withoutTosca/metadata"
+ },
+ "response": {
+ "status": 200,
+ "jsonBody": {
+ "uuid": "1e3feeb0-8e36-46c6-862c-236d9c626439",
+ "invariantUUID": "b58a118e-eeb9-4f6e-bdca-e292f84d17df",
+ "name": "vFW",
+ "version": "2.0",
+ "toscaModelURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439toto/toscaModel",
+ "category": "Network Service",
+ "lifecycleState": "CERTIFIED",
+ "lastUpdaterUserId": "jm0007",
+ "distributionStatus": "DISTRIBUTED",
+ "lastUpdaterFullName": "Joni Mitchell",
+ "resources": [{
+ "resourceInstanceName": "vFW-vSINK 0",
+ "resourceName": "vFW-vSINK",
+ "resourceInvariantUUID": "18b90934-aa82-456f-938e-e74a07a426f3",
+ "resourceVersion": "2.0",
+ "resoucreType": "VF",
+ "resourceUUID": "89a6b4c5-3973-4c19-b651-fae3713ca8d5",
+ "artifacts": [{
+ "artifactName": "vf-license-model.xml",
+ "artifactType": "VF_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/f6fa3f94-f5cd-4233-a7b2-b5e8dc2e1ec6",
+ "artifactDescription": "VF license file",
+ "artifactChecksum": "NDQ2NzIxNzgyMjZhNTc1NDNlMWU0ODI1ZmIyNjc3Zjg=",
+ "artifactUUID": "f6fa3f94-f5cd-4233-a7b2-b5e8dc2e1ec6",
+ "artifactVersion": "1",
+ "artifactLabel": "vflicense",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "vfwvsink0_modules.json",
+ "artifactType": "VF_MODULES_METADATA",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/d0aaecf9-6ffb-4b4b-81fd-c59c1e8e6fb6",
+ "artifactDescription": "Auto-generated VF Modules information artifact",
+ "artifactChecksum": "ZGIyOWY3YzE0MTM2MjlhMjY1ZjkzNDg3YjE2ZmQxY2Y=",
+ "artifactUUID": "d0aaecf9-6ffb-4b4b-81fd-c59c1e8e6fb6",
+ "artifactVersion": "1",
+ "artifactLabel": "vfModulesMetadata",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "base_vfw.yaml",
+ "artifactType": "HEAT",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/c94e8eec-b1a7-431c-ab6f-2fda5f0ee920",
+ "artifactDescription": "created from csar",
+ "artifactTimeout": 60,
+ "artifactChecksum": "YTY0MDg5ODUwZDE4YzQyYWI0NjE5Y2NjYmM3ZDg5ZGE=",
+ "artifactUUID": "c94e8eec-b1a7-431c-ab6f-2fda5f0ee920",
+ "artifactVersion": "4",
+ "artifactLabel": "heat1",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "vendor-license-model.xml",
+ "artifactType": "VENDOR_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/423d2c66-6c3a-4257-9342-7b57ebf9dd54",
+ "artifactDescription": " Vendor license file",
+ "artifactChecksum": "YTNhYTc3ZGE4ZWViMmYzOThkOGQ3ZTVjZGNmNmU0ZmQ=",
+ "artifactUUID": "423d2c66-6c3a-4257-9342-7b57ebf9dd54",
+ "artifactVersion": "1",
+ "artifactLabel": "vendorlicense",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "base_vfw.env",
+ "artifactType": "HEAT_ENV",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vfwvsink0/artifacts/a1a58cc9-8225-4b6f-b81a-02fa3c7fb6ec",
+ "artifactDescription": "Auto-generated HEAT Environment deployment artifact",
+ "artifactChecksum": "ZmVkM2MwODhlZjcwNWY5MDk5ZGEyMjI5ZTAyYWRjNjY=",
+ "artifactUUID": "a1a58cc9-8225-4b6f-b81a-02fa3c7fb6ec",
+ "artifactVersion": "2",
+ "generatedFromUUID": "32591489-33c9-4461-a47c-7c463250788d.heat1",
+ "artifactLabel": "heat1env",
+ "artifactGroupType": "DEPLOYMENT"
+ }
+ ]
+ },
+ {
+ "resourceInstanceName": "vPkG 0",
+ "resourceName": "vPkG",
+ "resourceInvariantUUID": "8d8a20c0-746c-4d5e-a1a2-fa49fa5786ad",
+ "resourceVersion": "2.0",
+ "resoucreType": "VF",
+ "resourceUUID": "31961e27-2a2c-4beb-87c9-bfe0067088f5",
+ "artifacts": [{
+ "artifactName": "vf-license-model.xml",
+ "artifactType": "VF_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/7af6cc3b-2ba3-4164-9d7d-65b3b46a71f4",
+ "artifactDescription": "VF license file",
+ "artifactChecksum": "MWM5NDlmNjdhZTdmZTA5MzIzY2RhYjcxZmFkYzQyZDM=",
+ "artifactUUID": "7af6cc3b-2ba3-4164-9d7d-65b3b46a71f4",
+ "artifactVersion": "1",
+ "artifactLabel": "vflicense",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "vpkg0_modules.json",
+ "artifactType": "VF_MODULES_METADATA",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/37b16173-bd54-447f-a5a2-1a5e24db8afb",
+ "artifactDescription": "Auto-generated VF Modules information artifact",
+ "artifactChecksum": "ZDA3MWQ3MTE3MTA1MzNkY2M1ODQ4YTUxN2YwMDk0MmM=",
+ "artifactUUID": "37b16173-bd54-447f-a5a2-1a5e24db8afb",
+ "artifactVersion": "1",
+ "artifactLabel": "vfModulesMetadata",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "base_vpkg.yaml",
+ "artifactType": "HEAT",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/43184998-c107-40a7-92f6-00ba74de8539",
+ "artifactDescription": "created from csar",
+ "artifactTimeout": 60,
+ "artifactChecksum": "NDZhY2U0YTExZjllNTFmZjc4ZTE4YzU2Zjk1ZDc2MWI=",
+ "artifactUUID": "43184998-c107-40a7-92f6-00ba74de8539",
+ "artifactVersion": "4",
+ "artifactLabel": "heat1",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "vendor-license-model.xml",
+ "artifactType": "VENDOR_LICENSE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/6cd5f968-20aa-4b86-9a50-97db5e4ca806",
+ "artifactDescription": " Vendor license file",
+ "artifactChecksum": "YTNhYTc3ZGE4ZWViMmYzOThkOGQ3ZTVjZGNmNmU0ZmQ=",
+ "artifactUUID": "6cd5f968-20aa-4b86-9a50-97db5e4ca806",
+ "artifactVersion": "1",
+ "artifactLabel": "vendorlicense",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "base_vpkg.env",
+ "artifactType": "HEAT_ENV",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/resourceInstances/vpkg0/artifacts/60944038-d382-4aa6-b387-7b87c9c9df19",
+ "artifactDescription": "Auto-generated HEAT Environment deployment artifact",
+ "artifactChecksum": "OGU0OGFlZTFiZDdhYmQ0MmM0MjAyY2U5YjljYWViYTA=",
+ "artifactUUID": "60944038-d382-4aa6-b387-7b87c9c9df19",
+ "artifactVersion": "2",
+ "generatedFromUUID": "0d3918df-ea14-4fc3-a5c9-34032eaae573.heat1",
+ "artifactLabel": "heat1env",
+ "artifactGroupType": "DEPLOYMENT"
+ }
+ ]
+ }
+ ],
+ "artifacts": [{
+ "artifactName": "AAI-vFW-service-2VF-based-service-2.0.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/2e6cd967-93c2-4f53-82bd-c56ab98e8df7",
+ "artifactDescription": "AAI Service Model",
+ "artifactChecksum": "ZTY5ZTJmYTY4YzE2NGUxMTQxNWNkN2QzMmI4MWIzNDU=",
+ "artifactUUID": "2e6cd967-93c2-4f53-82bd-c56ab98e8df7",
+ "artifactVersion": "1",
+ "artifactLabel": "aaiservice1603481860",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "AAI-Vpkg..base_vpkg..module-0-resource-2.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/ad600a09-edde-4356-bb0a-9e638a671d06",
+ "artifactDescription": "AAI Resource Model",
+ "artifactChecksum": "MzQyMjczOGVmYzM1OWQ1NmFhZjBhOWUxM2JjMmYxZTQ=",
+ "artifactUUID": "ad600a09-edde-4356-bb0a-9e638a671d06",
+ "artifactVersion": "1",
+ "artifactLabel": "aairesource529289386",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "AAI-vFW-vSINK-resource-2.0.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/413a631e-69c4-453b-ab68-fac09b390259",
+ "artifactDescription": "AAI Resource Model",
+ "artifactChecksum": "ZWRmMzQzYzc0MThlYjQ1YjY2ZTFkYzJmMjAyNzQ1YWU=",
+ "artifactUUID": "413a631e-69c4-453b-ab68-fac09b390259",
+ "artifactVersion": "1",
+ "artifactLabel": "aairesource1461475898",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "AAI-vPkG-resource-2.0.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/aee30754-eec4-4820-ae3a-790b80b76e81",
+ "artifactDescription": "AAI Resource Model",
+ "artifactChecksum": "OGQ4ZTdhYjkyZDRkYmFiZTBhNWU4MDc4YTM2YjY1NmI=",
+ "artifactUUID": "aee30754-eec4-4820-ae3a-790b80b76e81",
+ "artifactVersion": "1",
+ "artifactLabel": "aairesource936479495",
+ "artifactGroupType": "DEPLOYMENT"
+ },
+ {
+ "artifactName": "AAI-VfwVsink..base_vfw..module-0-resource-2.xml",
+ "artifactType": "MODEL_INVENTORY_PROFILE",
+ "artifactURL": "/sdc/v1/catalog/services/1e3feeb0-8e36-46c6-862c-236d9c626439/artifacts/ac9a3bbf-a052-4176-abff-fe2d2741194a",
+ "artifactDescription": "AAI Resource Model",
+ "artifactChecksum": "OWIzNjVhNmI2ZWYyZThlMjk1NjA2MDFhZTU3MGQ0ZDU=",
+ "artifactUUID": "ac9a3bbf-a052-4176-abff-fe2d2741194a",
+ "artifactVersion": "1",
+ "artifactLabel": "aairesource1106409880",
+ "artifactGroupType": "DEPLOYMENT"
+ }
+ ]
+ },
+ "headers": {
+ "Content-Type": "application/json"
+ }
+ }
+} \ No newline at end of file