summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeora Barsky <georab@amdocs.com>2018-10-12 11:46:52 -0400
committerPhillip Leigh <phillip.leigh@amdocs.com>2018-10-12 17:06:49 -0400
commit696b3aab041353afd74e26c0b9a569d0b1b9e254 (patch)
tree31830f0df17dc5c01bcf0eb72eeae845d8ed3257
parenta2423cf3ba54da34bb865befd44d56bbb925a94b (diff)
Adding API Mapping infrastructure
Issue-ID: LOG-391 Change-Id: I30d954bcdf1cf0748bb5249cbf10defb8dbc8ff6 Signed-off-by: Geora Barsky <georab@amdocs.com>
-rw-r--r--config/application.properties20
-rw-r--r--config/dynamic/conf/api-handlers.xml13
-rw-r--r--config/dynamic/routes/sdnc-api.route17
-rw-r--r--config/rules/api-mapping-rules.drl39
-rw-r--r--pom.xml34
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/sdnc/Application.java29
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/sdnc/SdncConfiguration.java69
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/sdnc/SpringXMLConfig.java28
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/sdnc/handlers/GenericResourceApiHandler.java68
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/sdnc/handlers/VnfApiHandler.java52
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/sdnc/model/ServiceEntity.java73
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/sdnc/service/SpringServiceImpl.java65
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/sdnc/util/RestUtil.java211
-rw-r--r--src/test/java/org/onap/pomba/contextbuilder/sdnc/unittest/service/SdncContextBuilderTest.java101
-rw-r--r--src/test/resources/junit/aaiResourcesData-1.json8
-rw-r--r--src/test/resources/junit/customerData-1.json6
-rw-r--r--src/test/resources/junit/customerData-CustomerIdNotFound.json6
-rw-r--r--src/test/resources/junit/queryNodeData-1.json8
-rw-r--r--src/test/resources/junit/queryNodeData-nullResourceLink.json8
-rw-r--r--src/test/resources/sdncResponse.json2
20 files changed, 821 insertions, 36 deletions
diff --git a/config/application.properties b/config/application.properties
index 6ad4731..8fc2503 100644
--- a/config/application.properties
+++ b/config/application.properties
@@ -18,7 +18,8 @@
spring.jersey.type=filter
spring.mvc.urls=swagger,docs,prometheus,auditevents,info,heapdump,autoconfig,beans,loggers,dump,env,trace,health,configprops,mappings,metrics,webjars
-
+camel.springboot.xmlRoutes = file:config/dynamic/routes/*.route
+service.xml.beans = config/dynamic/conf/*.xml
server.contextPath=/sdnccontextbuilder/v1
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
@@ -46,3 +47,20 @@ sdnc.genericResourcePath=/restconf/config/GENERIC-RESOURCE-API:services/service/
#Servlet context parameters
server.context_parameters.p-name=value #context parameter with p-name as key and value as value.
+
+# AAI REST Client Configuration
+aai.serviceName=10.12.6.120
+aai.servicePort=30233
+aai.username=AAI
+aai.password=OBF:1gfr1ev31gg7
+aai.httpProtocol=https
+aai.connectionTimeout=5000
+aai.readTimeout=1000
+
+# HTTP Basic Authorization credentials for AAI Rest Service API
+aai.http.userId=admin
+aai.http.password=OBF:1u2a1toa1w8v1tok1u30
+
+aai.searchNodeQuery=/aai/v11/search/nodes-query?search-node-type=service-instance&filter=service-instance-id:EQUALS:
+aai.customerQuery=/aai/v11/business/customers/customer/
+
diff --git a/config/dynamic/conf/api-handlers.xml b/config/dynamic/conf/api-handlers.xml
new file mode 100644
index 0000000..8ad08c5
--- /dev/null
+++ b/config/dynamic/conf/api-handlers.xml
@@ -0,0 +1,13 @@
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean id="vnfApiHandler" class="org.onap.pomba.contextbuilder.sdnc.handlers.VnfApiHandler" >
+ </bean>
+
+ <bean id="genericResourceApiHandler" class="org.onap.pomba.contextbuilder.sdnc.handlers.GenericResourceApiHandler" >
+ </bean>
+
+</beans> \ No newline at end of file
diff --git a/config/dynamic/routes/sdnc-api.route b/config/dynamic/routes/sdnc-api.route
new file mode 100644
index 0000000..19bc5ec
--- /dev/null
+++ b/config/dynamic/routes/sdnc-api.route
@@ -0,0 +1,17 @@
+<route xmlns="http://camel.apache.org/schema/spring" trace="true" id="apiMapperRoute">
+ <from uri="direct:startRoutingProcess" />
+ <choice>
+ <when>
+ <simple>${in.body.apiName} == 'VNF-API'</simple>
+ <log message="Processing ${in.body.apiName} by Camel Routing Context"/>
+ <to uri="bean:vnfApiHandler?method=process"/>
+ </when>
+ <when>
+ <simple>${in.body.apiName} == 'GENERIC-RESOURCE-API'</simple>
+ <log message="Processing ${in.body.apiName} by Camel Routing Context"/>
+ <to uri="bean:genericResourceApiHandler?method=process"/>
+ </when>
+ </choice>
+</route>
+
+
diff --git a/config/rules/api-mapping-rules.drl b/config/rules/api-mapping-rules.drl
new file mode 100644
index 0000000..6278d48
--- /dev/null
+++ b/config/rules/api-mapping-rules.drl
@@ -0,0 +1,39 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.pomba.contextbuilder.sdnc.rules;
+
+import org.onap.pomba.contextbuilder.sdnc.model.ServiceEntity;
+
+rule "ApiMapping-1"
+ no-loop true
+ lock-on-active true
+ when
+ $s : ServiceEntity( serviceType not contains "vFW" )
+ then
+ $s.setApiName("GENERIC-RESOURCE-API");
+end
+
+
+rule "ApiMapping-2"
+ no-loop true
+ lock-on-active true
+ when
+ $s : ServiceEntity( serviceType contains "vFW" )
+ then
+ $s.setApiName("VNF-API");
+end
diff --git a/pom.xml b/pom.xml
index 6c4a843..d1bea76 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,11 +31,13 @@ limitations under the License.
</parent>
<properties>
+ <camel-spring-boot.version>2.21.1</camel-spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<swagger.directory>${project.build.directory}/generated-resources/swagger</swagger.directory>
<!--docker -->
<docker.tag>${project.version}-${timestamp}</docker.tag>
<docker.latest.tag>${project.version}-latest</docker.latest.tag>
+ <kie.version>7.1.0.Final</kie.version>
</properties>
<dependencyManagement>
@@ -48,6 +50,13 @@ limitations under the License.
<type>pom</type>
<scope>import</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-spring-boot-dependencies</artifactId>
+ <version>${camel-spring-boot.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
@@ -95,7 +104,21 @@ limitations under the License.
</exclusion>
</exclusions>
</dependency>
-
+ <!-- camel dependencies -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-spring-boot-starter</artifactId>
+ <version>${camel-spring-boot.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core</artifactId>
+ <version>${camel-spring-boot.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-servlet-starter</artifactId>
+ </dependency>
<!-- logging dependencies -->
<dependency>
<groupId>org.slf4j</groupId>
@@ -146,12 +169,17 @@ limitations under the License.
<artifactId>json-utils</artifactId>
<version>0.1.0</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.onap.aai</groupId>
<artifactId>rest-client</artifactId>
<version>1.2.1</version>
</dependency>
-
+ <!-- Drools dependencies -->
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-ci</artifactId>
+ <version>${kie.version}</version>
+ </dependency>
<!-- Test dependencies -->
<dependency>
diff --git a/src/main/java/org/onap/pomba/contextbuilder/sdnc/Application.java b/src/main/java/org/onap/pomba/contextbuilder/sdnc/Application.java
index e0ebfc8..93dd886 100644
--- a/src/main/java/org/onap/pomba/contextbuilder/sdnc/Application.java
+++ b/src/main/java/org/onap/pomba/contextbuilder/sdnc/Application.java
@@ -18,7 +18,13 @@
package org.onap.pomba.contextbuilder.sdnc;
-import org.apache.velocity.app.VelocityEngine;
+import org.kie.api.KieServices;
+import org.kie.api.builder.KieBuilder;
+import org.kie.api.builder.KieFileSystem;
+import org.kie.api.builder.KieRepository;
+import org.kie.api.io.Resource;
+import org.kie.api.io.ResourceType;
+import org.kie.api.runtime.KieContainer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -30,8 +36,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
+import java.io.File;
+
@SpringBootApplication
-@ComponentScan(basePackages = "org.onap.pomba.contextbuilder.sdnc")
+@ComponentScan(basePackages = {"org.onap.pomba.contextbuilder.sdnc","org.kie.api"})
@EnableAsync
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
public class Application extends SpringBootServletInitializer {
@@ -45,9 +53,18 @@ public class Application extends SpringBootServletInitializer {
}
@Bean
- public VelocityEngine velocityEngine() {
- VelocityEngine velocityEngine = new VelocityEngine();
- velocityEngine.init();
- return velocityEngine;
+ public KieContainer kieContainer() {
+
+ KieServices kServices = KieServices.Factory.get();
+ KieFileSystem kfs = kServices.newKieFileSystem();
+ KieRepository kr = kServices.getRepository();
+ File file = new File("config/rules/api-mapping-rules.drl");
+ Resource resource = kServices.getResources().newFileSystemResource(file).setResourceType(ResourceType.DRL);
+ kfs.write(resource);
+
+ KieBuilder kb = kServices.newKieBuilder(kfs);
+ kb.buildAll();
+ KieContainer kContainer = kServices.newKieContainer(kr.getDefaultReleaseId());
+ return kContainer;
}
} \ No newline at end of file
diff --git a/src/main/java/org/onap/pomba/contextbuilder/sdnc/SdncConfiguration.java b/src/main/java/org/onap/pomba/contextbuilder/sdnc/SdncConfiguration.java
index ec5c8b3..71c3502 100644
--- a/src/main/java/org/onap/pomba/contextbuilder/sdnc/SdncConfiguration.java
+++ b/src/main/java/org/onap/pomba/contextbuilder/sdnc/SdncConfiguration.java
@@ -24,7 +24,7 @@ import org.eclipse.jetty.util.security.Password;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
-
+import org.onap.aai.restclient.client.RestClient;
@Component
@ApplicationPath("/")
@@ -70,5 +70,72 @@ public class SdncConfiguration {
return ("Basic " + Base64.getEncoder().encodeToString(auth.getBytes()));
}
+ /* AAI related interfaces */
+ @Value("${aai.serviceName}")
+ private String aaiHost;
+ @Value("${aai.servicePort}")
+ private String aaiPort;
+ @Value("${aai.username}")
+ private String aaiUsername;
+ @Value("${aai.password}")
+ private String aaiPassword;
+ @Value("${aai.httpProtocol}")
+ private String aaiHttpProtocol;
+ @Value("${aai.connectionTimeout}")
+ private Integer aaiConnectionTimeout;
+ @Value("${aai.readTimeout}")
+ private Integer aaiReadTimeout;
+
+ @Value("${aai.http.userId}")
+ private String aaiHttpUserId;
+
+ @Value("${aai.http.password}")
+ private String aaiHttpPassword;
+
+ @Value("${aai.searchNodeQuery}")
+ private String aaiSearchNodeQuery;
+
+ @Value("${aai.customerQuery}")
+ private String aaiCustomerQuery;
+
+ @Bean(name="aaiHttpBasicAuthorization")
+ public String getHttpBasicAuth() {
+ String auth = new String(this.aaiHttpUserId + ":" + Password.deobfuscate(this.aaiHttpPassword));
+
+ String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());
+ return ("Basic " + encodedAuth);
+ }
+
+ @Bean(name="aaiBasicAuthorization")
+ public String getAAIBasicAuth() {
+ String auth = new String(this.aaiUsername + ":" + Password.deobfuscate(this.aaiPassword));
+ String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());
+ return ("Basic " + encodedAuth);
+ }
+
+ @Bean(name="aaiClient")
+ public RestClient restClient() {
+ RestClient restClient = new RestClient();
+ restClient.validateServerHostname(false).validateServerCertChain(false).connectTimeoutMs(aaiConnectionTimeout).readTimeoutMs(aaiReadTimeout);
+ restClient.basicAuthUsername(aaiUsername);
+ restClient.basicAuthPassword(Password.deobfuscate(aaiPassword));
+ return restClient;
+ }
+
+ @Bean(name="aaiBaseUrl")
+ public String getAaiURL() {
+ return httpProtocol + "://" + aaiHost + ":" + aaiPort;
+
+ }
+
+ @Bean(name="aaiPathToSearchNodeQuery")
+ public String getAaiPathToSearchNodeQuery() {
+ return aaiSearchNodeQuery.trim();
+ }
+
+ @Bean(name="aaiPathToCustomerQuery")
+ public String getAaiPathToCustomerQuery() {
+ return aaiCustomerQuery.trim();
+ }
}
diff --git a/src/main/java/org/onap/pomba/contextbuilder/sdnc/SpringXMLConfig.java b/src/main/java/org/onap/pomba/contextbuilder/sdnc/SpringXMLConfig.java
new file mode 100644
index 0000000..db38754
--- /dev/null
+++ b/src/main/java/org/onap/pomba/contextbuilder/sdnc/SpringXMLConfig.java
@@ -0,0 +1,28 @@
+/**
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.pomba.contextbuilder.sdnc;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+
+@Configuration
+@ImportResource({"file:${service.xml.beans}"})
+public class SpringXMLConfig {
+
+
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/pomba/contextbuilder/sdnc/handlers/GenericResourceApiHandler.java b/src/main/java/org/onap/pomba/contextbuilder/sdnc/handlers/GenericResourceApiHandler.java
new file mode 100644
index 0000000..885c923
--- /dev/null
+++ b/src/main/java/org/onap/pomba/contextbuilder/sdnc/handlers/GenericResourceApiHandler.java
@@ -0,0 +1,68 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=====================================================
+ */
+
+package org.onap.pomba.contextbuilder.sdnc.handlers;
+
+import org.apache.camel.Exchange;
+import org.onap.pomba.common.datatypes.ModelContext;
+import org.onap.pomba.contextbuilder.sdnc.exception.AuditException;
+import org.onap.pomba.contextbuilder.sdnc.model.ServiceEntity;
+import org.onap.pomba.contextbuilder.sdnc.util.RestUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.ws.rs.client.Client;
+
+@Component
+public class GenericResourceApiHandler {
+
+ private static Logger log = LoggerFactory.getLogger(GenericResourceApiHandler.class);
+ @Autowired
+ private Client jerseyClient;
+ @Autowired
+ private String sdncBaseUrl;
+ @Autowired
+ private String sdncBasicAuthorization;
+ @Autowired
+ private String sdncGenericResourcePath;
+
+
+
+ public ModelContext process(Exchange exchange) throws Exception {
+
+ ModelContext context;
+ log.info("in GENERIC-RESOURCE-API HANDLER: ");
+
+ ServiceEntity serviceEntity = (ServiceEntity)exchange.getIn().getBody();
+ String serviceInstanceId = serviceEntity.getServiceInstanceId();
+
+ try {
+ String sdncResponse = RestUtil.getSdncGenericResource(jerseyClient, sdncBaseUrl, sdncBasicAuthorization, sdncGenericResourcePath, serviceInstanceId);
+ context = RestUtil.transform(sdncResponse);
+ } catch (AuditException ae) {
+ throw ae;
+ } catch (Exception e) {
+ throw new AuditException(e.getLocalizedMessage());
+ }
+
+ return context;
+ }
+
+}
diff --git a/src/main/java/org/onap/pomba/contextbuilder/sdnc/handlers/VnfApiHandler.java b/src/main/java/org/onap/pomba/contextbuilder/sdnc/handlers/VnfApiHandler.java
new file mode 100644
index 0000000..bfedf69
--- /dev/null
+++ b/src/main/java/org/onap/pomba/contextbuilder/sdnc/handlers/VnfApiHandler.java
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=====================================================
+ */
+
+package org.onap.pomba.contextbuilder.sdnc.handlers;
+
+import org.apache.camel.Exchange;
+import org.onap.pomba.common.datatypes.ModelContext;
+import org.onap.pomba.common.datatypes.Service;
+import org.onap.pomba.contextbuilder.sdnc.model.ServiceEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class VnfApiHandler {
+
+ private static Logger log = LoggerFactory.getLogger(VnfApiHandler.class);
+
+ public ModelContext process(Exchange exchange) throws Exception {
+
+ log.info("in VNF-API HANDLER: ");
+
+// dummy population of the model context
+// The following lines should be replaced with the logic of calling to SDN-C VNF-API
+// and transforming the response into common model
+ ModelContext context = new ModelContext();
+ Service service = new Service();
+ ServiceEntity serviceEntity = (ServiceEntity)exchange.getIn().getBody();
+ service.setName( serviceEntity.getServiceType() + " service instance");
+ context.setService(service);
+// end dummy code
+
+ return context;
+ }
+
+
+}
diff --git a/src/main/java/org/onap/pomba/contextbuilder/sdnc/model/ServiceEntity.java b/src/main/java/org/onap/pomba/contextbuilder/sdnc/model/ServiceEntity.java
new file mode 100644
index 0000000..2f08533
--- /dev/null
+++ b/src/main/java/org/onap/pomba/contextbuilder/sdnc/model/ServiceEntity.java
@@ -0,0 +1,73 @@
+/*
+ * ============LICENSE_START===================================================
+ * Copyright (c) 2018 Amdocs
+ * ============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=====================================================
+ */
+package org.onap.pomba.contextbuilder.sdnc.model;
+
+public class ServiceEntity {
+
+ private String customerType;
+ private String customerName;
+ private String serviceType;
+ private String apiName;
+ private String serviceInstanceId;
+ private String customerId;
+
+ public String getCustomerId() {
+ return customerId;
+ }
+
+ public void setCustomerId(String customerId) {
+ this.customerId = customerId;
+ }
+
+ public String getServiceInstanceId() { return serviceInstanceId; }
+
+ public void setServiceInstanceId(String serviceInstanceId) { this.serviceInstanceId = serviceInstanceId; }
+
+ public String getCustomerType() {
+ return customerType;
+ }
+
+ public void setCustomerType(String customerType) {
+ this.customerType = customerType;
+ }
+
+ public String getCustomerName() {
+ return customerName;
+ }
+
+ public void setCustomerName(String customerName) {
+ this.customerName = customerName;
+ }
+
+ public String getServiceType() {
+ return serviceType;
+ }
+
+ public void setServiceType(String serviceType) {
+ this.serviceType = serviceType;
+ }
+
+ public String getApiName() {
+ return apiName;
+ }
+
+ public void setApiName(String apiName) {
+ this.apiName = apiName;
+ }
+
+}
diff --git a/src/main/java/org/onap/pomba/contextbuilder/sdnc/service/SpringServiceImpl.java b/src/main/java/org/onap/pomba/contextbuilder/sdnc/service/SpringServiceImpl.java
index daf6bf8..b19c24c 100644
--- a/src/main/java/org/onap/pomba/contextbuilder/sdnc/service/SpringServiceImpl.java
+++ b/src/main/java/org/onap/pomba/contextbuilder/sdnc/service/SpringServiceImpl.java
@@ -18,57 +18,82 @@
package org.onap.pomba.contextbuilder.sdnc.service;
-import javax.ws.rs.client.Client;
+import org.apache.camel.ProducerTemplate;
+import org.kie.api.runtime.KieContainer;
+import org.kie.api.runtime.KieSession;
import org.onap.pomba.common.datatypes.ModelContext;
import org.onap.pomba.contextbuilder.sdnc.exception.AuditException;
import org.onap.pomba.contextbuilder.sdnc.service.rs.RestService;
-import org.onap.pomba.contextbuilder.sdnc.util.RestUtil;
+import org.onap.pomba.contextbuilder.sdnc.model.ServiceEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import org.onap.pomba.contextbuilder.sdnc.util.RestUtil;
+import org.onap.aai.restclient.client.RestClient;
@Service
public class SpringServiceImpl implements SpringService {
private static Logger log = LoggerFactory.getLogger(RestService.class);
@Autowired
- private Client jerseyClient;
+ private String sdncCtxBuilderBasicAuthorization;
+ private KieContainer kieContainer;
@Autowired
- private String sdncBaseUrl;
+ private ProducerTemplate producerTemplate;
+
+ //AAI related
@Autowired
- private String sdncBasicAuthorization;
+ private String aaiBasicAuthorization;
@Autowired
- private String sdncGenericResourcePath;
+ private RestClient aaiClient;
@Autowired
- private String sdncCtxBuilderBasicAuthorization;
+ private String aaiBaseUrl;
+ @Autowired
+ private String aaiPathToSearchNodeQuery;
+ @Autowired
+ private String aaiPathToCustomerQuery;
public SpringServiceImpl() {
// needed for instantiation
}
+ @Autowired
+ public SpringServiceImpl(KieContainer kieContainer) {
+ this.kieContainer = kieContainer;
+
+ }
@Override
public ModelContext getContext(String serviceInstanceId, String transactionId) throws AuditException {
ModelContext context = null;
- String url = "serviceInstanceId=" + serviceInstanceId + " transactionId=" + transactionId;
- log.info("URL Query the SDN-C model data with URL: " , url);
-
- // Retrieve the service instance information from SDNC and AAI
- try {
- String sdncResponse = RestUtil.getSdncGenericResource(jerseyClient, sdncBaseUrl, sdncBasicAuthorization, sdncGenericResourcePath, serviceInstanceId);
- log.info("sdncResponse: ", sdncResponse);
- context = RestUtil.transform(sdncResponse);
- } catch (AuditException ae) {
- throw ae;
- } catch (Exception e) {
- throw new AuditException(e.getLocalizedMessage());
- }
+
+ // Call AAI system to populate ServiceData
+ ServiceEntity serviceEntity = RestUtil.getServiceEntity(aaiClient, aaiBaseUrl, aaiBasicAuthorization, aaiPathToSearchNodeQuery, aaiPathToCustomerQuery, serviceInstanceId, transactionId);
+
+ processApiMappingRules(serviceEntity);
+ log.info("SDN-C determined API: " + serviceEntity.getApiName());
+
+ context = producerTemplate.requestBody("direct:startRoutingProcess", serviceEntity, ModelContext.class);
+
return context;
}
+ private void processApiMappingRules(ServiceEntity serviceData){
+
+ KieSession kieSession = kieContainer.newKieSession();
+ log.info ("KIE Session is created");
+ kieSession.insert(serviceData);
+ kieSession.fireAllRules();
+ log.info("Rules are fired");
+ kieSession.getFactHandles().forEach(fh -> kieSession.delete(fh));
+ kieSession.dispose();
+ }
+
public String getSdncAuthoriztion() {
return sdncCtxBuilderBasicAuthorization;
}
+
+
}
diff --git a/src/main/java/org/onap/pomba/contextbuilder/sdnc/util/RestUtil.java b/src/main/java/org/onap/pomba/contextbuilder/sdnc/util/RestUtil.java
index 806514c..8701c89 100644
--- a/src/main/java/org/onap/pomba/contextbuilder/sdnc/util/RestUtil.java
+++ b/src/main/java/org/onap/pomba/contextbuilder/sdnc/util/RestUtil.java
@@ -34,6 +34,16 @@ import org.onap.pomba.contextbuilder.sdnc.exception.AuditException;
import org.onap.pomba.contextbuilder.sdnc.service.rs.RestService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.onap.aai.restclient.client.OperationResult;
+import org.onap.aai.restclient.client.RestClient;
+import javax.ws.rs.core.MediaType;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+import java.util.Map;
+import java.util.Collections;
+import javax.ws.rs.core.MultivaluedMap;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.onap.pomba.contextbuilder.sdnc.model.ServiceEntity;
public class RestUtil {
@@ -46,6 +56,22 @@ public class RestUtil {
public static final String FROM_APP_ID = "X-FromAppId";
public static final String AUTHORIZATION = "Authorization";
+ // AAI related
+ private static final String APP_NAME = "sdncCtxBuilder";
+ private static final String EMPTY_JSON_STRING = "{}";
+ private static final String JSON_ATT_RESOURCE_TYPE = "resource-type";
+ private static final String JSON_ATT_RESOURCE_LINK = "resource-link";
+ private static final String RESULT_DATA = "result-data";
+ private static final String CATALOG_SERVICE_INSTANCE = "service-instance";
+ private static final String CUSTOMER_ID_STRING = "/customers/customer/";
+ private static final String SERVICE_TYPE_STRING = "/service-subscriptions/service-subscription/";
+ private static final String CUSTOMER = "customer";
+ private static final String JSON_ATT_GLOBAL_CUSTOMER_ID = "global-customer-id";
+ private static final String JSON_ATT_SUBSCRIBER_TYPE = "subscriber-type";
+ private static final String JSON_ATT_SUBSCRIBER_NAME = "subscriber-name";
+
+ private static final String FORWARD_SLASH = "/";
+
// Parameters for Query SDNC Model Data REST API URL
private static final String SERVICE_INSTANCE_ID = "serviceInstanceId";
@@ -147,4 +173,189 @@ public class RestUtil {
return MessageFormat.format(siPath, vfModuleLink);
}
+ /**
+ * Get customer info from multiple AAI api
+ * @param aaiClient
+ * @param aaiBaseUrl
+ * @param aaiBasicAuthorization
+ * @param aaiPathToSearchNodeQuery
+ * @param aaiPathToCustomerQuery
+ * @param serviceInstaceId
+ * @param transactionId
+ * @return
+ * @throws AuditException
+ */
+ public static ServiceEntity getServiceEntity(RestClient aaiClient,
+ String aaiBaseUrl,
+ String aaiBasicAuthorization,
+ String aaiPathToSearchNodeQuery,
+ String aaiPathToCustomerQuery,
+ String serviceInstanceId,
+ String transactionId)throws AuditException {
+
+ String obtainResourceLink_url = generateUrl_ForResourceLink(aaiBaseUrl, aaiPathToSearchNodeQuery, serviceInstanceId);
+ String aaiResourceData = getAaiResource(aaiClient, obtainResourceLink_url, aaiBasicAuthorization, transactionId, MediaType.valueOf(MediaType.APPLICATION_JSON));
+
+ // Handle the case if the service instance is not found in AAI
+ if (isEmptyJson(aaiResourceData)) {
+ log.info(" Service Instance {} is not found from AAI", serviceInstanceId);
+ // Only return the empty Json on the root level. i.e service instance
+ return null;
+ }
+
+ String resourceLink = extractResourceLinkBasedOnServiceInstance(aaiResourceData, CATALOG_SERVICE_INSTANCE);
+
+ ServiceEntity serviceEntityObj = createServiceEntityObj (resourceLink); //customerId and serviceType are updated here.
+ if (serviceEntityObj != null) {
+ serviceEntityObj.setServiceInstanceId(serviceInstanceId);
+ String customerId = serviceEntityObj.getCustomerId();
+ // Obtain customerType and customerName
+ String obtainCustomer_url = generateUrl_ForCustomer (aaiBaseUrl, aaiPathToCustomerQuery, customerId);
+ String aaiCustomerData = getAaiResource(aaiClient, obtainCustomer_url, aaiBasicAuthorization, transactionId, MediaType.valueOf(MediaType.APPLICATION_JSON));
+ if (isEmptyJson(aaiCustomerData)) {
+ log.info(" Customer name {} is not found from AAI", customerId);
+ // Only return the empty Json on the root level. i.e service instance
+ throw new AuditException(INTERNAL_SERVER_ERROR + ": Customer ID cannot be found from AAI :" + customerId);
+ }
+ // Update customerType and customerName to the existing serviceEntityObj
+ updateServiceEntityObj ( aaiCustomerData , serviceEntityObj);
+ }
+
+ return serviceEntityObj;
+ }
+
+ private static boolean isEmptyJson(String serviceInstancePayload) {
+ return (serviceInstancePayload.equals(EMPTY_JSON_STRING));
+ }
+
+ private static String generateUrl_ForResourceLink (String aaiBaseURL, String aaiPathToSearchNodeQuery ,String serviceInstanceId) {
+ return aaiBaseURL + aaiPathToSearchNodeQuery + serviceInstanceId;
+ }
+
+ private static String generateUrl_ForCustomer (String aaiBaseURL, String aaiPathToCustomerQuery ,String customerId) {
+ return aaiBaseURL + aaiPathToCustomerQuery + customerId;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Map<String, List<String>> buildHeaders(String aaiBasicAuthorization, String transactionId) {
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.put(TRANSACTION_ID, Collections.singletonList(transactionId));
+ headers.put(FROM_APP_ID, Collections.singletonList(APP_NAME));
+ headers.put(AUTHORIZATION, Collections.singletonList(aaiBasicAuthorization));
+ return headers;
+ }
+
+ private static String getAaiResource(RestClient client, String url, String aaiBasicAuthorization, String transId, MediaType mediaType)
+ throws AuditException {
+ OperationResult result = client.get(url, buildHeaders(aaiBasicAuthorization, transId), MediaType.valueOf(MediaType.APPLICATION_JSON));
+
+ if (result.getResultCode() == 200) {
+ return result.getResult();
+ } else if (result.getResultCode() == 404) {
+ // Resource not found, generate empty JSON format
+ log.info("Resource for {} is not found: {}", url, "return empty Json format");
+ return new JSONObject().toString();
+
+ } else {
+ throw new AuditException(INTERNAL_SERVER_ERROR + " with " + result.getFailureCause());
+ }
+ }
+
+ /*
+ * Extract the resource-Link from Json payload. For example
+ * {
+ * "result-data": [
+ * {
+ * "resource-type": "service-instance",
+ * "resource-link": "/aai/v11/business/customers/customer/DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2/service-subscriptions/service-subscription/vFW/service-instances/service-instance/adc3cc2a-c73e-414f-8ddb-367de81300cb"
+ * }
+ * ]
+ * }
+ */
+ private static String extractResourceLinkBasedOnServiceInstance(String payload, String catalog) throws AuditException {
+ String resourceLink = null;
+ log.info("Fetching the resource-link based on resource-type=" + catalog);
+
+ try {
+ JSONArray result_data_list = new JSONObject(payload).getJSONArray(RESULT_DATA);
+ if (result_data_list != null) {
+ for (int i = 0; i < result_data_list.length(); i++) {
+ JSONObject obj = result_data_list.optJSONObject(i);
+ if (obj.has(JSON_ATT_RESOURCE_TYPE) && (obj.getString(JSON_ATT_RESOURCE_TYPE).equals(catalog) )) {
+ resourceLink = obj.getString(JSON_ATT_RESOURCE_LINK);
+ log.info(resourceLink);
+ return resourceLink;
+ }
+ }
+ }
+ } catch (JSONException e) {
+ log.error(e.getMessage());
+ throw new AuditException("Json Reader Parse Error " + e.getMessage());
+ }
+
+ log.warn("resource-link CANNOT be found: ", payload );
+
+ return resourceLink;
+ }
+
+ /*
+ * Extract the "subscriber-name" and "subscriber-type" from Json payload. For example
+ * {
+ * "global-customer-id": "OttoonMorph36",
+ * "subscriber-name": "OttoonMorph36",
+ * "subscriber-type": "CUST",
+ * "resource-version": "1526324315029"
+ * }
+ */
+ private static void updateServiceEntityObj(String payload, ServiceEntity serviceEntityObj) throws AuditException {
+ if (serviceEntityObj == null ) {
+ throw new AuditException("null pointer serviceEntityObj");
+ }
+ String customerId = serviceEntityObj.getCustomerId();
+ log.info("Fetching the subscriber type based on customer-id = " + customerId);
+
+ try {
+ JSONObject obj = new JSONObject (payload);
+ if (obj.has(JSON_ATT_GLOBAL_CUSTOMER_ID) && (obj.getString(JSON_ATT_GLOBAL_CUSTOMER_ID).equals(customerId) )) {
+ serviceEntityObj.setCustomerType(obj.getString(JSON_ATT_SUBSCRIBER_TYPE));
+ serviceEntityObj.setCustomerName(obj.getString(JSON_ATT_SUBSCRIBER_NAME));
+ return;
+ }
+ } catch (JSONException e) {
+ log.error(e.getMessage());
+ throw new AuditException("Json Reader Parse Error " + e.getMessage());
+ }
+
+ log.warn("subscriberType (" + customerId + ") CANNOT be found: ", payload );
+
+ return;
+ }
+
+ /* Look for "/customers/customer/" and "/service-subscriptions/service-subscription/" in resourceLink
+ * and find the customer id and service type.
+ * For example,
+ * "/aai/v11/business/customers/customer/DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2/service-subscriptions/service-subscription/vFW/service-instances/service-instance/adc3cc2a-c73e-414f-8ddb-367de81300cb"
+ * customerId = DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2
+ * serviceType = vFW
+ * */
+
+ private static ServiceEntity createServiceEntityObj (String resourceLink) {
+ int customer_id_idx = resourceLink.indexOf(CUSTOMER_ID_STRING);
+ int service_type_idx = resourceLink.indexOf(SERVICE_TYPE_STRING);
+
+ if (( customer_id_idx < 0 ) || ( service_type_idx < 0 )) {
+ return null;
+ }
+
+ ServiceEntity serviceEntity = new ServiceEntity ();
+ serviceEntity.setCustomerId(abstractStrInfo(resourceLink, CUSTOMER_ID_STRING));
+ serviceEntity.setServiceType(abstractStrInfo(resourceLink, SERVICE_TYPE_STRING));
+ return serviceEntity;
+ }
+
+ private static String abstractStrInfo (String origStr, String matchStr) {
+ String after = origStr.substring( origStr.indexOf(matchStr) + matchStr.length());
+
+ return after.substring(0, after.indexOf(FORWARD_SLASH));
+ }
}
diff --git a/src/test/java/org/onap/pomba/contextbuilder/sdnc/unittest/service/SdncContextBuilderTest.java b/src/test/java/org/onap/pomba/contextbuilder/sdnc/unittest/service/SdncContextBuilderTest.java
index 91ab1cf..2d21ca4 100644
--- a/src/test/java/org/onap/pomba/contextbuilder/sdnc/unittest/service/SdncContextBuilderTest.java
+++ b/src/test/java/org/onap/pomba/contextbuilder/sdnc/unittest/service/SdncContextBuilderTest.java
@@ -50,21 +50,44 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
+import org.onap.aai.restclient.client.RestClient;
+import org.onap.pomba.contextbuilder.sdnc.Application;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.UUID;
+import org.onap.pomba.contextbuilder.sdnc.model.ServiceEntity;
@RunWith(SpringJUnit4ClassRunner.class)
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@WebAppConfiguration
-@SpringBootTest
-@TestPropertySource(properties = {"sdnc.host=localhost", "sdnc.port=30202"})
+@SpringBootTest (classes = Application.class)
+@TestPropertySource(properties = {"sdnc.host=localhost", "sdnc.port=30202",
+ "aai.httpProtocol=http", "aai.serviceName=localhost", "aai.servicePort=9808"})
public class SdncContextBuilderTest {
- private String serviceInstanceId = "c6456519-6acf-4adb-997c-3c363dd4caaf";
+ private String serviceInstanceId = "7d518257-49bd-40ac-8d17-017a726ec12a"; //match to the test data in junit/queryNodeData-1.json
private String testRestHeaders = "testRestHeaders";
- @Autowired
+ private String customerId = "DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2"; // match to queryNodeData-1.json and customerData-1.json
+ @Autowired
RestService service;
@Autowired
private String sdncCtxBuilderBasicAuthorization;
+ //AAI related
+ @Autowired
+ private String aaiBasicAuthorization;
+ @Autowired
+ private RestClient aaiClient;
+ @Autowired
+ private String aaiBaseUrl;
+ @Autowired
+ private String aaiPathToSearchNodeQuery;
+ @Autowired
+ private String aaiPathToCustomerQuery;
+ @Rule
+ public WireMockRule aaiEnricherRule = new WireMockRule(wireMockConfig().port(9808));
+
@Rule
public WireMockRule sdncRule = new WireMockRule(wireMockConfig().port(30202));
@@ -129,6 +152,12 @@ public class SdncContextBuilderTest {
"testVerifyServiceDecomposition", "test1", sdncCtxBuilderBasicAuthorization);
when(mockHttpHeaders.getRequestHeaders()).thenReturn(multivaluedMapImpl);
+
+ String queryNodeUrl = aaiPathToSearchNodeQuery + serviceInstanceId;
+ addResponse(queryNodeUrl, "junit/queryNodeData-1.json", aaiEnricherRule);
+ String customerUrl = aaiPathToCustomerQuery + customerId;
+ addResponse(customerUrl, "junit/customerData-1.json", aaiEnricherRule);
+
Response response = this.service.getContext(mockHttpHeaders, serviceInstanceId);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -152,4 +181,68 @@ public class SdncContextBuilderTest {
}
return headers;
}
+
+ //AAI related
+
+ @Test
+ public void testObtainResouceLinkBasedOnServiceInstanceFromAAI() throws Exception {
+ String transactionId = UUID.randomUUID().toString();
+ String queryNodeUrl = aaiPathToSearchNodeQuery + serviceInstanceId;
+ addResponse(queryNodeUrl, "junit/queryNodeData-1.json", aaiEnricherRule);
+ String customerUrl = aaiPathToCustomerQuery + customerId;
+ addResponse(customerUrl, "junit/customerData-1.json", aaiEnricherRule);
+
+ ServiceEntity serviceEntity = RestUtil.getServiceEntity(aaiClient,aaiBaseUrl,aaiBasicAuthorization, aaiPathToSearchNodeQuery, aaiPathToCustomerQuery, serviceInstanceId, transactionId);
+
+ assertEquals(serviceInstanceId, serviceEntity.getServiceInstanceId());
+ assertEquals("vFW", serviceEntity.getServiceType()); // serviceType is hard-coded in queryNodeData-1.json
+ assertEquals(customerId, serviceEntity.getCustomerId()); // customerId is hard-coded in queryNodeData-1.json
+ assertEquals("DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2", serviceEntity.getCustomerName()); // customerName is hard-coded in queryNodeData-1.json
+ assertEquals("CUST", serviceEntity.getCustomerType()); //customerType is hard-coded in customerData-1.json
+ }
+
+ @Test
+ public void testObtainResouceLinkBasedOnServiceInstanceFromAAI_nullResourceLink() throws Exception {
+ String transactionId = UUID.randomUUID().toString();
+ String queryNodeUrl = aaiPathToSearchNodeQuery + serviceInstanceId;
+ addResponse(queryNodeUrl, "junit/queryNodeData-nullResourceLink.json", aaiEnricherRule);
+
+ try {
+ RestUtil.getServiceEntity(aaiClient,aaiBaseUrl,aaiBasicAuthorization, aaiPathToSearchNodeQuery, aaiPathToCustomerQuery, serviceInstanceId, transactionId);
+ } catch (Exception e) {
+ assertTrue(e.getMessage().contains("JSONObject[\"resource-link\"] not found"));
+ }
+ }
+
+ @Test
+ public void testObtainResouceLinkBasedOnServiceInstanceFromAAI_nullCustomerType() throws Exception {
+ String transactionId = UUID.randomUUID().toString();
+ String queryNodeUrl = aaiPathToSearchNodeQuery + serviceInstanceId;
+ addResponse(queryNodeUrl, "junit/queryNodeData-1.json", aaiEnricherRule);
+ String customerUrl = aaiPathToCustomerQuery + customerId;
+ addResponse(customerUrl, "junit/customerData-CustomerIdNotFound.json", aaiEnricherRule);
+
+ try {
+ RestUtil.getServiceEntity(aaiClient,aaiBaseUrl,aaiBasicAuthorization, aaiPathToSearchNodeQuery, aaiPathToCustomerQuery, serviceInstanceId, transactionId);
+ } catch (Exception e) {
+ assertTrue(e.getMessage().contains("Customer ID cannot be found from AAI"));
+ }
+ }
+
+ private void addResponse(String path, String classpathResource, WireMockRule thisMock) throws IOException {
+ String payload = readFully(ClassLoader.getSystemResourceAsStream(classpathResource));
+ thisMock.stubFor(get(path).willReturn(okJson(payload)));
+ }
+
+ private String readFully(InputStream in) throws IOException {
+ char[] cbuf = new char[1024];
+ StringBuilder content = new StringBuilder();
+ try (InputStreamReader reader = new InputStreamReader(in, "UTF-8")) {
+ int count;
+ while ((count = reader.read(cbuf)) >= 0) {
+ content.append(cbuf, 0, count);
+ }
+ }
+ return content.toString();
+ }
}
diff --git a/src/test/resources/junit/aaiResourcesData-1.json b/src/test/resources/junit/aaiResourcesData-1.json
new file mode 100644
index 0000000..66563d5
--- /dev/null
+++ b/src/test/resources/junit/aaiResourcesData-1.json
@@ -0,0 +1,8 @@
+{
+ "related-to": "vnfc",
+ "related-link": "/aai/v11/network/vnfcs/vnfc/zrdm5aepdg01vmg003",
+ "relationship-data": [
+ { "relationship-key": "vnfc.vnfc-name",
+ "relationship-value": "zrdm5aepdg01vmg003" }
+ ]
+} \ No newline at end of file
diff --git a/src/test/resources/junit/customerData-1.json b/src/test/resources/junit/customerData-1.json
new file mode 100644
index 0000000..31e6baa
--- /dev/null
+++ b/src/test/resources/junit/customerData-1.json
@@ -0,0 +1,6 @@
+{
+ "global-customer-id": "DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2",
+ "subscriber-name": "DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2",
+ "subscriber-type": "CUST",
+ "resource-version": "1526324315029"
+} \ No newline at end of file
diff --git a/src/test/resources/junit/customerData-CustomerIdNotFound.json b/src/test/resources/junit/customerData-CustomerIdNotFound.json
new file mode 100644
index 0000000..e2f71c6
--- /dev/null
+++ b/src/test/resources/junit/customerData-CustomerIdNotFound.json
@@ -0,0 +1,6 @@
+{
+ "global-customer-id": "dummy",
+ "subscriber-name": "dummy",
+ "subscriber-type": "CUST",
+ "resource-version": "1526324315029"
+} \ No newline at end of file
diff --git a/src/test/resources/junit/queryNodeData-1.json b/src/test/resources/junit/queryNodeData-1.json
new file mode 100644
index 0000000..e827391
--- /dev/null
+++ b/src/test/resources/junit/queryNodeData-1.json
@@ -0,0 +1,8 @@
+{
+ "result-data": [
+ {
+ "resource-type": "service-instance",
+ "resource-link": "/aai/v11/business/customers/customer/DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2/service-subscriptions/service-subscription/vFW/service-instances/service-instance/7d518257-49bd-40ac-8d17-017a726ec12a"
+ }
+ ]
+} \ No newline at end of file
diff --git a/src/test/resources/junit/queryNodeData-nullResourceLink.json b/src/test/resources/junit/queryNodeData-nullResourceLink.json
new file mode 100644
index 0000000..36eb667
--- /dev/null
+++ b/src/test/resources/junit/queryNodeData-nullResourceLink.json
@@ -0,0 +1,8 @@
+{
+ "result-data": [
+ {
+ "resource-type": "service-instance",
+ "related-link": "/aai/v11/network/vnfcs/vnfc/zrdm5aepdg01vmg003"
+ }
+ ]
+}
diff --git a/src/test/resources/sdncResponse.json b/src/test/resources/sdncResponse.json
index 25499c9..27b791a 100644
--- a/src/test/resources/sdncResponse.json
+++ b/src/test/resources/sdncResponse.json
@@ -1 +1 @@
-{"service":[{"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","service-status":{"final-indicator":"Y","rpc-action":"assign","rpc-name":"vf-module-topology-operation","response-code":"200","response-timestamp":"2018-08-27T01:58:25.652Z","action":"CreateVfModuleInstance","response-message":"","request-status":"synccomplete"},"service-data":{"service-request-input":{"service-instance-name":"vcpe_svc_vcpesvc_rescust_0822a_201808262153","service-input-parameters":{"param":[{"name":"BRG_WAN_MAC_Address","value":"fa:16:3e:79:24:0e"},{"name":"customerLongitude","value":"-97.040443"},{"name":"customerLatitude","value":"32.897480"},{"name":"Homing_Solution","value":"sniro"},{"name":"customerName","value":"some_company"}]}},"service-information":{"service-id":"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb","onap-model-information":{"model-invariant-uuid":"3a4e6986-5c5e-434e-b0be-8d718107fa83","model-name":"vcpesvc_rescust_0822a","model-version":"1.0","model-uuid":"209efacc-54d4-4f12-9064-099d47c36a29"},"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","global-customer-id":"SDN-ETHERNET-INTERNET","subscription-service-type":"vCPE"},"service-topology":{"service-topology-identifier":{"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","service-instance-name":"vcpe_svc_vcpesvc_rescust_0822a_201808262153","global-customer-id":"SDN-ETHERNET-INTERNET","service-type":"vCPE"},"onap-model-information":{"model-invariant-uuid":"3a4e6986-5c5e-434e-b0be-8d718107fa83","model-name":"vcpesvc_rescust_0822a","model-version":"1.0","model-uuid":"209efacc-54d4-4f12-9064-099d47c36a29"}},"sdnc-request-header":{"svc-action":"assign","svc-request-id":"dd3dffc8-6a15-4f7f-9787-d835ee247283","svc-notification-url":"http://c1.vm1.mso.simpledemo.openecomp.org:8080/adapters/rest/SDNCNotify"},"request-information":{"request-id":"2a950a5c-21bf-4496-a592-b51f45719603","request-action":"CreateServiceInstance","source":"MSO"},"vnfs":{"vnf":[{"vnf-id":"bf2a200d-744f-4900-afc4-d5ef44638467","vnf-data":{"vf-modules":{"vf-module":[{"vf-module-id":"815e8636-5c2a-41ad-b24d-17c824106bd2","vf-module-data":{"service-information":{"service-id":"null","onap-model-information":{"model-invariant-uuid":"3a4e6986-5c5e-434e-b0be-8d718107fa83","model-name":"vcpesvc_rescust_0822a","model-version":"1.0","model-uuid":"209efacc-54d4-4f12-9064-099d47c36a29"},"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","global-customer-id":"SDN-ETHERNET-INTERNET","subscription-service-type":"null"},"vf-module-topology":{"onap-model-information":{"model-invariant-uuid":"7e91451d-e320-4755-a1a8-fcf140b86779","model-name":"VcpevspVgw0822a..base_vcpe_vgw..module-0","model-version":"1","model-customization-uuid":"7fbb59b7-a7ac-4fa6-b0bc-42f47339010a","model-uuid":"1908874e-cfae-4ee1-93b9-f4ba46b460ff"},"vf-module-parameters":{"param":[{"name":"mux_ip_addr","value":"10.5.0.21"},{"name":"mux_gw_private_net_id","value":"vcpe_net_mux_gw_201808231522"},{"name":"vg_vgmux_tunnel_vni","value":"107"},{"name":"repo_url_artifacts","value":"https://nexus.onap.org/content/groups/staging"},{"name":"cpe_public_net_id","value":"vcpe_net_cpe_public_201808231522"},{"name":"key_name","value":"vgw_key"},{"name":"onap_private_subnet_id","value":"oam_onap_1MdY"},{"name":"cpe_public_net_cidr","value":"10.2.0.0/24"},{"name":"mux_gw_private_net_cidr","value":"10.5.0.0/24"},{"name":"cloud_env","value":"openstack"},{"name":"cpe_public_subnet_id","value":"vcpe_net_cpe_public_subnet_201808231522"},{"name":"mux_gw_private_subnet_id","value":"vcpe_net_mux_gw_subnet_201808231522"},{"name":"onap_private_net_id","value":"oam_onap_1MdY"},{"name":"repo_url_blob","value":"https://nexus.onap.org/content/sites/raw"},{"name":"install_script_version","value":"1.1.1"},{"name":"demo_artifacts_version","value":"1.1.1"},{"name":"vgw_name_0","value":"zdcpe1cpe01gw01_201808261550"},{"name":"vgw_private_ip_1","value":"10.0.101.99"},{"name":"vgw_private_ip_0","value":"10.5.0.107"},{"name":"public_net_id","value":"971040b2-7059-49dc-b220-4fab50cb2ad4"},{"name":"vgw_private_ip_2","value":"10.2.0.6"},{"name":"onap_private_net_cidr","value":"10.0.0.0/16"},{"name":"pub_key","value":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKXDgoo3+WOqcUG8/5uUbk81+yczgwC4Y8ywTmuQqbNxlY1oQ0YxdMUqUnhitSXs5S/yRuAVOYHwGg2mCs20oAINrP+mxBI544AMIb9itPjCtgqtE2EWo6MmnFGbHB4Sx3XioE7F4VPsh7japsIwzOjbrQe+Mua1TGQ5d4nfEOQaaglXLLPFfuc7WbhbJbK6Q7rHqZfRcOwAMXgDoBqlyqKeiKwnumddo2RyNT8ljYmvB6buz7KnMinzo7qB0uktVT05FH9Rg0CTWH5norlG5qXgP2aukL0gk1ph8iAt7uYLf1ktp+LJI2gaF6L0/qli9EmVCSLr1uJ38Q8CBflhkh"}]},"tenant":"7fad299815104c0a8f90a8df80343f03","aic-clli":"clli1","aic-cloud-region":"RegionOne","vf-module-topology-identifier":{"vf-module-id":"815e8636-5c2a-41ad-b24d-17c824106bd2","vf-module-name":"zRegionOne06_base_vcpe_vgw_0","vf-module-type":"VcpevspVgw0822a..base_vcpe_vgw..module-0"},"vf-module-assignments":{"vms":{"vm":[{"vm-type":"vgw","vm-count":1,"vm-type-tag":"vgw","vm-names":{"vm-name":["zRegionOne06001"]}}]}}},"vf-module-request-input":{"vf-module-name":"zRegionOne06_base_vcpe_vgw_0","tenant":"7fad299815104c0a8f90a8df80343f03","aic-cloud-region":"RegionOne"},"vf-module-information":{"onap-model-information":{"model-invariant-uuid":"7e91451d-e320-4755-a1a8-fcf140b86779","model-name":"VcpevspVgw0822a..base_vcpe_vgw..module-0","model-version":"1","model-customization-uuid":"7fbb59b7-a7ac-4fa6-b0bc-42f47339010a","model-uuid":"1908874e-cfae-4ee1-93b9-f4ba46b460ff"},"vf-module-id":"815e8636-5c2a-41ad-b24d-17c824106bd2","vf-module-type":"VcpevspVgw0822a..base_vcpe_vgw..module-0"},"sdnc-request-header":{"svc-action":"assign","svc-request-id":"2a950a5c-21bf-4496-a592-b51f45719603-1535335110722","svc-notification-url":"http://c1.vm1.mso.simpledemo.openecomp.org:8080/adapters/rest/SDNCNotify"},"vnf-information":{"vnf-id":"bf2a200d-744f-4900-afc4-d5ef44638467","vnf-type":"vcpesvc_rescust_0822a/vcpevsp_vgw_0822a 0","onap-model-information":{"model-invariant-uuid":"71370375-e1b4-4ad2-9832-1b7877428c81","model-name":"vcpevsp_vgw_0822a","model-version":"1.0","model-customization-uuid":"d4484d8e-09c8-4e1e-89f7-b556bf7c57ba","model-uuid":"7dd31559-9fc6-4b0d-bbe3-7ba641bf8a9b"}},"request-information":{"request-id":"2a950a5c-21bf-4496-a592-b51f45719603","request-action":"CreateVfModuleInstance","source":"VID"},"vf-module-level-oper-status":{"order-status":"PendingCreate","last-rpc-action":"assign"}}}]},"vnf-level-oper-status":{"last-rpc-action":"activate","order-status":"Created","last-action":"CreateVnfInstance"},"service-information":{"service-id":"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb","onap-model-information":{"model-invariant-uuid":"3a4e6986-5c5e-434e-b0be-8d718107fa83","model-name":"vcpesvc_rescust_0822a","model-version":"1.0","model-uuid":"209efacc-54d4-4f12-9064-099d47c36a29"},"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","global-customer-id":"SDN-ETHERNET-INTERNET","subscription-service-type":"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb"},"sdnc-request-header":{"svc-action":"activate","svc-request-id":"2a950a5c-21bf-4496-a592-b51f45719603-1535335104196","svc-notification-url":"http://c1.vm1.mso.simpledemo.openecomp.org:8080/adapters/rest/SDNCNotify"},"vnf-information":{"vnf-id":"bf2a200d-744f-4900-afc4-d5ef44638467","vnf-type":"vcpesvc_rescust_0822a/vcpevsp_vgw_0822a 0","onap-model-information":{"model-invariant-uuid":"71370375-e1b4-4ad2-9832-1b7877428c81","model-name":"vcpevsp_vgw_0822a","model-version":"1.0","model-customization-uuid":"d4484d8e-09c8-4e1e-89f7-b556bf7c57ba","model-uuid":"7dd31559-9fc6-4b0d-bbe3-7ba641bf8a9b"}},"request-information":{"request-id":"2a950a5c-21bf-4496-a592-b51f45719603","request-action":"CreateVnfInstance","source":"VID"},"vnf-request-input":{"vnf-name":"zRegionOne06","tenant":"7fad299815104c0a8f90a8df80343f03","aic-cloud-region":"RegionOne"},"vnf-topology":{"onap-model-information":{"model-invariant-uuid":"71370375-e1b4-4ad2-9832-1b7877428c81","model-name":"vcpevsp_vgw_0822a","model-version":"1.0","model-customization-uuid":"d4484d8e-09c8-4e1e-89f7-b556bf7c57ba","model-uuid":"7dd31559-9fc6-4b0d-bbe3-7ba641bf8a9b"},"tenant":"7fad299815104c0a8f90a8df80343f03","aic-clli":"clli1","aic-cloud-region":"RegionOne","vnf-topology-identifier-structure":{"vnf-id":"bf2a200d-744f-4900-afc4-d5ef44638467","vnf-type":"vcpesvc_rescust_0822a/vcpevsp_vgw_0822a 0","vnf-name":"zRegionOne06"},"vnf-resource-assignments":{"availability-zones":{"availability-zone":["nova"],"max-count":1}}}}}]},"service-level-oper-status":{"last-rpc-action":"assign","order-status":"Created","last-action":"CreateServiceInstance"}}}]}
+{"service":[{"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","service-status":{"final-indicator":"Y","rpc-action":"assign","rpc-name":"vf-module-topology-operation","response-code":"200","response-timestamp":"2018-08-27T01:58:25.652Z","action":"CreateVfModuleInstance","response-message":"","request-status":"synccomplete"},"service-data":{"service-request-input":{"service-instance-name":"vfw_svc_vfwsvc_rescust_0822a_201808262153","service-input-parameters":{"param":[{"name":"BRG_WAN_MAC_Address","value":"fa:16:3e:79:24:0e"},{"name":"customerLongitude","value":"-97.040443"},{"name":"customerLatitude","value":"32.897480"},{"name":"Homing_Solution","value":"sniro"},{"name":"customerName","value":"some_company"}]}},"service-information":{"service-id":"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb","onap-model-information":{"model-invariant-uuid":"3a4e6986-5c5e-434e-b0be-8d718107fa83","model-name":"vfwsvc_rescust_0822a","model-version":"1.0","model-uuid":"209efacc-54d4-4f12-9064-099d47c36a29"},"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","global-customer-id":"SDN-ETHERNET-INTERNET","subscription-service-type":"vFW"},"service-topology":{"service-topology-identifier":{"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","service-instance-name":"vfw_svc_vfwsvc_rescust_0822a_201808262153","global-customer-id":"SDN-ETHERNET-INTERNET","service-type":"vFW"},"onap-model-information":{"model-invariant-uuid":"3a4e6986-5c5e-434e-b0be-8d718107fa83","model-name":"vfwsvc_rescust_0822a","model-version":"1.0","model-uuid":"209efacc-54d4-4f12-9064-099d47c36a29"}},"sdnc-request-header":{"svc-action":"assign","svc-request-id":"dd3dffc8-6a15-4f7f-9787-d835ee247283","svc-notification-url":"http://c1.vm1.mso.simpledemo.openecomp.org:8080/adapters/rest/SDNCNotify"},"request-information":{"request-id":"2a950a5c-21bf-4496-a592-b51f45719603","request-action":"CreateServiceInstance","source":"MSO"},"vnfs":{"vnf":[{"vnf-id":"bf2a200d-744f-4900-afc4-d5ef44638467","vnf-data":{"vf-modules":{"vf-module":[{"vf-module-id":"815e8636-5c2a-41ad-b24d-17c824106bd2","vf-module-data":{"service-information":{"service-id":"null","onap-model-information":{"model-invariant-uuid":"3a4e6986-5c5e-434e-b0be-8d718107fa83","model-name":"vfwsvc_rescust_0822a","model-version":"1.0","model-uuid":"209efacc-54d4-4f12-9064-099d47c36a29"},"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","global-customer-id":"SDN-ETHERNET-INTERNET","subscription-service-type":"null"},"vf-module-topology":{"onap-model-information":{"model-invariant-uuid":"7e91451d-e320-4755-a1a8-fcf140b86779","model-name":"VfwvspVgw0822a..base_vfw_vgw..module-0","model-version":"1","model-customization-uuid":"7fbb59b7-a7ac-4fa6-b0bc-42f47339010a","model-uuid":"1908874e-cfae-4ee1-93b9-f4ba46b460ff"},"vf-module-parameters":{"param":[{"name":"mux_ip_addr","value":"10.5.0.21"},{"name":"mux_gw_private_net_id","value":"vfw_net_mux_gw_201808231522"},{"name":"vg_vgmux_tunnel_vni","value":"107"},{"name":"repo_url_artifacts","value":"https://nexus.onap.org/content/groups/staging"},{"name":"cpe_public_net_id","value":"vfw_net_cpe_public_201808231522"},{"name":"key_name","value":"vgw_key"},{"name":"onap_private_subnet_id","value":"oam_onap_1MdY"},{"name":"cpe_public_net_cidr","value":"10.2.0.0/24"},{"name":"mux_gw_private_net_cidr","value":"10.5.0.0/24"},{"name":"cloud_env","value":"openstack"},{"name":"cpe_public_subnet_id","value":"vfw_net_cpe_public_subnet_201808231522"},{"name":"mux_gw_private_subnet_id","value":"vfw_net_mux_gw_subnet_201808231522"},{"name":"onap_private_net_id","value":"oam_onap_1MdY"},{"name":"repo_url_blob","value":"https://nexus.onap.org/content/sites/raw"},{"name":"install_script_version","value":"1.1.1"},{"name":"demo_artifacts_version","value":"1.1.1"},{"name":"vgw_name_0","value":"zdcpe1cpe01gw01_201808261550"},{"name":"vgw_private_ip_1","value":"10.0.101.99"},{"name":"vgw_private_ip_0","value":"10.5.0.107"},{"name":"public_net_id","value":"971040b2-7059-49dc-b220-4fab50cb2ad4"},{"name":"vgw_private_ip_2","value":"10.2.0.6"},{"name":"onap_private_net_cidr","value":"10.0.0.0/16"},{"name":"pub_key","value":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKXDgoo3+WOqcUG8/5uUbk81+yczgwC4Y8ywTmuQqbNxlY1oQ0YxdMUqUnhitSXs5S/yRuAVOYHwGg2mCs20oAINrP+mxBI544AMIb9itPjCtgqtE2EWo6MmnFGbHB4Sx3XioE7F4VPsh7japsIwzOjbrQe+Mua1TGQ5d4nfEOQaaglXLLPFfuc7WbhbJbK6Q7rHqZfRcOwAMXgDoBqlyqKeiKwnumddo2RyNT8ljYmvB6buz7KnMinzo7qB0uktVT05FH9Rg0CTWH5norlG5qXgP2aukL0gk1ph8iAt7uYLf1ktp+LJI2gaF6L0/qli9EmVCSLr1uJ38Q8CBflhkh"}]},"tenant":"7fad299815104c0a8f90a8df80343f03","aic-clli":"clli1","aic-cloud-region":"RegionOne","vf-module-topology-identifier":{"vf-module-id":"815e8636-5c2a-41ad-b24d-17c824106bd2","vf-module-name":"zRegionOne06_base_vfw_vgw_0","vf-module-type":"VfwvspVgw0822a..base_vfw_vgw..module-0"},"vf-module-assignments":{"vms":{"vm":[{"vm-type":"vgw","vm-count":1,"vm-type-tag":"vgw","vm-names":{"vm-name":["zRegionOne06001"]}}]}}},"vf-module-request-input":{"vf-module-name":"zRegionOne06_base_vfw_vgw_0","tenant":"7fad299815104c0a8f90a8df80343f03","aic-cloud-region":"RegionOne"},"vf-module-information":{"onap-model-information":{"model-invariant-uuid":"7e91451d-e320-4755-a1a8-fcf140b86779","model-name":"VfwvspVgw0822a..base_vfw_vgw..module-0","model-version":"1","model-customization-uuid":"7fbb59b7-a7ac-4fa6-b0bc-42f47339010a","model-uuid":"1908874e-cfae-4ee1-93b9-f4ba46b460ff"},"vf-module-id":"815e8636-5c2a-41ad-b24d-17c824106bd2","vf-module-type":"VfwvspVgw0822a..base_vfw_vgw..module-0"},"sdnc-request-header":{"svc-action":"assign","svc-request-id":"2a950a5c-21bf-4496-a592-b51f45719603-1535335110722","svc-notification-url":"http://c1.vm1.mso.simpledemo.openecomp.org:8080/adapters/rest/SDNCNotify"},"vnf-information":{"vnf-id":"bf2a200d-744f-4900-afc4-d5ef44638467","vnf-type":"vfwsvc_rescust_0822a/vfwvsp_vgw_0822a 0","onap-model-information":{"model-invariant-uuid":"71370375-e1b4-4ad2-9832-1b7877428c81","model-name":"vfwvsp_vgw_0822a","model-version":"1.0","model-customization-uuid":"d4484d8e-09c8-4e1e-89f7-b556bf7c57ba","model-uuid":"7dd31559-9fc6-4b0d-bbe3-7ba641bf8a9b"}},"request-information":{"request-id":"2a950a5c-21bf-4496-a592-b51f45719603","request-action":"CreateVfModuleInstance","source":"VID"},"vf-module-level-oper-status":{"order-status":"PendingCreate","last-rpc-action":"assign"}}}]},"vnf-level-oper-status":{"last-rpc-action":"activate","order-status":"Created","last-action":"CreateVnfInstance"},"service-information":{"service-id":"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb","onap-model-information":{"model-invariant-uuid":"3a4e6986-5c5e-434e-b0be-8d718107fa83","model-name":"vfwsvc_rescust_0822a","model-version":"1.0","model-uuid":"209efacc-54d4-4f12-9064-099d47c36a29"},"service-instance-id":"7d518257-49bd-40ac-8d17-017a726ec12a","global-customer-id":"SDN-ETHERNET-INTERNET","subscription-service-type":"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb"},"sdnc-request-header":{"svc-action":"activate","svc-request-id":"2a950a5c-21bf-4496-a592-b51f45719603-1535335104196","svc-notification-url":"http://c1.vm1.mso.simpledemo.openecomp.org:8080/adapters/rest/SDNCNotify"},"vnf-information":{"vnf-id":"bf2a200d-744f-4900-afc4-d5ef44638467","vnf-type":"vfwsvc_rescust_0822a/vfwvsp_vgw_0822a 0","onap-model-information":{"model-invariant-uuid":"71370375-e1b4-4ad2-9832-1b7877428c81","model-name":"vfwvsp_vgw_0822a","model-version":"1.0","model-customization-uuid":"d4484d8e-09c8-4e1e-89f7-b556bf7c57ba","model-uuid":"7dd31559-9fc6-4b0d-bbe3-7ba641bf8a9b"}},"request-information":{"request-id":"2a950a5c-21bf-4496-a592-b51f45719603","request-action":"CreateVnfInstance","source":"VID"},"vnf-request-input":{"vnf-name":"zRegionOne06","tenant":"7fad299815104c0a8f90a8df80343f03","aic-cloud-region":"RegionOne"},"vnf-topology":{"onap-model-information":{"model-invariant-uuid":"71370375-e1b4-4ad2-9832-1b7877428c81","model-name":"vfwvsp_vgw_0822a","model-version":"1.0","model-customization-uuid":"d4484d8e-09c8-4e1e-89f7-b556bf7c57ba","model-uuid":"7dd31559-9fc6-4b0d-bbe3-7ba641bf8a9b"},"tenant":"7fad299815104c0a8f90a8df80343f03","aic-clli":"clli1","aic-cloud-region":"RegionOne","vnf-topology-identifier-structure":{"vnf-id":"bf2a200d-744f-4900-afc4-d5ef44638467","vnf-type":"vfwsvc_rescust_0822a/vfwvsp_vgw_0822a 0","vnf-name":"zRegionOne06"},"vnf-resource-assignments":{"availability-zones":{"availability-zone":["nova"],"max-count":1}}}}}]},"service-level-oper-status":{"last-rpc-action":"assign","order-status":"Created","last-action":"CreateServiceInstance"}}}]}