Initial OpenECOMP A&AI Model Loader commit 85/185/1
authorSteve Smokowski <ss835w@att.com>
Thu, 9 Feb 2017 20:43:35 +0000 (15:43 -0500)
committerSteve Smokowski <ss835w@att.com>
Thu, 9 Feb 2017 20:44:01 +0000 (15:44 -0500)
Change-Id: Iae343fa01ecc701919703fb7d61727555371321d
Signed-off-by: Steve Smokowski <ss835w@att.com>
53 files changed:
.gitignore [new file with mode: 0644]
.gitreview [new file with mode: 0644]
License.txt [new file with mode: 0644]
Readme.md [new file with mode: 0644]
pom.xml [new file with mode: 0644]
src/main/docker/.dockerignore [new file with mode: 0644]
src/main/docker/Dockerfile [new file with mode: 0644]
src/main/docker/startup.sh [new file with mode: 0644]
src/main/docker/update_config.sh [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/config/ModelLoaderConfig.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/entity/Artifact.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/entity/ArtifactHandler.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/entity/ArtifactType.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifact.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandler.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/entity/model/ModelArtifact.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactHandler.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactParser.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/notification/DistributionStatusMsg.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/notification/EventCallback.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/restclient/AaiRestClient.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/service/ModelLoaderInterface.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/service/ModelLoaderMsgs.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/service/ModelLoaderService.java [new file with mode: 0644]
src/main/java/org/openecomp/modelloader/util/JsonXmlConverter.java [new file with mode: 0644]
src/main/resources/aai-os-cert.p12 [new file with mode: 0644]
src/main/resources/logback.xml [new file with mode: 0644]
src/main/resources/model-loader.properties [new file with mode: 0644]
src/main/resources/org/openecomp/modelloader/filemonitor/FileMonitorMsgs.properties [new file with mode: 0644]
src/main/resources/org/openecomp/modelloader/service/ModelLoaderMsgs.properties [new file with mode: 0644]
src/main/resources/schema/aai_schema_v8.xsd [new file with mode: 0644]
src/main/resources/schema/vnfcatalog.xsd [new file with mode: 0644]
src/main/webapp/WEB-INF/applicationContext.xml [new file with mode: 0644]
src/main/webapp/WEB-INF/rest-servlet.xml [new file with mode: 0644]
src/main/webapp/WEB-INF/web.xml [new file with mode: 0644]
src/test/java/org/openecomp/modelloader/config/ModelLoaderConfigTest.java [new file with mode: 0644]
src/test/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandlerTest.java [new file with mode: 0644]
src/test/java/org/openecomp/modelloader/entity/model/ModelArtifactParserTest.java [new file with mode: 0644]
src/test/java/org/openecomp/modelloader/entity/model/ModelSorterTest.java [new file with mode: 0644]
src/test/java/org/openecomp/modelloader/restclient/AAIRestClientTest.java [new file with mode: 0644]
src/test/java/org/openecomp/modelloader/service/ModelLoaderServiceTest.java [new file with mode: 0644]
src/test/java/org/openecomp/modelloader/util/JsonXmlConverterTest.java [new file with mode: 0644]
src/test/resources/logback-test.xml [new file with mode: 0644]
src/test/resources/model-loader-empty-auth-password.properties [new file with mode: 0644]
src/test/resources/model-loader-no-auth-password.properties [new file with mode: 0644]
src/test/resources/model-loader.properties [new file with mode: 0644]
src/test/resources/models/complete-model.xml [new file with mode: 0644]
src/test/resources/models/named-query-wan-connector.xml [new file with mode: 0644]
src/test/resources/models/vnf-model.json [new file with mode: 0644]
src/test/resources/models/vnf-model.xml [new file with mode: 0644]
src/test/resources/models/wan-connector-model.xml [new file with mode: 0644]
src/test/resources/vnfcatalogexample.xml [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..f402f8c
--- /dev/null
@@ -0,0 +1,6 @@
+.classpath
+.project
+.settings/
+target/
+logs/
+debug-logs/
\ No newline at end of file
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..01d111b
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.openecomp.org
+port=29418
+project=aai/model-loader
diff --git a/License.txt b/License.txt
new file mode 100644 (file)
index 0000000..17cfdd5
--- /dev/null
@@ -0,0 +1,22 @@
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright © 2017 AT&T Intellectual Property.
+  Copyright © 2017 Amdocs
+  All rights reserved.
+  ================================================================================
+  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=========================================================
+  
+  ECOMP and OpenECOMP are trademarks
+  and service marks of AT&T Intellectual Property.
\ No newline at end of file
diff --git a/Readme.md b/Readme.md
new file mode 100644 (file)
index 0000000..758b3a7
--- /dev/null
+++ b/Readme.md
@@ -0,0 +1,47 @@
+# Introduction
+
+The A&AI Model Loader Service is an application that facilitates
+distribution, ingestion of new service and resource models, and vnf
+catalogs from the SDC to the A&AI.
+
+## Features
+
+The Model Loader:
+
+* registers with the SDC to receive notification events 
+* polls the UEB/DMaap cluster for notification events
+* downloads artifacts from SDC upon receipt of a distribution event
+* pushes distribution components to A&AI
+                   
+## Compiling Model Loader
+
+Model Loader can be compiled by running `mvn clean install`
+
+## Running Model Loader 
+
+### Create a config file with the following key/values:
+
+```
+DISTR_CLIENT_ASDC_ADDRESS=<SDC_ADDRESS>
+DISTR_CLIENT_CONSUMER_GROUP=<UEB_CONSUMER_GROUP>  ;;  Uniquely identiy this group of model loaders.
+DISTR_CLIENT_CONSUMER_ID=<UEB_CONSUMER_GROUP_ID>  ;;  Uniquely identiythis model loader.
+DISTR_CLIENT_ENVIRONMENT_NAME=<ENVIRONMENT_NAME>  ;;  Environment name configured on the SDC
+DISTR_CLIENT_PASSWORD=<DISTR_PASSWORD>            ;;  Password to connect to SDC
+DISTR_CLIENT_USER=<USER_ID>                       ;;  User name to connect to SDC
+                    
+APP_SERVER_BASE_URL=https://<aai-address>:8443    ;; AAI Address (URL)
+APP_SERVER_AUTH_USER=<USER_ID>                    ;; User name to connect to AAI
+APP_SERVER_AUTH_PASSWORD=<PASSWORD>               ;; Password to connect to AAi
+
+```
+
+### Docker 
+
+#### Build your own Model Loader docker image and create docker containers
+1. mvn clean package docker:build                 ;; Build a docker image of Model Loader
+2. sudo docker images                             ;; list docker images and check if the image you build is listed.
+3. sudo docker run --env-file <config-filename> <model-loader-image> /opt/jetty/jetty*/bin/startup.sh
+
+
+#### Retrieve logs from stopped container
+* docker cp <container-id>:/opt/jetty/jetty-distribution-9.3.9.v20160517/logs/AAI-ML/error.log /tmp/
diff --git a/pom.xml b/pom.xml
new file mode 100644 (file)
index 0000000..2228b40
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,372 @@
+<!--
+     ============LICENSE_START=======================================================
+     MODEL LOADER SERVICE
+     ================================================================================
+     Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+     ================================================================================
+     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=========================================================
+   -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>org.openecomp.aai.model-loader</groupId>
+       <artifactId>model-loader</artifactId>
+       <version>1.0.0-SNAPSHOT</version>
+       <packaging>war</packaging>
+       
+       <properties>
+               <docker.location>${basedir}/target</docker.location>
+               <docker.url>${dockerurl}</docker.url>
+               <docker.imagetag>${dockertag}</docker.imagetag>
+               <docker.login>${dockerlogin}</docker.login>
+               <docker.password>${dockerpassword}</docker.password>
+               <docker.registry>${dockerregistry}</docker.registry>
+               <dependency.scope>provided</dependency.scope>
+               <checkstyle.config.location>google_checks.xml</checkstyle.config.location>
+               <maven.compiler.source>1.8</maven.compiler.source>
+       <maven.compiler.target>1.8</maven.compiler.target>
+       </properties>
+       
+       <repositories>
+               <repository>
+                       <id>maven-central</id>
+                       <name>maven-central</name>
+                       <url>http://central.maven.org/maven2/</url>
+                       <releases>
+                               <enabled>true</enabled>
+                               <updatePolicy>never</updatePolicy>
+                       </releases>
+                       <snapshots>
+                               <enabled>false</enabled>
+                       </snapshots>
+               </repository>
+               <repository>
+                       <id>ecomp-nexus</id>
+                       <name>ecomp-nexus</name>
+                       <url>https://ecomp-nexus:8443/repository/maven-releases/</url>
+                       <releases>
+                               <enabled>true</enabled>
+                               <updatePolicy>never</updatePolicy>
+                       </releases>
+                       <snapshots>
+                               <enabled>false</enabled>
+                       </snapshots>
+               </repository>
+       </repositories>
+
+       
+       <dependencies>
+               <!-- powermockito dependencies -->
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-all</artifactId>
+                       <version>1.10.19</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-junit4</artifactId>
+                       <version>1.6.2</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-api-mockito</artifactId>
+                       <version>1.6.2</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-javaagent</artifactId>
+                       <version>1.6.2</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-junit4-rule-agent</artifactId>
+                       <version>1.6.2</version>
+                       <scope>test</scope>
+               </dependency>
+               <!-- xjc dependencies -->
+               <dependency>
+                       <groupId>javax.xml.bind</groupId>
+                       <artifactId>jaxb-api</artifactId>
+                       <version>2.2.11</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.xml.bind</groupId>
+                       <artifactId>jaxb-impl</artifactId>
+                       <version>2.2.11</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.xml.bind</groupId>
+                       <artifactId>jaxb-core</artifactId>
+                       <version>2.2.11</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.xml.bind</groupId>
+                       <artifactId>jaxb-xjc</artifactId>
+                       <version>2.2.11</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>org.eclipse.persistence.moxy</artifactId>
+                       <version>2.6.2</version>
+                       <scope>compile</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.jersey</groupId>
+                       <artifactId>jersey-client</artifactId>
+                       <version>1.18</version>
+               </dependency>
+               <!-- Common logging framework -->
+               <dependency>
+                       <groupId>org.openecomp.cl</groupId>
+                       <artifactId>common-logging</artifactId>
+                       <version>1.0.0-SNAPSHOT</version>
+               </dependency>
+               <!-- ASDC Client Library -->
+               <dependency>
+                       <groupId>org.openecomp.sdc</groupId>
+                       <artifactId>sdc-distribution-client</artifactId>
+                       <version>1.1.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.json</groupId>
+                       <artifactId>json</artifactId>
+                       <version>20131018</version>
+               </dependency>
+               
+               <dependency>
+                   <groupId>org.eclipse.jetty</groupId>
+                   <artifactId>jetty-security</artifactId>
+                   <version>9.3.8.RC0</version>
+               </dependency>
+               
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>4.0.0.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>jline</groupId>
+            <artifactId>jline</artifactId>
+            <version>2.12.1</version>
+        </dependency>
+        
+       </dependencies>
+       
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-dependency-plugin</artifactId>
+                               <version>2.5.1</version>
+                               <executions>
+                                       <execution>
+                                               <id>copy-agent</id>
+                                               <phase>process-test-classes</phase>
+                                               <goals>
+                                                       <goal>copy</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <artifactItems>
+                                                               <artifactItem>
+                                                                       <groupId>org.powermock</groupId>
+                                                                       <artifactId>powermock-module-javaagent</artifactId>
+                                                                       <version>1.6.2</version>
+                                                                       <outputDirectory>${project.build.directory}/agents</outputDirectory>
+                                                                       <destFileName>powermock-javaagent.jar</destFileName>
+                                                               </artifactItem>
+                                                       </artifactItems>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-surefire-plugin</artifactId>
+                               <version>2.12.4</version>
+                               <configuration>
+                                       <argLine>-javaagent:${project.build.directory}/agents/powermock-javaagent.jar
+                                               -noverify</argLine>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.codehaus.mojo</groupId>
+                               <artifactId>jaxb2-maven-plugin</artifactId>
+                               <version>2.2</version>
+                               <executions>
+                                       <execution>
+                                               <id>xjc</id>
+                                               <goals>
+                                                       <goal>xjc</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                               <configuration>
+                                       <clearOutputDir>false</clearOutputDir>
+                                       <outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
+                                       <sources>
+                                               <source>${project.basedir}/src/main/resources/schema</source>
+                                       </sources>
+                                       <addGeneratedAnnotation>true</addGeneratedAnnotation>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <version>3.1</version>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>2.7</version>
+                               <executions>
+                                       <execution>
+                                               <id>copy-docker-file</id>
+                                               <phase>package</phase>
+                                               <goals>
+                                                       <goal>copy-resources</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <outputDirectory>target</outputDirectory>
+                                                       <overwrite>true</overwrite>
+                                                       <resources>
+                                                               <resource>
+                                                                       <directory>${basedir}/src/main/docker</directory>
+                                                                       <filtering>true</filtering>
+                                                                       <includes>
+                                                                               <include>**/*</include>
+                                                                       </includes>
+                                                               </resource>
+                                                       </resources>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>com.spotify</groupId>
+                               <artifactId>docker-maven-plugin</artifactId>
+                               <version>0.4.11</version>
+                               <configuration>
+                                       <dockerHost>${docker.url}</dockerHost>
+                                       <registry>${docker.registry}</registry>
+                                       <authConfig>
+                        <username>${docker.login}</username>
+                        <password>${docker.password}</password>
+                    </authConfig>
+                                       <imageName>${docker.registry}/ecomp/${project.artifactId}</imageName>
+                                       <dockerDirectory>${docker.location}</dockerDirectory>
+                                       <registryUrl>https://${docker.registry}</registryUrl>
+                                       <imageTags>
+                                               <imageTag>${docker.imagetag}</imageTag>
+                                               <imageTag>latest</imageTag>
+                                       </imageTags>
+                                       <forceTags>true</forceTags>
+                               </configuration>
+                       </plugin>
+                       <!-- blackduck maven plugin -->
+                       <plugin>
+                               <groupId>com.blackducksoftware.integration</groupId>
+                               <artifactId>hub-maven-plugin</artifactId>
+                               <version>1.0.4</version>
+                               <inherited>false</inherited>
+                               <configuration>
+                                       <target>${project.basedir/target}</target>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <id>create-bdio-file</id>
+                                               <phase>package</phase>
+                                               <goals>
+                                                       <goal>createHubOutput</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <!-- Checkstyle plugin - used to report on compliance with -->
+                       <!-- the Google style guide. -->
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-site-plugin</artifactId>
+                               <version>3.3</version>
+                               <configuration>
+                                       <reportPlugins>
+                                               <plugin>
+                                                       <groupId>org.apache.maven.plugins</groupId>
+                                                       <artifactId>maven-checkstyle-plugin</artifactId>
+                                                       <version>2.17</version>
+                                                       <reportSets>
+                                                               <reportSet>
+                                                                       <reports>
+                                                                               <report>checkstyle</report>
+                                                                       </reports>
+                                                               </reportSet>
+                                                       </reportSets>
+                                               </plugin>
+                                       </reportPlugins>
+                               </configuration>
+                       </plugin>
+                        
+            <!-- license plugin -->
+            <plugin>
+              <groupId>org.codehaus.mojo</groupId>
+              <artifactId>license-maven-plugin</artifactId>
+              <version>1.10</version>
+              <configuration>
+                <addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage>
+                <excludes>
+                  <exclude>**.json</exclude>
+                  <exclude>**.properties</exclude>
+                </excludes>
+                <processStartTag>============LICENSE_START=======================================================</processStartTag>
+                <processEndTag>============LICENSE_END=========================================================</processEndTag>
+                <sectionDelimiter>================================================================================</sectionDelimiter>
+                <licenseName>apache_v2</licenseName>
+                <inceptionYear>2017</inceptionYear>
+                <organizationName>AT&amp;T Intellectual Property. All rights reserved.</organizationName>
+                <projectName>MODEL LOADER SERVICE</projectName>
+                <canUpdateCopyright>true</canUpdateCopyright>
+                <canUpdateDescription>true</canUpdateDescription>
+                <canUpdateLicense>true</canUpdateLicense>
+                <emptyLineAfterHeader>true</emptyLineAfterHeader>
+                <roots>
+                  <root>.</root>
+                </roots>
+                <excludes>
+                  <exclude>**/*.json</exclude>
+                </excludes>
+                <extraExtensions>
+                  <route>xml</route>
+                  <props>properties</props>
+                  <xsd>xml</xsd>
+                  <txt>java</txt>
+                </extraExtensions>
+              </configuration>
+              <executions>
+                <execution>
+                  <id>first</id>
+                  <goals>
+                    <goal>update-file-header</goal>
+                  </goals>
+                  <phase>process-sources</phase>
+                </execution>
+              </executions>
+            </plugin>
+               </plugins>
+       </build>
+       
+</project>
diff --git a/src/main/docker/.dockerignore b/src/main/docker/.dockerignore
new file mode 100644 (file)
index 0000000..1128374
--- /dev/null
@@ -0,0 +1,2 @@
+*.war
+*.jsonld
\ No newline at end of file
diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile
new file mode 100644 (file)
index 0000000..4c2fe1a
--- /dev/null
@@ -0,0 +1,52 @@
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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=========================================================
+###
+
+FROM ubuntu:14.04
+ARG jettyrel=9.3.9.v20160517
+ARG jettydist=jetty-distribution-${jettyrel}
+ARG jettybase=/opt/jetty
+
+RUN apt-get update && apt-get --force-yes -y -f install wget
+
+# Install java8
+RUN apt-get install -y software-properties-common
+
+# sudo -E is required to preserve the environment
+# If you remove that line, it will most like freeze at this step
+
+RUN sudo -E add-apt-repository ppa:openjdk-r/ppa && apt-get update && apt-get install -y openjdk-8-jdk
+
+# Setup JAVA_HOME, this is useful for docker commandline
+
+ENV JAVA_HOME usr/lib/jvm/java-8-openjdk-amd64
+RUN export JAVA_HOME
+
+RUN wget http://central.maven.org/maven2/org/eclipse/jetty/jetty-distribution/${jettyrel}/${jettydist}.tar.gz
+RUN gunzip ${jettydist}.tar.gz && tar xvf ${jettydist}.tar
+
+COPY model-loader* $jettydist/webapps/model-loader/
+
+COPY startup.sh update_config.sh ${jettydist}/bin/
+RUN chmod 700 ${jettydist}/bin/startup.sh && chmod 700 ${jettydist}/bin/update_config.sh
+RUN mkdir -p ${jettybase}
+RUN mv ${jettydist} ${jettybase}/${jettydist}
+RUN rm -rf $jettybase/$jettydist/demo-base
+
+CMD /opt/jetty/*/bin/startup.sh
diff --git a/src/main/docker/startup.sh b/src/main/docker/startup.sh
new file mode 100644 (file)
index 0000000..22950cd
--- /dev/null
@@ -0,0 +1,27 @@
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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=========================================================
+###
+
+BIN_DIR=`dirname $0`
+
+echo "Checking environment for configuration options"
+$BIN_DIR/update_config.sh
+
+echo "Starting up model loader..."
+$BIN_DIR/jetty.sh run > /dev/null 2>&1
\ No newline at end of file
diff --git a/src/main/docker/update_config.sh b/src/main/docker/update_config.sh
new file mode 100644 (file)
index 0000000..77916ed
--- /dev/null
@@ -0,0 +1,151 @@
+#!/bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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=========================================================
+###
+
+#
+# This script will update the config file, with config values supplied
+# through environment variables, if set
+# 
+
+CONFIG_FILE=`dirname $0`/../webapps/model-loader/WEB-INF/classes/model-loader.properties
+
+# Distribution client configuration
+ENVVAR=DISTR_CLIENT_ACTIVE_SERVER_TLS_AUTH
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.ACTIVE_SERVER_TLS_AUTH/s/.*/ml.distribution.ACTIVE_SERVER_TLS_AUTH=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_ASDC_ADDRESS 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.ASDC_ADDRESS/s/.*/ml.distribution.ASDC_ADDRESS=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_CONSUMER_GROUP
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.CONSUMER_GROUP/s/.*/ml.distribution.CONSUMER_GROUP=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_CONSUMER_ID
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.CONSUMER_ID/s/.*/ml.distribution.CONSUMER_ID=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_ENVIRONMENT_NAME
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.ENVIRONMENT_NAME/s/.*/ml.distribution.ENVIRONMENT_NAME=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_KEYSTORE_PASSWORD
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.KEYSTORE_PASSWORD/s/.*/ml.distribution.KEYSTORE_PASSWORD=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_KEYSTORE_FILE 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.KEYSTORE_FILE/s/.*/ml.distribution.KEYSTORE_FILE=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_PASSWORD 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.PASSWORD/s/.*/ml.distribution.PASSWORD=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_POLLING_INTERVAL 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.POLLING_INTERVAL/s/.*/ml.distribution.POLLING_INTERVAL=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_POLLING_TIMEOUT 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.POLLING_TIMEOUT/s/.*/ml.distribution.POLLING_TIMEOUT=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_USER 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.USER/s/.*/ml.distribution.USER=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=DISTR_CLIENT_ARTIFACT_TYPES 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.distribution.ARTIFACT_TYPES/s/.*/ml.distribution.ARTIFACT_TYPES=$ENVVALUE/" $CONFIG_FILE;
+
+  
+# Model Loader Application Server REST Client Configuration
+ENVVAR=APP_SERVER_BASE_URL
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.aai.BASE_URL/s/.*/ml.aai.BASE_URL=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=APP_SERVER_MODEL_URL 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.aai.MODEL_URL/s/.*/ml.aai.MODEL_URL=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=APP_SERVER_NAMED_QUERY_URL 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.aai.NAMED_QUERY_URL/s/.*/ml.aai.NAMED_QUERY_URL=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=APP_SERVER_VNF_IMAGE_URL 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.aai.VNF_IMAGE_URL/s/.*/ml.aai.VNF_IMAGE_URL=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=APP_SERVER_KEYSTORE_FILE 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.aai.KEYSTORE_FILE/s/.*/ml.aai.KEYSTORE_FILE=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=APP_SERVER_KEYSTORE_PASSWORD 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.aai.KEYSTORE_PASSWORD/s/.*/ml.aai.KEYSTORE_PASSWORD=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=APP_SERVER_AUTH_USER 
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.aai.AUTH_USER/s/.*/ml.aai.AUTH_USER=$ENVVALUE/" $CONFIG_FILE;
+
+ENVVAR=APP_SERVER_AUTH_PASSWORD
+ENVVALUE=${!ENVVAR}
+ENVVALUE=${ENVVALUE//\//\\/}
+[ -z ${!ENVVAR+x} ] \
+ || sed -i "/ml.aai.AUTH_PASSWORD/s/.*/ml.aai.AUTH_PASSWORD=$ENVVALUE/" $CONFIG_FILE;
diff --git a/src/main/java/org/openecomp/modelloader/config/ModelLoaderConfig.java b/src/main/java/org/openecomp/modelloader/config/ModelLoaderConfig.java
new file mode 100644 (file)
index 0000000..26f13ad
--- /dev/null
@@ -0,0 +1,235 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.config;
+
+import org.eclipse.jetty.util.security.Password;
+import org.openecomp.sdc.api.consumer.IConfiguration;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+public class ModelLoaderConfig implements IConfiguration {
+
+  // Configuration file structure
+  public static final String PREFIX_MODEL_LOADER_CONFIG = "ml";
+  public static final String PREFIX_DISTRIBUTION_CLIENT = 
+      PREFIX_MODEL_LOADER_CONFIG + ".distribution.";
+  public static final String PREFIX_AAI = PREFIX_MODEL_LOADER_CONFIG + ".aai.";
+  public static final String PREFIX_DEBUG = PREFIX_MODEL_LOADER_CONFIG + ".debug.";
+
+  // Configuration file properties
+  protected static final String PROP_ML_DISTRIBUTION_ACTIVE_SERVER_TLS_AUTH = 
+      PREFIX_DISTRIBUTION_CLIENT + "ACTIVE_SERVER_TLS_AUTH";
+  protected static final String PROP_ML_DISTRIBUTION_ASDC_ADDRESS = PREFIX_DISTRIBUTION_CLIENT
+      + "ASDC_ADDRESS";
+  protected static final String PROP_ML_DISTRIBUTION_CONSUMER_GROUP = PREFIX_DISTRIBUTION_CLIENT
+      + "CONSUMER_GROUP";
+  protected static final String PROP_ML_DISTRIBUTION_CONSUMER_ID = PREFIX_DISTRIBUTION_CLIENT
+      + "CONSUMER_ID";
+  protected static final String PROP_ML_DISTRIBUTION_ENVIRONMENT_NAME = PREFIX_DISTRIBUTION_CLIENT
+      + "ENVIRONMENT_NAME";
+  protected static final String PROP_ML_DISTRIBUTION_KEYSTORE_PASSWORD = PREFIX_DISTRIBUTION_CLIENT
+      + "KEYSTORE_PASSWORD";
+  protected static final String PROP_ML_DISTRIBUTION_KEYSTORE_FILE = PREFIX_DISTRIBUTION_CLIENT
+      + "KEYSTORE_FILE";
+  protected static final String PROP_ML_DISTRIBUTION_PASSWORD = PREFIX_DISTRIBUTION_CLIENT
+      + "PASSWORD";
+  protected static final String PROP_ML_DISTRIBUTION_POLLING_INTERVAL = PREFIX_DISTRIBUTION_CLIENT
+      + "POLLING_INTERVAL";
+  protected static final String PROP_ML_DISTRIBUTION_POLLING_TIMEOUT = PREFIX_DISTRIBUTION_CLIENT
+      + "POLLING_TIMEOUT";
+  protected static final String PROP_ML_DISTRIBUTION_USER = PREFIX_DISTRIBUTION_CLIENT + "USER";
+  protected static final String PROP_ML_DISTRIBUTION_ARTIFACT_TYPES = PREFIX_DISTRIBUTION_CLIENT
+      + "ARTIFACT_TYPES";
+
+  protected static final String PROP_AAI_BASE_URL = PREFIX_AAI + "BASE_URL";
+  protected static final String PROP_AAI_KEYSTORE_FILE = PREFIX_AAI + "KEYSTORE_FILE";
+  protected static final String PROP_AAI_KEYSTORE_PASSWORD = PREFIX_AAI + "KEYSTORE_PASSWORD";
+  protected static final String PROP_AAI_MODEL_RESOURCE_URL = PREFIX_AAI + "MODEL_URL";
+  protected static final String PROP_AAI_NAMED_QUERY_RESOURCE_URL = PREFIX_AAI + "NAMED_QUERY_URL";
+  protected static final String PROP_AAI_VNF_IMAGE_RESOURCE_URL = PREFIX_AAI + "VNF_IMAGE_URL";
+  protected static final String PROP_AAI_AUTHENTICATION_USER = PREFIX_AAI + "AUTH_USER";
+  protected static final String PROP_AAI_AUTHENTICATION_PASSWORD = PREFIX_AAI + "AUTH_PASSWORD";
+
+  protected static final String PROP_DEBUG_INGEST_SIMULATOR = PREFIX_DEBUG + "INGEST_SIMULATOR";
+
+  private Properties modelLoaderProperties = null;
+
+  private String certLocation = ".";
+
+  private List<String> artifactTypes = null;
+
+  /**
+   * This is the class constructor.
+   * 
+   * @param modelLoaderProperties properties needed to be configured for the model loader
+   * @param certLocation location of the certificate
+   */
+  public ModelLoaderConfig(Properties modelLoaderProperties) {
+    this.modelLoaderProperties = modelLoaderProperties;
+    
+    String aaiKeystoreFile = modelLoaderProperties.getProperty(PROP_AAI_KEYSTORE_FILE);
+    if(aaiKeystoreFile != null){
+           URL keystoreURL = this.getClass().getClassLoader().getResource(aaiKeystoreFile);
+           if(keystoreURL != null){
+               File fKeystoreLocation = new File(keystoreURL.getPath());
+               this.certLocation = fKeystoreLocation.getParent();
+           }
+    }
+
+    // Get list of artifacts
+    artifactTypes = new ArrayList<String>();
+    if (modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_ARTIFACT_TYPES) != null) {
+      String[] artTypeList = modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_ARTIFACT_TYPES)
+          .split(",");
+      for (String artType : artTypeList) {
+        artifactTypes.add(artType);
+      }
+    }
+  }
+
+  @Override
+  public boolean activateServerTLSAuth() {
+    String value = modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_ACTIVE_SERVER_TLS_AUTH);
+    return value == null ? false : Boolean.parseBoolean(value);
+  }
+
+  @Override
+  public String getAsdcAddress() {
+    return modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_ASDC_ADDRESS);
+  }
+
+  @Override
+  public String getConsumerGroup() {
+    return modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_CONSUMER_GROUP);
+  }
+
+  @Override
+  public String getConsumerID() {
+    return modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_CONSUMER_ID);
+  }
+
+  @Override
+  public String getEnvironmentName() {
+    return modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_ENVIRONMENT_NAME);
+  }
+
+  @Override
+  public String getKeyStorePassword() {
+    return Password
+        .deobfuscate(modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_KEYSTORE_PASSWORD));
+  }
+
+  @Override
+  public String getKeyStorePath() {
+    return certLocation + modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_KEYSTORE_FILE);
+  }
+
+  @Override
+  public String getPassword() {
+    return Password.deobfuscate(modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_PASSWORD));
+  }
+
+  @Override
+  public int getPollingInterval() {
+    return Integer
+        .parseInt(modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_POLLING_INTERVAL));
+  }
+
+  @Override
+  public int getPollingTimeout() {
+    return Integer
+        .parseInt(modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_POLLING_TIMEOUT));
+  }
+
+  @Override
+  public List<String> getRelevantArtifactTypes() {
+    return artifactTypes;
+  }
+
+  @Override
+  public String getUser() {
+    return modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_USER);
+  }
+
+  public String getAaiKeyStorePath() {
+    return certLocation + "/" + modelLoaderProperties.getProperty(PROP_AAI_KEYSTORE_FILE);
+  }
+
+  public String getAaiKeyStorePassword() {
+    return Password.deobfuscate(modelLoaderProperties.getProperty(PROP_AAI_KEYSTORE_PASSWORD));
+  }
+
+  public String getAaiBaseUrl() {
+    return modelLoaderProperties.getProperty(PROP_AAI_BASE_URL);
+  }
+
+  public String getAaiModelUrl() {
+    return modelLoaderProperties.getProperty(PROP_AAI_MODEL_RESOURCE_URL);
+  }
+
+  public String getAaiNamedQueryUrl() {
+    return modelLoaderProperties.getProperty(PROP_AAI_NAMED_QUERY_RESOURCE_URL);
+  }
+
+  public String getAaiVnfImageUrl() {
+    return modelLoaderProperties.getProperty(PROP_AAI_VNF_IMAGE_RESOURCE_URL);
+  }
+
+  public String getAaiAuthenticationUser() {
+    return modelLoaderProperties.getProperty(PROP_AAI_AUTHENTICATION_USER);
+  }
+
+  /**
+   * @return password for AAI authentication that has been reverse-engineered
+   *         from its obfuscated form.
+   */
+  public String getAaiAuthenticationPassword() {
+    String password = Password
+        .deobfuscate(modelLoaderProperties.getProperty(PROP_AAI_AUTHENTICATION_PASSWORD));
+
+    if ((password != null) && (password.equals(""))) {
+      return null;
+    }
+
+    return password;
+  }
+
+  /**
+   * @return a boolean value indicating whether the simulator is enabled.
+   */
+  public boolean getIngestSimulatorEnabled() {
+    String propValue = modelLoaderProperties.getProperty(PROP_DEBUG_INGEST_SIMULATOR);
+
+    if (propValue == null) {
+      return false;
+    }
+
+    if (propValue.compareToIgnoreCase("enabled") == 0) {
+      return true;
+    }
+
+    return false;
+  }
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/Artifact.java b/src/main/java/org/openecomp/modelloader/entity/Artifact.java
new file mode 100644 (file)
index 0000000..fb0ec9f
--- /dev/null
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity;
+
+public abstract class Artifact {
+
+  private String payload;
+  private ArtifactType type;
+
+  public ArtifactType getType() {
+    return type;
+  }
+
+  public void setType(ArtifactType type) {
+    this.type = type;
+  }
+
+  public String getPayload() {
+    return payload;
+  }
+
+  public void setPayload(String payload) {
+    this.payload = payload;
+  }
+
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/ArtifactHandler.java b/src/main/java/org/openecomp/modelloader/entity/ArtifactHandler.java
new file mode 100644 (file)
index 0000000..16f2c87
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity;
+
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+
+import java.util.List;
+
+public abstract class ArtifactHandler {
+
+  protected ModelLoaderConfig config;
+
+  public ArtifactHandler(ModelLoaderConfig config) {
+    this.config = config;
+  }
+
+  public abstract boolean pushArtifacts(List<Artifact> artifacts, String distributionId);
+
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java b/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java
new file mode 100644 (file)
index 0000000..8977e3c
--- /dev/null
@@ -0,0 +1,25 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity;
+
+public enum ArtifactType {
+  MODEL, NAMED_QUERY, VNF_CATALOG;
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifact.java b/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifact.java
new file mode 100644 (file)
index 0000000..b2e1fdb
--- /dev/null
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity.catalog;
+
+import org.openecomp.modelloader.entity.Artifact;
+import org.openecomp.modelloader.entity.ArtifactType;
+
+public class VnfCatalogArtifact extends Artifact {
+  public VnfCatalogArtifact(String payload) {
+    setPayload(payload);
+    setType(ArtifactType.VNF_CATALOG);
+  }
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandler.java b/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandler.java
new file mode 100644 (file)
index 0000000..189b069
--- /dev/null
@@ -0,0 +1,184 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity.catalog;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+import generated.VnfCatalog;
+import generated.VnfCatalog.PartNumberList;
+
+import inventory.aai.openecomp.org.v8.VnfImage;
+
+import org.eclipse.persistence.jaxb.MarshallerProperties;
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+import org.openecomp.modelloader.entity.Artifact;
+import org.openecomp.modelloader.entity.ArtifactHandler;
+import org.openecomp.modelloader.restclient.AaiRestClient;
+import org.openecomp.modelloader.restclient.AaiRestClient.MimeType;
+import org.openecomp.modelloader.service.ModelLoaderMsgs;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+
+public class VnfCatalogArtifactHandler extends ArtifactHandler {
+
+  private static Logger logger = LoggerFactory.getInstance()
+      .getLogger(VnfCatalogArtifactHandler.class.getName());
+
+  public VnfCatalogArtifactHandler(ModelLoaderConfig config) {
+    super(config);
+  }
+
+  @Override
+  public boolean pushArtifacts(List<Artifact> artifacts, String distributionId) {
+    for (Artifact art : artifacts) {
+      VnfCatalogArtifact vnfCatalog = (VnfCatalogArtifact) art;
+      String artifactPayload = vnfCatalog.getPayload();
+
+      AaiRestClient restClient = new AaiRestClient(this.config);
+      List<VnfImage> putImages = new ArrayList<VnfImage>();
+
+      try {
+        JAXBContext inputContext = JAXBContext.newInstance(VnfCatalog.class);
+        Unmarshaller unmarshaller = inputContext.createUnmarshaller();
+        StringReader reader = new StringReader(artifactPayload);
+        VnfCatalog cat = (VnfCatalog) unmarshaller.unmarshal(reader);
+
+        int numParts = cat.getPartNumberList().size();
+
+        for (int i = 0; i < numParts; i++) {
+
+          PartNumberList pnl = cat.getPartNumberList().get(i);
+
+          String application = pnl.getVendorInfo().getVendorModel();
+          String applicationVendor = pnl.getVendorInfo().getVendorName();
+
+          int numVersions = pnl.getSoftwareVersionList().size();
+
+          for (int j = 0; j < numVersions; j++) {
+            String applicationVersion = pnl.getSoftwareVersionList().get(j).getSoftwareVersion();
+
+            String imageId = "vnf image " + applicationVendor + " " + application + " "
+                + applicationVersion;
+
+            String getUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl()
+                + "?application-vendor=" + applicationVendor + "&application=" + application
+                + "&application-version=" + applicationVersion;
+
+            ClientResponse tryGet = restClient.getResource(getUrl, distributionId, MimeType.JSON);
+            if (tryGet == null) {
+              logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+                  "Ingestion failed on " + imageId + ". Rolling back distribution.");
+              failureCleanup(putImages, restClient, distributionId);
+              return false;
+            }
+            if (tryGet.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) {
+              // this vnf-image not already in the db, need to add
+              // only do this on 404 bc other error responses could mean there
+              // are problems that
+              // you might not want to try to PUT against
+
+              VnfImage image = new VnfImage();
+              image.setApplication(application);
+              image.setApplicationVendor(applicationVendor);
+              image.setApplicationVersion(applicationVersion);
+              String uuid = UUID.randomUUID().toString();
+              image.setUuid(uuid); // need to create uuid
+
+              System.setProperty("javax.xml.bind.context.factory",
+                  "org.eclipse.persistence.jaxb.JAXBContextFactory");
+              JAXBContext jaxbContext = JAXBContext.newInstance(VnfImage.class);
+              Marshaller marshaller = jaxbContext.createMarshaller();
+              marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
+              marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
+              marshaller.setProperty(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
+              marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
+              StringWriter writer = new StringWriter();
+              marshaller.marshal(image, writer);
+              String payload = writer.toString();
+
+              String putUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/"
+                  + uuid;
+
+              ClientResponse putResp = restClient.putResource(putUrl, payload, distributionId,
+                  MimeType.JSON);
+              if (putResp == null
+                  || putResp.getStatus() != Response.Status.CREATED.getStatusCode()) {
+                logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+                    "Ingestion failed on vnf-image " + imageId + ". Rolling back distribution.");
+                failureCleanup(putImages, restClient, distributionId);
+                return false;
+              }
+              putImages.add(image);
+              logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, imageId + " successfully ingested.");
+            } else if (tryGet.getStatus() == Response.Status.OK.getStatusCode()) {
+              logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
+                  imageId + " already exists.  Skipping ingestion.");
+            } else {
+              // if other than 404 or 200, something went wrong
+              logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+                  "Ingestion failed on vnf-image " + imageId + " with status " + tryGet.getStatus()
+                      + ". Rolling back distribution.");
+              failureCleanup(putImages, restClient, distributionId);
+              return false;
+            }
+          }
+        }
+
+      } catch (JAXBException e) {
+        logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+            "Ingestion failed. " + e.getMessage() + ". Rolling back distribution.");
+        failureCleanup(putImages, restClient, distributionId);
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /*
+   * if something fails in the middle of ingesting the catalog we want to
+   * rollback any changes to the db
+   */
+  private void failureCleanup(List<VnfImage> putImages, AaiRestClient restClient, String transId) {
+    for (VnfImage image : putImages) {
+      String url = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/"
+          + image.getUuid();
+      restClient.getAndDeleteResource(url, transId); // try to delete the image,
+                                                     // if something goes wrong
+                                                     // we can't really do
+                                                     // anything here
+    }
+  }
+
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifact.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifact.java
new file mode 100644 (file)
index 0000000..904dba9
--- /dev/null
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity.model;
+
+import org.openecomp.modelloader.entity.Artifact;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class ModelArtifact extends Artifact {
+
+  String nameVersionId;
+  Set<String> referencedModelIds = new HashSet<String>();
+
+  public String getNameVersionId() {
+    return nameVersionId;
+  }
+
+  public void setNameVersionId(String nameVersionId) {
+    this.nameVersionId = nameVersionId;
+  }
+
+  public Set<String> getDependentModelIds() {
+    return referencedModelIds;
+  }
+
+  public void addDependentModelId(String dependentModelId) {
+    this.referencedModelIds.add(dependentModelId);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append("NameVersId=" + nameVersionId + "(" + getType().toString() + ") ==> ");
+    for (String dep : referencedModelIds) {
+      sb.append(dep + "  ");
+    }
+
+    return sb.toString();
+  }
+
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactHandler.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactHandler.java
new file mode 100644 (file)
index 0000000..fb269b1
--- /dev/null
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity.model;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+import org.openecomp.modelloader.entity.Artifact;
+import org.openecomp.modelloader.entity.ArtifactHandler;
+import org.openecomp.modelloader.entity.ArtifactType;
+import org.openecomp.modelloader.restclient.AaiRestClient;
+import org.openecomp.modelloader.service.ModelLoaderMsgs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.core.Response;
+
+public class ModelArtifactHandler extends ArtifactHandler {
+
+  private static Logger logger = LoggerFactory.getInstance()
+      .getLogger(ArtifactHandler.class.getName());
+
+  public ModelArtifactHandler(ModelLoaderConfig config) {
+    super(config);
+  }
+
+  @Override
+  public boolean pushArtifacts(List<Artifact> artifacts, String distributionId) {
+    ModelSorter modelSorter = new ModelSorter();
+    List<Artifact> sortedModelArtifacts = modelSorter.sort(artifacts);
+
+    // Push the ordered list of model artifacts to A&AI. If one fails, we need
+    // to roll back
+    // the changes.
+    List<ModelArtifact> completedModels = new ArrayList<ModelArtifact>();
+    AaiRestClient aaiClient = new AaiRestClient(config);
+
+    for (Artifact art : sortedModelArtifacts) {
+      ModelArtifact model = (ModelArtifact) art;
+      ClientResponse getResponse = aaiClient.getResource(getUrl(model), distributionId,
+          AaiRestClient.MimeType.XML);
+      if ((getResponse == null)
+          || (getResponse.getStatus() != Response.Status.OK.getStatusCode())) {
+        // Only attempt the PUT if the model doesn't already exist
+        ClientResponse putResponse = aaiClient.putResource(getUrl(model), model.getPayload(),
+            distributionId, AaiRestClient.MimeType.XML);
+        if ((putResponse != null)
+            && (putResponse.getStatus() == Response.Status.CREATED.getStatusCode())) {
+          completedModels.add(model);
+          logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, model.getType().toString() + " "
+              + model.getNameVersionId() + " successfully ingested.");
+        } else {
+          logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+              "Ingestion failed for " + model.getType().toString() + " " + model.getNameVersionId()
+                  + ". Rolling back distribution.");
+
+          for (ModelArtifact modelToDelete : completedModels) {
+            // Best effort to delete. Nothing we can do in the event this fails.
+            aaiClient.getAndDeleteResource(getUrl(modelToDelete), distributionId);
+          }
+
+          return false;
+        }
+      } else {
+        logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, model.getType().toString() + " "
+            + model.getNameVersionId() + " already exists.  Skipping ingestion.");
+      }
+    }
+
+    return true;
+  }
+
+  private String getUrl(ModelArtifact model) {
+    String baseUrl = config.getAaiBaseUrl().trim();
+    String subUrl = null;
+    if (model.getType().equals(ArtifactType.MODEL)) {
+      subUrl = config.getAaiModelUrl().trim();
+    } else {
+      subUrl = config.getAaiNamedQueryUrl().trim();
+    }
+
+    if ((!baseUrl.endsWith("/")) && (!subUrl.startsWith("/"))) {
+      baseUrl = baseUrl + "/";
+    }
+
+    if (baseUrl.endsWith("/") && subUrl.startsWith("/")) {
+      baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
+    }
+
+    if (!subUrl.endsWith("/")) {
+      subUrl = subUrl + "/";
+    }
+
+    String url = baseUrl + subUrl + model.getNameVersionId();
+    return url;
+  }
+
+  /**
+   * This method is used for the test REST interface to load models without an
+   * ASDC.
+   * 
+   * @param payload content of the request
+   */
+  public void loadModelTest(byte[] payload) {
+    List<Artifact> modelArtifacts = new ArrayList<Artifact>();
+    ModelArtifactParser parser = new ModelArtifactParser();
+    modelArtifacts.addAll(parser.parse(payload, "Test-Artifact"));
+    ModelSorter modelSorter = new ModelSorter();
+    List<Artifact> sortedModelArtifacts = modelSorter.sort(modelArtifacts);
+    pushArtifacts(sortedModelArtifacts, "Test-Distribution");
+  }
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactParser.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactParser.java
new file mode 100644 (file)
index 0000000..625145f
--- /dev/null
@@ -0,0 +1,197 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity.model;
+
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.modelloader.entity.Artifact;
+import org.openecomp.modelloader.entity.ArtifactType;
+import org.openecomp.modelloader.service.ModelLoaderMsgs;
+import org.openecomp.modelloader.util.JsonXmlConverter;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+public class ModelArtifactParser {
+
+  private static String MODELS_ELEMENT = "models";
+  private static String MODEL_ELEMENT = "model";
+  private static String NAMED_QUERIES_ELEMENT = "named-queries";
+  private static String NAMED_QUERY_ELEMENT = "named-query";
+  private static String MODEL_NAME_VERSION_ID = "model-name-version-id";
+  private static String NAMED_QUERY_VERSION_ID = "named-query-uuid";
+  private static String RELATIONSHIP_DATA = "relationship-data";
+  private static String RELATIONSHIP_KEY = "relationship-key";
+  private static String RELATIONSHIP_VALUE = "relationship-value";
+  private static String MODEL_ELEMENT_RELATIONSHIP_KEY = "model.model-name-version-id";
+
+  private static Logger logger = LoggerFactory.getInstance()
+      .getLogger(ModelArtifactParser.class.getName());
+
+  /**
+   * This method parses the given artifact payload in byte array format and
+   * generates a list of model artifacts according to the content.
+   * 
+   * @param artifactPayload
+   *          artifact content to be parsed
+   * @param artifactName
+   *          name of the artifact
+   * @return a list of model artifacts
+   */
+  public List<Artifact> parse(byte[] artifactPayload, String artifactName) {
+    String payload = new String(artifactPayload);
+    List<Artifact> modelList = new ArrayList<Artifact>();
+
+    try {
+      // Artifact could be JSON or XML
+      if (JsonXmlConverter.isValidJson(payload)) {
+        payload = JsonXmlConverter.convertJsonToXml(payload);
+      }
+
+      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+      DocumentBuilder builder = factory.newDocumentBuilder();
+      InputSource is = new InputSource(new StringReader(payload));
+      Document doc = builder.parse(is);
+
+      if ((doc.getDocumentElement().getNodeName().equalsIgnoreCase(MODEL_ELEMENT))
+          || (doc.getDocumentElement().getNodeName().equalsIgnoreCase(NAMED_QUERY_ELEMENT))) {
+        ModelArtifact model = parseModel(doc.getDocumentElement(), payload);
+        if (model != null) {
+          modelList.add(model);
+        } else {
+          // TODO: A WARN message?
+          logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
+              "Unable to parse artifact " + artifactName);
+        }
+      } else if ((doc.getDocumentElement().getNodeName().equalsIgnoreCase(MODELS_ELEMENT))
+          || (doc.getDocumentElement().getNodeName().equalsIgnoreCase(NAMED_QUERIES_ELEMENT))) {
+        // The complete set of models/named-queries were contained in this
+        // artifact
+        NodeList nodeList = doc.getDocumentElement().getChildNodes();
+        for (int i = 0; i < nodeList.getLength(); i++) {
+          Node childNode = nodeList.item(i);
+          if ((childNode.getNodeName().equalsIgnoreCase(MODEL_ELEMENT))
+              || (childNode.getNodeName().equalsIgnoreCase(NAMED_QUERY_ELEMENT))) {
+            String modelPayload = nodeToString(childNode);
+            ModelArtifact model = parseModel(childNode, modelPayload);
+            if (model != null) {
+              modelList.add(model);
+            } else {
+              // TODO: A WARN message?
+              logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
+                  "Unable to parse artifact " + artifactName);
+              modelList.clear();
+              break;
+            }
+          }
+        }
+      }
+    } catch (Exception ex) {
+      // This may not be an error. We may be receiving an artifact that is
+      // unrelated
+      // to models. In this case, we just ignore it.
+      // TODO: A WARN message?
+      logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
+          "Unable to parse artifact " + artifactName + ": " + ex.getLocalizedMessage());
+    }
+
+    return modelList;
+  }
+
+  private ModelArtifact parseModel(Node modelNode, String payload) {
+    ModelArtifact model = new ModelArtifact();
+    model.setPayload(payload);
+
+    if (modelNode.getNodeName().equalsIgnoreCase(MODEL_ELEMENT)) {
+      model.setType(ArtifactType.MODEL);
+    } else {
+      model.setType(ArtifactType.NAMED_QUERY);
+    }
+
+    parseNode(modelNode, model);
+
+    if (model.getNameVersionId() == null) {
+      return null;
+    }
+
+    return model;
+  }
+
+  private void parseNode(Node node, ModelArtifact model) {
+    if (node.getNodeName().equalsIgnoreCase(MODEL_NAME_VERSION_ID)) {
+      model.setNameVersionId(node.getTextContent().trim());
+    } else if (node.getNodeName().equalsIgnoreCase(NAMED_QUERY_VERSION_ID)) {
+      model.setNameVersionId(node.getTextContent().trim());
+    } else if (node.getNodeName().equalsIgnoreCase(RELATIONSHIP_DATA)) {
+      parseRelationshipNode(node, model);
+    } else {
+      NodeList nodeList = node.getChildNodes();
+      for (int i = 0; i < nodeList.getLength(); i++) {
+        Node childNode = nodeList.item(i);
+        parseNode(childNode, model);
+      }
+    }
+  }
+
+  private void parseRelationshipNode(Node node, ModelArtifact model) {
+    String key = null;
+    String value = null;
+
+    NodeList nodeList = node.getChildNodes();
+    for (int i = 0; i < nodeList.getLength(); i++) {
+      Node childNode = nodeList.item(i);
+      if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_KEY)) {
+        key = childNode.getTextContent().trim();
+      } else if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_VALUE)) {
+        value = childNode.getTextContent().trim();
+      }
+    }
+
+    if ((key != null) && (key.equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY))) {
+      if (value != null) {
+        model.addDependentModelId(value);
+      }
+    }
+  }
+
+  private String nodeToString(Node node) throws TransformerException {
+    StringWriter sw = new StringWriter();
+    Transformer transfomer = TransformerFactory.newInstance().newTransformer();
+    transfomer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+    transfomer.transform(new DOMSource(node), new StreamResult(sw));
+    return sw.toString();
+  }
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java
new file mode 100644 (file)
index 0000000..4dcda71
--- /dev/null
@@ -0,0 +1,233 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity.model;
+
+import jline.internal.Log;
+
+import org.openecomp.modelloader.entity.Artifact;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Utility class to sort the given Models according to their dependencies.
+ * Example: Given a list of Models [A, B, C] where B depends on A, and A depends
+ * on C, the sorted result will be [C, A, B]
+ */
+public class ModelSorter {
+
+  /**
+   * Wraps a Model object to form dependencies other Models using Edges.
+   */
+  static class Node {
+    private final ModelArtifact model;
+    private final HashSet<Edge> inEdges;
+    private final HashSet<Edge> outEdges;
+
+    public Node(ModelArtifact model) {
+      this.model = model;
+      inEdges = new HashSet<Edge>();
+      outEdges = new HashSet<Edge>();
+    }
+
+    public Node addEdge(Node node) {
+      Edge edge = new Edge(this, node);
+      outEdges.add(edge);
+      node.inEdges.add(edge);
+      return this;
+    }
+
+    @Override
+    public String toString() {
+      return model.getNameVersionId();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+      ModelArtifact otherModel = ((Node) other).model;
+      return this.model.getNameVersionId().equals(otherModel.getNameVersionId());
+    }
+
+    @Override
+    public int hashCode() {
+      return this.model.getNameVersionId().hashCode();
+
+    }
+  }
+
+  /**
+   * Represents a dependency between two Nodes.
+   */
+  static class Edge {
+    public final Node from;
+    public final Node to;
+
+    public Edge(Node from, Node to) {
+      this.from = from;
+      this.to = to;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      Edge edge = (Edge) obj;
+      return edge.from == from && edge.to == to;
+    }
+  }
+
+  /**
+   * Returns the list of models sorted by order of dependency.
+   * 
+   * @param originalList
+   *          the list that needs to be sorted
+   * @return a list of sorted models
+   */
+  public List<Artifact> sort(List<Artifact> originalList) {
+
+    if (originalList.size() <= 1) {
+      return originalList;
+    }
+
+    Collection<Node> nodes = createNodes(originalList);
+    Collection<Node> sortedNodes = sortNodes(nodes);
+
+    List<Artifact> sortedModelsList = new ArrayList<Artifact>(sortedNodes.size());
+    for (Node node : sortedNodes) {
+      sortedModelsList.add(node.model);
+    }
+
+    return sortedModelsList;
+  }
+
+  /**
+   * Create nodes from the list of models and their dependencies.
+   * 
+   * @param models
+   *          what the nodes creation is based upon
+   * @return Collection of Node objects
+   */
+  private Collection<Node> createNodes(Collection<Artifact> models) {
+
+    // load list of models into a map, so we can later replace referenceIds with
+    // real Models
+    HashMap<String, ModelArtifact> versionIdToModelMap = new HashMap<String, ModelArtifact>();
+    for (Artifact art : models) {
+      ModelArtifact ma = (ModelArtifact) art;
+      versionIdToModelMap.put(ma.getNameVersionId(), ma);
+    }
+
+    HashMap<String, Node> nodes = new HashMap<String, Node>();
+    // create a node for each model and its referenced models
+    for (Artifact art : models) {
+      ModelArtifact model = (ModelArtifact) art;
+
+      // node might have been created by another model referencing it
+      Node node = nodes.get(model.getNameVersionId());
+
+      if (null == node) {
+        node = new Node(model);
+        nodes.put(model.getNameVersionId(), node);
+      }
+
+      for (String referencedModelId : model.getDependentModelIds()) {
+        // node might have been created by another model referencing it
+        Node referencedNode = nodes.get(referencedModelId);
+
+        if (null == referencedNode) {
+          // create node
+          ModelArtifact referencedModel = versionIdToModelMap.get(referencedModelId);
+          if (referencedModel == null) {
+            Log.debug("ignoring " + referencedModelId);
+            continue; // referenced model not supplied, no need to sort it
+          }
+          referencedNode = new Node(referencedModel);
+          nodes.put(referencedModelId, referencedNode);
+        }
+        referencedNode.addEdge(node);
+      }
+    }
+
+    return nodes.values();
+  }
+
+  /**
+   * Sorts the given Nodes by order of dependency.
+   * 
+   * @param originalList
+   *          the collection of nodes to be sorted
+   * @return a sorted collection of the given nodes
+   */
+  private Collection<Node> sortNodes(Collection<Node> unsortedNodes) {
+
+    // L <- Empty list that will contain the sorted elements
+    ArrayList<Node> nodeList = new ArrayList<Node>();
+
+    // S <- Set of all nodes with no incoming edges
+    HashSet<Node> nodeSet = new HashSet<Node>();
+    for (Node unsortedNode : unsortedNodes) {
+      if (unsortedNode.inEdges.size() == 0) {
+        nodeSet.add(unsortedNode);
+      }
+    }
+
+    // while S is non-empty do
+    while (!nodeSet.isEmpty()) {
+      // remove a node n from S
+      Node node = nodeSet.iterator().next();
+      nodeSet.remove(node);
+
+      // insert n into L
+      nodeList.add(node);
+
+      // for each node m with an edge e from n to m do
+      for (Iterator<Edge> it = node.outEdges.iterator(); it.hasNext();) {
+        // remove edge e from the graph
+        Edge edge = it.next();
+        Node to = edge.to;
+        it.remove();// Remove edge from n
+        to.inEdges.remove(edge);// Remove edge from m
+
+        // if m has no other incoming edges then insert m into S
+        if (to.inEdges.isEmpty()) {
+          nodeSet.add(to);
+        }
+      }
+    }
+    // Check to see if all edges are removed
+    boolean cycle = false;
+    for (Node node : unsortedNodes) {
+      if (!node.inEdges.isEmpty()) {
+        cycle = true;
+        break;
+      }
+    }
+    if (cycle) {
+      throw new RuntimeException(
+          "Circular dependency present between models, topological sort not possible");
+    }
+
+    return nodeList;
+  }
+
+}
diff --git a/src/main/java/org/openecomp/modelloader/notification/DistributionStatusMsg.java b/src/main/java/org/openecomp/modelloader/notification/DistributionStatusMsg.java
new file mode 100644 (file)
index 0000000..6079d5d
--- /dev/null
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.notification;
+
+import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
+import org.openecomp.sdc.utils.DistributionStatusEnum;
+
+public class DistributionStatusMsg implements IDistributionStatusMessage {
+  private DistributionStatusEnum status;
+  private String distributionId;
+  private String consumerId;
+  private String artifactUrl;
+
+  /**
+   * Creates a new DistributionStatusMsg instance.
+   * 
+   * @param status         - The distribution status to be reported.
+   * @param distributionId - The identifier of the distribution who's status is being rported on.
+   * @param consumerId     - Identifier of the consumer associated with the distribution.
+   * @param artifactUrl    - Resource identifier for the artifact.
+   */
+  public DistributionStatusMsg(DistributionStatusEnum status, 
+                               String distributionId,
+                               String consumerId, 
+                               String artifactUrl) {
+    this.status = status;
+    this.distributionId = distributionId;
+    this.consumerId = consumerId;
+    this.artifactUrl = artifactUrl;
+  }
+
+  @Override
+  public long getTimestamp() {
+    long currentTimeMillis = System.currentTimeMillis();
+    return currentTimeMillis;
+  }
+
+  @Override
+  public DistributionStatusEnum getStatus() {
+    return status;
+  }
+
+  @Override
+  public String getDistributionID() {
+    return distributionId;
+  }
+
+  @Override
+  public String getConsumerID() {
+    return consumerId;
+  }
+  
+  @Override
+  public String getArtifactURL() {
+    return artifactUrl;
+  }
+}
diff --git a/src/main/java/org/openecomp/modelloader/notification/EventCallback.java b/src/main/java/org/openecomp/modelloader/notification/EventCallback.java
new file mode 100644 (file)
index 0000000..3b32315
--- /dev/null
@@ -0,0 +1,286 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.notification;
+
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
+import org.openecomp.sdc.api.consumer.INotificationCallback;
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.notification.INotificationData;
+import org.openecomp.sdc.api.notification.IResourceInstance;
+import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.utils.ArtifactTypeEnum;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+import org.openecomp.sdc.utils.DistributionStatusEnum;
+
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.cl.mdc.MdcContext;
+import org.openecomp.cl.mdc.MdcOverride;
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+import org.openecomp.modelloader.entity.Artifact;
+import org.openecomp.modelloader.entity.catalog.VnfCatalogArtifact;
+import org.openecomp.modelloader.entity.catalog.VnfCatalogArtifactHandler;
+import org.openecomp.modelloader.entity.model.ModelArtifactHandler;
+import org.openecomp.modelloader.entity.model.ModelArtifactParser;
+import org.openecomp.modelloader.service.ModelLoaderMsgs;
+import org.slf4j.MDC;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+public class EventCallback implements INotificationCallback {
+
+  private IDistributionClient client;
+  private ModelLoaderConfig config;
+  private static Logger logger = LoggerFactory.getInstance()
+      .getLogger(EventCallback.class.getName());
+  private static Logger auditLogger = LoggerFactory.getInstance()
+      .getAuditLogger(EventCallback.class.getName());
+  private static Logger metricsLogger = LoggerFactory.getInstance()
+      .getMetricsLogger(EventCallback.class.getName());
+
+  private static SimpleDateFormat dateFormatter = new SimpleDateFormat(
+      "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+
+  public EventCallback(IDistributionClient client, ModelLoaderConfig config) {
+    this.client = client;
+    this.config = config;
+  }
+
+  @Override
+  public void activateCallback(INotificationData data) {
+    // Init MDC
+    MdcContext.initialize(data.getDistributionID(), "ModelLoader", "", "Event-Bus", "");
+
+    logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
+        "Received distribution " + data.getDistributionID());
+
+    boolean success = true;
+    List<IArtifactInfo> artifacts = getArtifacts(data);
+    List<Artifact> modelArtifacts = new ArrayList<Artifact>();
+    List<Artifact> catalogArtifacts = new ArrayList<Artifact>();
+    ModelArtifactParser modelArtParser = new ModelArtifactParser();
+
+    for (IArtifactInfo artifact : artifacts) {
+      // Grab the current time so we can measure the download time for the
+      // metrics log
+      long startTimeInMs = System.currentTimeMillis();
+      MdcOverride override = new MdcOverride();
+      override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
+
+      // Download Artifact
+      IDistributionClientDownloadResult downloadResult = client.download(artifact);
+
+      // Generate metrics log
+      metricsLogger.info(ModelLoaderMsgs.DOWNLOAD_COMPLETE, null, override,
+          artifact.getArtifactName(), downloadResult.getDistributionActionResult().toString());
+
+      if (downloadResult.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+        publishDownloadFailure(data, artifact, downloadResult.getDistributionMessageResult());
+        success = false;
+        break;
+      }
+
+      logger.debug("Artifact: " + artifact.getArtifactName() + "  Payload:\n" + new String(downloadResult.getArtifactPayload()));
+      
+      publishDownloadSuccess(data, artifact, downloadResult);
+
+      if ((artifact.getArtifactType()
+          .compareToIgnoreCase(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.toString()) == 0)
+          || (artifact.getArtifactType()
+              .compareToIgnoreCase(ArtifactTypeEnum.MODEL_QUERY_SPEC.toString()) == 0)) {
+        modelArtifacts.addAll(modelArtParser.parse(downloadResult.getArtifactPayload(),
+            downloadResult.getArtifactName()));
+      } else if (artifact.getArtifactType()
+          .compareToIgnoreCase(ArtifactTypeEnum.VNF_CATALOG.toString()) == 0) {
+        catalogArtifacts
+            .add(new VnfCatalogArtifact(new String(downloadResult.getArtifactPayload())));
+      }
+    }
+
+    String statusString = "SUCCESS";
+    if (success) {
+      ModelArtifactHandler modelHandler = new ModelArtifactHandler(config);
+      boolean modelDeploySuccess = modelHandler.pushArtifacts(modelArtifacts,
+          data.getDistributionID());
+
+      VnfCatalogArtifactHandler catalogHandler = new VnfCatalogArtifactHandler(config);
+      boolean catalogDeploySuccess = catalogHandler.pushArtifacts(catalogArtifacts,
+          data.getDistributionID());
+
+      for (IArtifactInfo artifact : artifacts) {
+        if ((artifact.getArtifactType()
+            .compareToIgnoreCase(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.toString()) == 0)
+            || (artifact.getArtifactType()
+                .compareToIgnoreCase(ArtifactTypeEnum.MODEL_QUERY_SPEC.toString()) == 0)) {
+          if (modelDeploySuccess) {
+            publishDeploySuccess(data, artifact);
+          } else {
+            publishDeployFailure(data, artifact);
+            statusString = "FAILURE";
+          }
+        } else if (artifact.getArtifactType()
+            .compareToIgnoreCase(ArtifactTypeEnum.VNF_CATALOG.toString()) == 0) {
+          if (catalogDeploySuccess) {
+            publishDeploySuccess(data, artifact);
+          } else {
+            publishDeployFailure(data, artifact);
+            statusString = "FAILURE";
+          }
+        }
+      }
+    }
+
+    auditLogger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
+        "Processed distribution " + data.getDistributionID() + "  (" + statusString + ")");
+    MDC.clear();
+  }
+
+  private List<IArtifactInfo> getArtifacts(INotificationData data) {
+    List<IArtifactInfo> artifacts = new ArrayList<IArtifactInfo>();
+    List<IResourceInstance> resources = data.getResources();
+
+    if (data.getServiceArtifacts() != null) {
+      artifacts.addAll(data.getServiceArtifacts());
+    }
+
+    if (resources != null) {
+      for (IResourceInstance resource : resources) {
+        if (resource.getArtifacts() != null) {
+          artifacts.addAll(resource.getArtifacts());
+        }
+      }
+    }
+
+    return artifacts;
+  }
+
+  private void publishDownloadFailure(INotificationData data, IArtifactInfo artifact,
+      String errorMessage) {
+    // Grab the current time so we can measure the download time for the metrics
+    // log
+    long startTimeInMs = System.currentTimeMillis();
+    MdcOverride override = new MdcOverride();
+    override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
+
+    IDistributionClientResult sendDownloadStatus = client.sendDownloadStatus(
+        buildStatusMessage(client, data, artifact, DistributionStatusEnum.DOWNLOAD_ERROR));
+    metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "download failure",
+        artifact.getArtifactName(), sendDownloadStatus.getDistributionActionResult().toString());
+
+    if (sendDownloadStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+      logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+          "Failed to publish download failure status: "
+              + sendDownloadStatus.getDistributionMessageResult());
+    }
+
+    logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+        "Failed to download artifact " + artifact.getArtifactName() + ": " + errorMessage);
+  }
+
+  private void publishDownloadSuccess(INotificationData data, IArtifactInfo artifact,
+      IDistributionClientDownloadResult downloadResult) {
+    // Grab the current time so we can measure the download time for the metrics
+    // log
+    long startTimeInMs = System.currentTimeMillis();
+    MdcOverride override = new MdcOverride();
+    override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
+
+    IDistributionClientResult sendDownloadStatus = client.sendDownloadStatus(
+        buildStatusMessage(client, data, artifact, DistributionStatusEnum.DOWNLOAD_OK));
+    metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "download success",
+        artifact.getArtifactName(), sendDownloadStatus.getDistributionActionResult().toString());
+
+    logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
+        "Downloaded artifact: " + artifact.getArtifactName());
+
+    if (sendDownloadStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+      logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+          "Failed to publish download success status: "
+              + sendDownloadStatus.getDistributionMessageResult());
+    }
+
+    if (logger.isDebugEnabled()) {
+      StringBuilder sb = new StringBuilder();
+      sb.append("Downloaded artifact:\n");
+      sb.append("ArtInfo_Art_Name: " + artifact.getArtifactName());
+      sb.append("\nArtInfo_Art_description: " + artifact.getArtifactDescription());
+      sb.append("\nArtInfo_Art_CheckSum: " + artifact.getArtifactChecksum());
+      sb.append("\nArtInfo_Art_Url: " + artifact.getArtifactURL());
+      sb.append("\nArtInfo_Art_Type: " + artifact.getArtifactType());
+      sb.append("\nArtInfo_Serv_description: " + data.getServiceDescription());
+      sb.append("\nArtInfo_Serv_Name: " + data.getServiceName());
+      sb.append("\nGet_serviceVersion: " + data.getServiceVersion());
+      sb.append("\nGet_Service_UUID: " + data.getServiceUUID());
+      sb.append("\nArtInfo_DistributionId: " + data.getDistributionID());
+      logger.debug(sb.toString());
+    }
+  }
+
+  private void publishDeployFailure(INotificationData data, IArtifactInfo artifact) {
+    // Grab the current time so we can measure the download time for the metrics
+    // log
+    long startTimeInMs = System.currentTimeMillis();
+    MdcOverride override = new MdcOverride();
+    override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
+
+    IDistributionClientResult sendStatus = client.sendDeploymentStatus(
+        buildStatusMessage(client, data, artifact, DistributionStatusEnum.DEPLOY_ERROR));
+    metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "deploy failure",
+        artifact.getArtifactName(), sendStatus.getDistributionActionResult().toString());
+
+    if (sendStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+      logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+          "Failed to publish deploy failure status: " + sendStatus.getDistributionMessageResult());
+    }
+  }
+
+  private void publishDeploySuccess(INotificationData data, IArtifactInfo artifact) {
+    // Grab the current time so we can measure the download time for the metrics
+    // log
+    long startTimeInMs = System.currentTimeMillis();
+    MdcOverride override = new MdcOverride();
+    override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
+
+    IDistributionClientResult sendStatus = client.sendDownloadStatus(
+        buildStatusMessage(client, data, artifact, DistributionStatusEnum.DEPLOY_OK));
+    metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "deploy success",
+        artifact.getArtifactName(), sendStatus.getDistributionActionResult().toString());
+
+    if (sendStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+      logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+          "Failed to publish deploy success status: " + sendStatus.getDistributionMessageResult());
+    }
+  }
+
+  private IDistributionStatusMessage buildStatusMessage(IDistributionClient client,
+      INotificationData data, IArtifactInfo artifact, DistributionStatusEnum status) {
+    IDistributionStatusMessage statusMessage = new DistributionStatusMsg(status,
+        data.getDistributionID(), client.getConfiguration().getConsumerID(),
+        artifact.getArtifactURL());
+
+    return statusMessage;
+  }
+
+}
diff --git a/src/main/java/org/openecomp/modelloader/restclient/AaiRestClient.java b/src/main/java/org/openecomp/modelloader/restclient/AaiRestClient.java
new file mode 100644 (file)
index 0000000..e13bdbd
--- /dev/null
@@ -0,0 +1,400 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.restclient;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.api.client.filter.LoggingFilter;
+import com.sun.jersey.client.urlconnection.HTTPSProperties;
+import org.openecomp.cl.api.LogFields;
+import org.openecomp.cl.api.LogLine;
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.cl.mdc.MdcContext;
+import org.openecomp.cl.mdc.MdcOverride;
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+import org.openecomp.modelloader.service.ModelLoaderMsgs;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.StringReader;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.ws.rs.core.Response;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+public class AaiRestClient {
+  public enum MimeType {
+    XML("application/xml"), JSON("application/json");
+
+    private String httpType;
+
+    MimeType(String httpType) {
+      this.httpType = httpType;
+    }
+
+    String getHttpHeaderType() {
+      return httpType;
+    }
+  }
+
+  private static String HEADER_TRANS_ID = "X-TransactionId";
+  private static String HEADER_FROM_APP_ID = "X-FromAppId";
+  private static String HEADER_AUTHORIZATION = "Authorization";
+  private static String ML_APP_NAME = "ModelLoader";
+  private static String RESOURCE_VERSION_PARAM = "resource-version";
+
+  private static SimpleDateFormat dateFormatter = new SimpleDateFormat(
+      "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+
+  private static Logger logger = LoggerFactory.getInstance()
+      .getLogger(AaiRestClient.class.getName());
+  private static Logger metricsLogger = LoggerFactory.getInstance()
+      .getMetricsLogger(AaiRestClient.class.getName());
+
+  private ModelLoaderConfig config = null;
+
+  public AaiRestClient(ModelLoaderConfig config) {
+    this.config = config;
+  }
+
+  /**
+   * Send a PUT request to the A&AI.
+   *
+   * @param url
+   *          - the url
+   * @param transId
+   *          - transaction ID
+   * @param payload
+   *          - the XML or JSON payload for the request
+   * @param mimeType
+   *          - the content type (XML or JSON)
+   * @return ClientResponse
+   */
+  public ClientResponse putResource(String url, String payload, String transId, MimeType mimeType) {
+    ClientResponse result = null;
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    long startTimeInMs = 0;
+    MdcOverride override = new MdcOverride();
+
+    try {
+      Client client = setupClient();
+
+      baos = new ByteArrayOutputStream();
+      PrintStream ps = new PrintStream(baos);
+      if (logger.isDebugEnabled()) {
+        client.addFilter(new LoggingFilter(ps));
+      }
+
+      // Grab the current time so that we can use it for metrics purposes later.
+      startTimeInMs = System.currentTimeMillis();
+      override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
+
+      if (useBasicAuth()) {
+        result = client.resource(url).header(HEADER_TRANS_ID, transId)
+            .header(HEADER_FROM_APP_ID, ML_APP_NAME)
+            .header(HEADER_AUTHORIZATION, getAuthenticationCredentials())
+            .type(mimeType.getHttpHeaderType()).put(ClientResponse.class, payload);
+      } else {
+        result = client.resource(url).header(HEADER_TRANS_ID, transId)
+            .header(HEADER_FROM_APP_ID, ML_APP_NAME).type(mimeType.getHttpHeaderType())
+            .put(ClientResponse.class, payload);
+      }
+    } catch (Exception ex) {
+      logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "PUT", url, ex.getLocalizedMessage());
+      return null;
+    } finally {
+      if (logger.isDebugEnabled()) {
+        logger.debug(baos.toString());
+      }
+    }
+
+    if ((result != null) && ((result.getStatus() == Response.Status.CREATED.getStatusCode())
+        || (result.getStatus() == Response.Status.OK.getStatusCode()))) {
+      logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "PUT", url,
+          Integer.toString(result.getStatus()));
+      metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS,
+          new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus())
+              .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION,
+                  result.getResponseStatus().toString()),
+          override, "PUT", url, Integer.toString(result.getStatus()));
+    } else {
+      // If response is not 200 OK, then additionally log the reason
+      String respMsg = result.getEntity(String.class);
+      if (respMsg == null) {
+        respMsg = result.getStatusInfo().getReasonPhrase();
+      }
+      logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_UNSUCCESSFUL, "PUT", url,
+          Integer.toString(result.getStatus()), respMsg);
+      metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_UNSUCCESSFUL,
+          new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus())
+              .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION,
+                  result.getResponseStatus().toString()),
+          override, "PUT", url, Integer.toString(result.getStatus()), respMsg);
+    }
+
+    return result;
+  }
+
+  /**
+   * Send a DELETE request to the A&AI.
+   *
+   * @param url
+   *          - the url
+   * @param resourceVersion
+   *          - the resource-version of the model to delete
+   * @param transId
+   *          - transaction ID
+   * @return ClientResponse
+   */
+  public ClientResponse deleteResource(String url, String resourceVersion, String transId) {
+    ClientResponse result = null;
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    long startTimeInMs = 0;
+    MdcOverride override = new MdcOverride();
+
+    try {
+      Client client = setupClient();
+
+      baos = new ByteArrayOutputStream();
+      PrintStream ps = new PrintStream(baos);
+      if (logger.isDebugEnabled()) {
+        client.addFilter(new LoggingFilter(ps));
+      }
+
+      // Grab the current time so that we can use it for metrics purposes later.
+      startTimeInMs = System.currentTimeMillis();
+      override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
+
+      if (useBasicAuth()) {
+        result = client.resource(url).queryParam(RESOURCE_VERSION_PARAM, resourceVersion)
+            .header(HEADER_TRANS_ID, transId).header(HEADER_FROM_APP_ID, ML_APP_NAME)
+            .header(HEADER_AUTHORIZATION, getAuthenticationCredentials())
+            .delete(ClientResponse.class);
+      } else {
+        result = client.resource(url).queryParam(RESOURCE_VERSION_PARAM, resourceVersion)
+            .header(HEADER_TRANS_ID, transId).header(HEADER_FROM_APP_ID, ML_APP_NAME)
+            .delete(ClientResponse.class);
+      }
+    } catch (Exception ex) {
+      logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "DELETE", url, ex.getLocalizedMessage());
+      return null;
+    } finally {
+      if (logger.isDebugEnabled()) {
+        logger.debug(baos.toString());
+      }
+    }
+
+    logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "DELETE", url,
+        Integer.toString(result.getStatus()));
+    metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS,
+        new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()).setField(
+            LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResponseStatus().toString()),
+        override, "DELETE", url, Integer.toString(result.getStatus()));
+
+    return result;
+  }
+
+  /**
+   * Send a GET request to the A&AI for a resource.
+   *
+   * @param url
+   *          - the url to use
+   * @param transId
+   *          - transaction ID
+   * @return ClientResponse
+   */
+  public ClientResponse getResource(String url, String transId, MimeType mimeType) {
+    ClientResponse result = null;
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    long startTimeInMs = 0;
+    MdcOverride override = new MdcOverride();
+
+    try {
+      Client client = setupClient();
+
+      baos = new ByteArrayOutputStream();
+      PrintStream ps = new PrintStream(baos);
+      if (logger.isDebugEnabled()) {
+        client.addFilter(new LoggingFilter(ps));
+      }
+
+      // Grab the current time so that we can use it for metrics purposes later.
+      startTimeInMs = System.currentTimeMillis();
+      override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
+
+      if (useBasicAuth()) {
+        result = client.resource(url).header(HEADER_TRANS_ID, transId)
+            .header(HEADER_FROM_APP_ID, ML_APP_NAME).accept(mimeType.getHttpHeaderType())
+            .header(HEADER_AUTHORIZATION, getAuthenticationCredentials()).get(ClientResponse.class);
+      } else {
+        result = client.resource(url).header(HEADER_TRANS_ID, transId)
+            .header(HEADER_FROM_APP_ID, ML_APP_NAME).accept(mimeType.getHttpHeaderType())
+            .get(ClientResponse.class);
+
+      }
+    } catch (Exception ex) {
+      logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "GET", url, ex.getLocalizedMessage());
+      return null;
+    } finally {
+      if (logger.isDebugEnabled()) {
+        logger.debug(baos.toString());
+      }
+    }
+
+    logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "GET", url,
+        Integer.toString(result.getStatus()));
+    metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS,
+        new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()).setField(
+            LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResponseStatus().toString()),
+        override, "GET", url, Integer.toString(result.getStatus()));
+
+    return result;
+  }
+
+  /**
+   * Does a GET on a resource to retrieve the resource version, and then DELETE
+   * that version.
+   *
+   * @param url
+   *          - the url
+   * @param transId
+   *          - transaction ID
+   * @return ClientResponse
+   */
+  public ClientResponse getAndDeleteResource(String url, String transId) {
+    // First, GET the model
+    ClientResponse getResponse = getResource(url, transId, MimeType.XML);
+    if ((getResponse == null) || (getResponse.getStatus() != Response.Status.OK.getStatusCode())) {
+      return getResponse;
+    }
+
+    // Delete the model using the resource version in the response
+    String resVersion = null;
+    try {
+      resVersion = getResourceVersion(getResponse);
+    } catch (Exception e) {
+      logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "GET", url, e.getLocalizedMessage());
+      return null;
+    }
+
+    return deleteResource(url, resVersion, transId);
+  }
+
+  private Client setupClient() throws IOException, GeneralSecurityException {
+    ClientConfig clientConfig = new DefaultClientConfig();
+
+    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
+      @Override
+      public boolean verify(String string, SSLSession ssls) {
+        return true;
+      }
+    });
+
+    // Create a trust manager that does not validate certificate chains
+    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
+      @Override
+      public X509Certificate[] getAcceptedIssuers() {
+        return null;
+      }
+
+      @Override
+      public void checkClientTrusted(X509Certificate[] certs, String authType) {}
+
+      @Override
+      public void checkServerTrusted(X509Certificate[] certs, String authType) {}
+    } };
+
+    SSLContext ctx = SSLContext.getInstance("TLS");
+    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+    FileInputStream fin = new FileInputStream(config.getAaiKeyStorePath());
+    KeyStore ks = KeyStore.getInstance("PKCS12");
+    char[] pwd = config.getAaiKeyStorePassword().toCharArray();
+    ks.load(fin, pwd);
+    kmf.init(ks, pwd);
+
+    ctx.init(kmf.getKeyManagers(), trustAllCerts, null);
+    clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
+        new HTTPSProperties(new HostnameVerifier() {
+          @Override
+          public boolean verify(String theString, SSLSession sslSession) {
+            return true;
+          }
+        }, ctx));
+
+    Client client = Client.create(clientConfig);
+
+    return client;
+  }
+
+  private String getResourceVersion(ClientResponse response)
+      throws ParserConfigurationException, SAXException, IOException {
+    String respData = response.getEntity(String.class);
+
+    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+    DocumentBuilder builder = factory.newDocumentBuilder();
+    InputSource is = new InputSource(new StringReader(respData));
+    Document doc = builder.parse(is);
+
+    NodeList nodeList = doc.getDocumentElement().getChildNodes();
+    for (int i = 0; i < nodeList.getLength(); i++) {
+      Node currentNode = nodeList.item(i);
+      if (currentNode.getNodeName().equals(RESOURCE_VERSION_PARAM)) {
+        return currentNode.getTextContent();
+      }
+    }
+
+    return null;
+  }
+
+  private String getAuthenticationCredentials() {
+
+    String usernameAndPassword = config.getAaiAuthenticationUser() + ":"
+        + config.getAaiAuthenticationPassword();
+    return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes());
+  }
+
+  public boolean useBasicAuth() {
+    return (config.getAaiAuthenticationUser() != null)
+        && (config.getAaiAuthenticationPassword() != null);
+  }
+}
diff --git a/src/main/java/org/openecomp/modelloader/service/ModelLoaderInterface.java b/src/main/java/org/openecomp/modelloader/service/ModelLoaderInterface.java
new file mode 100644 (file)
index 0000000..689115e
--- /dev/null
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.service;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+
+public interface ModelLoaderInterface {
+
+  @GET
+  @Path("/loadModel/{modelid}")
+  public Response loadModel(@PathParam("modelid") String modelid);
+
+  @PUT
+  @Path("/saveModel/{modelid}/{modelname}")
+  public Response saveModel(@PathParam("modelid") String modelid,
+      @PathParam("modelname") String modelname);
+
+  @POST
+  @Consumes("application/xml")
+  @Produces("application/xml")
+  @Path("/ingestModel/{modelid}")
+  public Response ingestModel(@PathParam("modelid") String modelid, @Context HttpServletRequest req,
+      String payload) throws IOException;
+}
diff --git a/src/main/java/org/openecomp/modelloader/service/ModelLoaderMsgs.java b/src/main/java/org/openecomp/modelloader/service/ModelLoaderMsgs.java
new file mode 100644 (file)
index 0000000..b81c541
--- /dev/null
@@ -0,0 +1,102 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.service;
+
+import com.att.eelf.i18n.EELFResourceManager;
+
+import org.openecomp.cl.eelf.LogMessageEnum;
+
+public enum ModelLoaderMsgs implements LogMessageEnum {
+
+  /**
+   * Arguments: None.
+   */
+  LOADING_CONFIGURATION,
+
+  /**
+   * Arguments: None.
+   */
+  STOPPING_CLIENT,
+
+  /**
+   * Arguments: {0} = message.
+   */
+  INITIALIZING,
+
+  /**
+   * Arguments: {0} = reason.
+   */
+  ASDC_CONNECTION_ERROR,
+
+  /**
+   * Arguments: {0} = message.
+   */
+  DISTRIBUTION_EVENT,
+
+  /**
+   * Arguments: {0} = error message.
+   */
+  DISTRIBUTION_EVENT_ERROR, 
+  
+  /**
+    * Arguments: {0} = request type.
+    *            {1} = endpoint. 
+    *            {2} = result code.
+    */
+  AAI_REST_REQUEST_SUCCESS,
+
+  /**
+   * Arguments: {0} = request type. 
+   *            {1} = endpoint. 
+   *            {2} = result code. 
+   *            {3} = result.
+   * message
+   */
+  AAI_REST_REQUEST_UNSUCCESSFUL,
+
+  /**
+   * Arguments: {0} = request type. 
+   *            {1} = endpoint.
+   *            {2} = error message.
+   */
+  AAI_REST_REQUEST_ERROR,
+
+  /**
+   * Arguments: {0} = artifact name. 
+   *            {1} = result.
+   */
+  DOWNLOAD_COMPLETE,
+
+  /**
+   * Arguments: {0} = event. 
+   *            {1} = artifact name. 
+   *            {2} = result.
+   */
+  EVENT_PUBLISHED;
+
+  /**
+   * Load message bundle (ModelLoaderMsgs.properties file)
+   */
+  static {
+    EELFResourceManager.loadMessageBundle("org/openecomp/modelloader/service/ModelLoaderMsgs");
+  }
+
+}
diff --git a/src/main/java/org/openecomp/modelloader/service/ModelLoaderService.java b/src/main/java/org/openecomp/modelloader/service/ModelLoaderService.java
new file mode 100644 (file)
index 0000000..16aba7e
--- /dev/null
@@ -0,0 +1,174 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.service;
+
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.impl.DistributionClientFactory;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+import org.openecomp.modelloader.entity.model.ModelArtifactHandler;
+import org.openecomp.modelloader.notification.EventCallback;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
+
+/**
+ * Service class in charge of managing the negotiating model loading
+ * capabilities between AAI and an ASDC.
+ */
+public class ModelLoaderService implements ModelLoaderInterface {
+
+  protected static String CONFIG_FILE = "model-loader.properties";
+
+  private IDistributionClient client;
+  private ModelLoaderConfig config;
+
+  static Logger logger = LoggerFactory.getInstance().getLogger(ModelLoaderService.class.getName());
+
+  /**
+   * Responsible for loading configuration files and calling initialization.
+   */
+  @PostConstruct
+  protected void start() {
+    // Load model loader system configuration
+    logger.info(ModelLoaderMsgs.LOADING_CONFIGURATION);
+    Properties configProperties = new Properties();
+    try {
+      configProperties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE));
+    } catch (IOException e) {
+      String errorMsg = "Failed to load configuration: " + e.getMessage();
+      logger.error(ModelLoaderMsgs.ASDC_CONNECTION_ERROR, errorMsg);
+      shutdown();
+    }
+    
+    config = new ModelLoaderConfig(configProperties);
+    init();
+  }
+
+  /**
+   * Responsible for stopping the connection to the distribution client before
+   * the resource is destroyed.
+   */
+  @PreDestroy
+  protected void preShutdownOperations() {
+    logger.info(ModelLoaderMsgs.STOPPING_CLIENT);
+    if (client != null) {
+      client.stop();
+    }
+  }
+
+  /**
+   * Responsible for loading configuration files, initializing model
+   * distribution clients, and starting them.
+   */
+  protected void init() {
+    // Initialize distribution client
+    logger.debug(ModelLoaderMsgs.INITIALIZING, "Initializing distribution client...");
+    client = DistributionClientFactory.createDistributionClient();
+    IDistributionClientResult initResult = client.init(config, new EventCallback(client, config));
+    if (initResult.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+      String errorMsg = "Failed to initialize distribution client: "
+          + initResult.getDistributionMessageResult();
+      logger.error(ModelLoaderMsgs.ASDC_CONNECTION_ERROR, errorMsg);
+      shutdown();
+    }
+
+    // Start distribution client
+    logger.debug(ModelLoaderMsgs.INITIALIZING, "Starting distribution client...");
+    IDistributionClientResult startResult = client.start();
+    if (startResult.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+      String errorMsg = "Failed to start distribution client: "
+          + startResult.getDistributionMessageResult();
+      logger.error(ModelLoaderMsgs.ASDC_CONNECTION_ERROR, errorMsg);
+      shutdown();
+    }
+
+    logger.debug(ModelLoaderMsgs.INITIALIZING,
+        "Succcessfully loaded service: " + this.getClass().getSimpleName());
+  }
+
+  /**
+   * Shut down the process.
+   */
+  private void shutdown() {
+    preShutdownOperations();
+
+    // TODO: Find a better way to shut down the model loader.
+    try {
+      // Give logs time to write to file
+      Thread.sleep(2000);
+    } catch (InterruptedException e) {
+      // Nothing we can do at this point
+    }
+
+    Runtime.getRuntime().halt(1);
+  }
+
+  /** (non-Javadoc)
+   * @see org.openecomp.modelloader.service.ModelLoaderInterface#loadModel(java.lang.String)
+   */
+  @Override
+  public Response loadModel(String modelid) {
+    Response response = Response.ok("{\"model_loaded\":\"" + modelid + "\"}").build();
+
+    return response;
+  }
+
+  /** (non-Javadoc)
+   * @see org.openecomp.modelloader.service.ModelLoaderInterface#saveModel(java.lang.String, java.lang.String)
+   */
+  @Override
+  public Response saveModel(String modelid, String modelname) {
+    Response response = Response.ok("{\"model_saved\":\"" + modelid + "-" + modelname + "\"}")
+        .build();
+
+    return response;
+  }
+
+  @Override
+  public Response ingestModel(String modelid, HttpServletRequest req, String payload)
+      throws IOException {
+    Response response;
+
+    if (config.getIngestSimulatorEnabled()) {
+      logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Received test artifact");
+
+      ModelArtifactHandler handler = new ModelArtifactHandler(config);
+      handler.loadModelTest(payload.getBytes());
+
+      response = Response.ok().build();
+    } else {
+      logger.debug("Simulation interface disabled");
+      response = Response.serverError().build();
+    }
+
+    return response;
+  }
+}
diff --git a/src/main/java/org/openecomp/modelloader/util/JsonXmlConverter.java b/src/main/java/org/openecomp/modelloader/util/JsonXmlConverter.java
new file mode 100644 (file)
index 0000000..ca63b23
--- /dev/null
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.util;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.XML;
+
+public class JsonXmlConverter {
+
+  /**
+   * Determines whether or not the supplied text string represents a valid
+   * JSON structure or not.
+   * 
+   * @param text - The text to be evaluated.
+   * 
+   * @return - true if the string represents a valid JSON object,
+   *           false, otherwise.
+   */
+  public static boolean isValidJson(String text) {
+    try {
+      new JSONObject(text);
+    } catch (JSONException ex) {
+      try {
+        new JSONArray(text);
+      } catch (JSONException ex1) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Takes a text string representing a valid JSON structure and converts it to
+   * an equivalent XML string.
+   * 
+   * @param jsonText - The JSON string to convert to XML.
+   * 
+   * @return - An XML string representation of the supplied JSON string.
+   */
+  public static String convertJsonToXml(String jsonText) {
+    JSONObject jsonObj = new JSONObject(jsonText);
+    String xmlText = XML.toString(jsonObj);
+    return xmlText;
+  }
+
+  /**
+   * Takes a text string representing a valid XML structure and converts it to
+   * an equivalent JSON string.
+   * 
+   * @param xmlText - The XML string to convert to JSON.
+   * 
+   * @return - A JSON string representation of the supplied XML string.
+   */
+  public static String convertXmlToJson(String xmlText) {
+    JSONObject jsonObj = XML.toJSONObject(xmlText);
+    return jsonObj.toString();
+  }
+}
diff --git a/src/main/resources/aai-os-cert.p12 b/src/main/resources/aai-os-cert.p12
new file mode 100644 (file)
index 0000000..ee57120
Binary files /dev/null and b/src/main/resources/aai-os-cert.p12 differ
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644 (file)
index 0000000..48233fe
--- /dev/null
@@ -0,0 +1,195 @@
+<!--
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="false">
+       <!--<jmxConfigurator /> -->
+       <!-- directory path for all other type logs -->
+
+       <property name="logDir" value="logs" />
+
+
+       <!-- specify the component name <ECOMP-component-name>::= "MSO" | "DCAE" 
+               | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC" -->
+       <property name="componentName" value="AAI-ML"></property>
+
+       <!-- default eelf log file names -->
+       <property name="generalLogName" value="error" />
+       <property name="metricsLogName" value="metrics" />
+       <property name="auditLogName" value="audit" />
+       <property name="debugLogName" value="debug" />
+
+       <property name="errorLogPattern"
+               value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%mdc{RequestId}|%thread|ModelLoader|%mdc{PartnerName}|%logger||%.-5level|%msg%n" />
+       <property name="auditMetricPattern" value="%m%n" />
+
+       <property name="logDirectory" value="${logDir}/${componentName}" />
+
+       <!-- Example evaluator filter applied against console appender -->
+       <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+               <encoder>
+                       <pattern>${defaultPattern}</pattern>
+               </encoder>
+       </appender>
+
+       <!-- ============================================================================ -->
+       <!-- EELF Appenders -->
+       <!-- ============================================================================ -->
+
+       <!-- The EELFAppender is used to record events to the general application 
+               log -->
+
+       <appender name="EELF"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <file>${logDirectory}/${generalLogName}.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/${generalLogName}.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
+                       <maxHistory>60</maxHistory>
+               </rollingPolicy>
+               <encoder>
+                       <pattern>${errorLogPattern}</pattern>
+               </encoder>
+       </appender>
+       <appender name="asyncEELF" class="ch.qos.logback.classic.AsyncAppender">
+               <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>INFO</level>
+               </filter>
+               <queueSize>256</queueSize>
+               <appender-ref ref="EELF" />
+       </appender>
+
+
+       <appender name="EELFAudit"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <file>${logDirectory}/${auditLogName}.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/${auditLogName}.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
+                       <maxHistory>60</maxHistory>
+               </rollingPolicy>
+               <encoder>
+                       <pattern>${auditMetricPattern}</pattern>
+               </encoder>
+       </appender>
+       <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>256</queueSize>
+               <appender-ref ref="EELFAudit" />
+       </appender>
+
+
+       <appender name="EELFMetrics"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <file>${logDirectory}/${metricsLogName}.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/${metricsLogName}.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
+                       <maxHistory>60</maxHistory>
+               </rollingPolicy>
+               <encoder>
+                       <pattern>${auditMetricPattern}</pattern>
+               </encoder>
+       </appender>
+       <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>256</queueSize>
+               <appender-ref ref="EELFMetrics" />
+       </appender>
+
+
+       <appender name="EELFDebug"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <file>${logDirectory}/${debugLogName}.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/${debugLogName}.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
+                       <maxHistory>60</maxHistory>
+               </rollingPolicy>
+               <encoder>
+                       <pattern>${errorLogPattern}</pattern>
+               </encoder>
+       </appender>
+       <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>256</queueSize>
+               <appender-ref ref="EELFDebug" />
+               <includeCallerData>true</includeCallerData>
+       </appender>
+
+
+       <!-- ============================================================================ -->
+       <!-- EELF loggers -->
+       <!-- ============================================================================ -->
+       <logger name="com.att.eelf" level="info" additivity="false">
+               <appender-ref ref="asyncEELF" />
+               <appender-ref ref="asyncEELFDebug" />
+       </logger>
+
+       <logger name="com.att.eelf.security" level="info" additivity="false">
+               <appender-ref ref="asyncEELFSecurity" />
+       </logger>
+       <logger name="com.att.eelf.perf" level="info" additivity="false">
+               <appender-ref ref="asyncEELFPerformance" />
+       </logger>
+       <logger name="com.att.eelf.server" level="info" additivity="false">
+               <appender-ref ref="asyncEELFServer" />
+       </logger>
+       <logger name="com.att.eelf.policy" level="info" additivity="false">
+               <appender-ref ref="asyncEELFPolicy" />
+       </logger>
+       <logger name="com.att.eelf.audit" level="info" additivity="false">
+               <appender-ref ref="asyncEELFAudit" />
+       </logger>
+       <logger name="com.att.eelf.metrics" level="info" additivity="false">
+               <appender-ref ref="asyncEELFMetrics" />
+       </logger>
+
+       <!-- Spring related loggers -->
+       <logger name="org.springframework" level="WARN" />
+       <logger name="org.springframework.beans" level="WARN" />
+       <logger name="org.springframework.web" level="WARN" />
+       <logger name="com.blog.spring.jms" level="WARN" />
+
+       <logger name="com.att" level="INFO" />
+
+       <!-- Model Loader loggers -->
+       <logger name="org.openecomp.modelloader" level="INFO" />
+
+       <!-- Other Loggers that may help troubleshoot -->
+       <logger name="net.sf" level="WARN" />
+       <logger name="org.apache.commons.httpclient" level="WARN" />
+       <logger name="org.apache.commons" level="WARN" />
+       <logger name="org.apache.coyote" level="WARN" />
+       <logger name="org.apache.jasper" level="WARN" />
+
+       <!-- Camel Related Loggers (including restlet/servlet/jaxrs/cxf logging. 
+               May aid in troubleshooting) -->
+       <logger name="org.apache.camel" level="WARN" />
+       <logger name="org.apache.cxf" level="WARN" />
+       <logger name="org.apache.camel.processor.interceptor" level="WARN" />
+       <logger name="org.apache.cxf.jaxrs.interceptor" level="WARN" />
+       <logger name="org.apache.cxf.service" level="WARN" />
+       <logger name="org.restlet" level="WARN" />
+       <logger name="org.apache.camel.component.restlet" level="WARN" />
+
+       <!-- logback internals logging -->
+       <logger name="ch.qos.logback.classic" level="WARN" />
+       <logger name="ch.qos.logback.core" level="WARN" />
+
+       <root>
+               <appender-ref ref="asyncEELF" />
+               <!-- <appender-ref ref="asyncEELFDebug" /> -->
+       </root>
+
+</configuration>
diff --git a/src/main/resources/model-loader.properties b/src/main/resources/model-loader.properties
new file mode 100644 (file)
index 0000000..7b8f63d
--- /dev/null
@@ -0,0 +1,43 @@
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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=========================================================
+###
+
+# Model Loader Distribution Client Configuration
+ml.distribution.ACTIVE_SERVER_TLS_AUTH=false
+ml.distribution.ASDC_ADDRESS=
+ml.distribution.CONSUMER_GROUP=aai-ml-group
+ml.distribution.CONSUMER_ID=aai-ml
+ml.distribution.ENVIRONMENT_NAME=
+ml.distribution.KEYSTORE_PASSWORD=
+ml.distribution.KEYSTORE_FILE=asdc-client.jks
+ml.distribution.PASSWORD=
+ml.distribution.POLLING_INTERVAL=30
+ml.distribution.POLLING_TIMEOUT=20
+ml.distribution.USER=ci
+ml.distribution.ARTIFACT_TYPES=MODEL_INVENTORY_PROFILE,MODEL_QUERY_SPEC,VNF_CATALOG
+
+# Model Loader AAI REST Client Configuration
+ml.aai.BASE_URL=
+ml.aai.MODEL_URL=/aai/v8/service-design-and-creation/models/model/
+ml.aai.NAMED_QUERY_URL=/aai/v8/service-design-and-creation/named-queries/named-query/
+ml.aai.VNF_IMAGE_URL=/aai/v8/service-design-and-creation/vnf-images
+ml.aai.KEYSTORE_FILE=aai-os-cert.p12
+ml.aai.KEYSTORE_PASSWORD=
+ml.aai.AUTH_USER=ModelLoader
+ml.aai.AUTH_PASSWORD=
diff --git a/src/main/resources/org/openecomp/modelloader/filemonitor/FileMonitorMsgs.properties b/src/main/resources/org/openecomp/modelloader/filemonitor/FileMonitorMsgs.properties
new file mode 100644 (file)
index 0000000..9abd55c
--- /dev/null
@@ -0,0 +1,81 @@
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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=========================================================
+###
+
+#Resource key=Error Code|Message text|Resolution text |Description text
+#######
+#Newlines can be utilized to add some clarity ensuring continuing line
+#has atleast one leading space
+#ResourceKey=\
+#             ERR0000E\
+#             Sample error msg txt\
+#             Sample resolution msg\
+#             Sample description txt
+#
+######
+#Error code classification category
+#100    Permission errors
+#200    Availability errors/Timeouts
+#300    Data errors
+#400    Schema Interface type/validation errors
+#500    Business process errors
+#900    Unknown errors
+#
+########################################################################
+
+#AVAILABILITY ERRORS
+
+LOADING_FROM_FILE=\
+                  FILEMON2001I|\
+                  Loading service properties from file {0}|\
+                  None. Attempting to load file|\
+                  Attempting to load service properties from the given service file
+                  
+FILE_SUCCESSFULLY_LOADED=\
+                  FILEMON2002I|\
+                  File {0} is loaded into the map and the corresponding system properties have been refreshed|\
+                  None. Successfully loaded file|\
+                  The given service file and its properties were successfully loaded
+                  
+FILE_CANNOT_BE_LOADED=\
+                  FILEMON2003E|\
+                  File {0} cannot be loaded into the map|\
+                  Please check the file permissions and format of the file|\
+                  Unable to load the given service file due to an error
+                        
+CANNOT_READ_FILE_STREAM=\  
+                  FILEMON2004E|\
+                  Error reading the file stream for file {0}|\
+                  Please ensure that the file exists and the permissions are set correctly|\
+                  Unable to read the file stream for the given file
+                
+#UNKNOWN ERRORS                
+                
+FILE_LISTENER_ATTACH_FAILED=\
+                  FILEMON9002W|\
+                  Unable to attach file change listener to file {0} due to an internal error|\
+                  Failed to attach file change listener to the given file. Please check the reported exception for details|\
+                  The file will not be actively monitored for changes
+                
+                
+PROP_MAP_CREATION_FAILED=\
+                  FILEMON9001E|\
+                  Internal Error occurred while creating property map for service files|\
+                  Error occurred due to an internal issue. Please check the reported exception for details |\
+                  Failed to create a property map for the service files
diff --git a/src/main/resources/org/openecomp/modelloader/service/ModelLoaderMsgs.properties b/src/main/resources/org/openecomp/modelloader/service/ModelLoaderMsgs.properties
new file mode 100644 (file)
index 0000000..53c96dc
--- /dev/null
@@ -0,0 +1,112 @@
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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=========================================================
+###
+
+#Resource key=Error Code|Message text|Resolution text |Description text
+#######
+#Newlines can be utilized to add some clarity ensuring continuing line
+#has at least one leading space
+#ResourceKey=\
+#             ERR0000E\
+#             Sample error msg txt\
+#             Sample resolution msg\
+#             Sample description txt
+#
+######
+#Error code classification category
+#000 Info/Debug
+#100 Permission errors
+#200 Availability errors/Timeouts
+#300 Data errors
+#400 Schema Interface type/validation errors
+#500 Business process errors
+#900 Unknown errors
+#
+########################################################################
+
+# INFO Level Logs
+LOADING_CONFIGURATION=\
+                  MDLSVC0001I|\
+                  Loading configuration |\
+                  None. Attempting to load configuration|\
+                  Attempting to load Model Loader Service configuration
+                  
+STOPPING_CLIENT=\
+                  MDLSVC0002I|\
+                  Stopping distribution client|\
+                  None. Stopping service|\
+                  Stopping the Model Service distribution client
+                  
+DISTRIBUTION_EVENT=\
+                  MDLSVC0003I|\
+                  Distribution event: {0}|\
+                  None. Processing distribution.|\
+                  A distribution event was received from the ASDC
+                  
+AAI_REST_REQUEST_SUCCESS=\
+                  MDLSVC0004I|\
+                  Sent {0} request to {1}.  Response: {2}|\
+                  None. Successfully sent REST request to AAI.|\
+                  The given request was sent to the specified endpoint.
+                  
+AAI_REST_REQUEST_UNSUCCESSFUL=\
+                  MDLSVC0005I|\
+                  Sent {0} request to {1}.  Response code: {2}, Response message: {3}|\
+                  REST request to AAI unsuccessful. Check response code, and message. |\
+                  The given request was unsuccessful.                                        
+
+DOWNLOAD_COMPLETE=\
+                  MDLSVC0006I|\
+                  Download of artifact {0} from ASDC complete.  Result: {1}|\
+                  None.|\
+                  An artifact was downloaded from the ASDC
+                  
+EVENT_PUBLISHED=\
+                  MDLSVC0007I|\
+                  Published {0} event for artifact {1}.  Result: {2}|\
+                  None.|\
+                  An event was published to the event bus
+                  
+# ERROR Level Logs                  
+ASDC_CONNECTION_ERROR=\
+                  MDLSVC2001E|\
+                  Unable to register with ASDC: {0}|\
+                  Check configuration.  Check network connection to ASDC|\
+                  During initialization, was not able to register with the configured ASDC instance
+                  
+DISTRIBUTION_EVENT_ERROR=\
+                  MDLSVC2002E|\
+                  Distribution event error: {0}|\
+                  Check configuration.  Check network connection to ASDC and UEB|\
+                  A failure occurred processing a distribution event
+                  
+AAI_REST_REQUEST_ERROR=\
+                  MDLSVC2003E|\
+                  Failed to send {0} request to {1}: {2}|\
+                  Check configuration.  Check network connection to AAI.|\
+                  A failure occurred attempting to send a request to the AAI
+                                  
+# DEBUG Level Logs                  
+INITIALIZING=\
+                  MDLSVC0001D|\
+                  init(): {0}|\
+                  None. Initializing service|\
+                  Debug information during model loader initialization
+                                  
+    
diff --git a/src/main/resources/schema/aai_schema_v8.xsd b/src/main/resources/schema/aai_schema_v8.xsd
new file mode 100644 (file)
index 0000000..66bc3db
--- /dev/null
@@ -0,0 +1,2462 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<xs:schema elementFormDefault="qualified" version="1.0"
+       targetNamespace="http://org.openecomp.aai.inventory/v8" xmlns:tns="http://org.openecomp.aai.inventory/v8"
+       xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+       <xs:element name="inventory-item-data">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="property-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="property-value" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="inventory-item">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="inventory-item-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="inventory-item-link" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:inventory-item-data" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                               <xs:element ref="tns:tagged-inventory-item-list"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="tagged-inventory-item-list">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:inventory-item" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="edge-tag-query-result">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:tagged-inventory-item-list"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="start-node-filter">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="property-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="property-value" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="include-node-filter">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="include-node-type" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="secondary-filter">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="property-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="filter-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="property-value" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="edge-tag-query-request">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="edge-tag" type="xs:string" minOccurs="0" />
+                               <xs:element name="result-detail" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="start-node-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:start-node-filter" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                               <xs:element ref="tns:include-node-filter" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                               <xs:element ref="tns:secondary-filter" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="result-data">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="resource-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-link" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="search-results">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:result-data" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="relationship-data">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="relationship-key" type="xs:string" />
+                               <xs:element name="relationship-value" type="xs:string" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="related-to-property">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="property-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="property-value" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="relationship">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="related-to" type="xs:string" minOccurs="0" />
+                               <xs:element name="related-link" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-data" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                               <xs:element ref="tns:related-to-property" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="relationship-list">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:relationship" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="oam-network">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="network-uuid" type="xs:string" />
+                               <xs:element name="network-name" type="xs:string" />
+                               <xs:element name="cvlan-tag" type="xs:unsignedInt" />
+                               <xs:element name="ipv4-oam-gateway-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-oam-gateway-address-prefix-length"
+                                       type="xs:int" minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="oam-networks">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:oam-network" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="dvs-switch">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="switch-name" type="xs:string" />
+                               <xs:element name="vcenter-url" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="dvs-switches">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:dvs-switch" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="availability-zone">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="availability-zone-name" type="xs:string" />
+                               <xs:element name="hypervisor-type" type="xs:string" />
+                               <xs:element name="operational-state" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="az-and-dvs-switches">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:dvs-switches" minOccurs="0" />
+                               <xs:element ref="tns:availability-zone" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="sdn-zone-response">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:oam-networks" minOccurs="0" />
+                               <xs:element ref="tns:az-and-dvs-switches" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="search">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:edge-tag-query-result" minOccurs="0" />
+                               <xs:element ref="tns:edge-tag-query-request" minOccurs="0" />
+                               <xs:element ref="tns:search-results" minOccurs="0" />
+                               <xs:element ref="tns:sdn-zone-response" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="update-node-key">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="key-name" type="xs:string" minOccurs="0" />
+                               <xs:element name="key-value" type="xs:string" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="action-data">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="property-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="property-value" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="action">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="action-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:action-data" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="update">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="update-node-type" type="xs:string" />
+                               <xs:element ref="tns:update-node-key" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                               <xs:element name="update-node-uri" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:action" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="key-data">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="key-name" type="xs:string" minOccurs="0" />
+                               <xs:element name="key-value" type="xs:string" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="notify">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="event-id" type="xs:string" />
+                               <xs:element name="node-type" type="xs:string" minOccurs="0" />
+                               <xs:element name="event-trigger" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:key-data" minOccurs="0" maxOccurs="unbounded" />
+                               <xs:element name="selflink" type="xs:string" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="actions">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:update" minOccurs="0" />
+                               <xs:element ref="tns:notify" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="ctag-pool">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="target-pe" type="xs:string" />
+                               <xs:element name="availability-zone-name" type="xs:string" />
+                               <xs:element name="ctag-pool-purpose" type="xs:string" />
+                               <xs:element name="ctag-values" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="ctag-pools">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:ctag-pool" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="complex">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="physical-location-id" type="xs:string" />
+                               <xs:element name="data-center-code" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="complex-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="identity-url" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="physical-location-type" type="xs:string" />
+                               <xs:element name="street1" type="xs:string" />
+                               <xs:element name="street2" type="xs:string" minOccurs="0" />
+                               <xs:element name="city" type="xs:string" />
+                               <xs:element name="state" type="xs:string" minOccurs="0" />
+                               <xs:element name="postal-code" type="xs:string" />
+                               <xs:element name="country" type="xs:string" />
+                               <xs:element name="region" type="xs:string" />
+                               <xs:element name="latitude" type="xs:string" minOccurs="0" />
+                               <xs:element name="longitude" type="xs:string" minOccurs="0" />
+                               <xs:element name="elevation" type="xs:string" minOccurs="0" />
+                               <xs:element name="lata" type="xs:string" minOccurs="0" />
+                               <xs:element ref="tns:ctag-pools" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="complexes">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:complex" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="volume-group">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="volume-group-id" type="xs:string" />
+                               <xs:element name="volume-group-name" type="xs:string" />
+                               <xs:element name="heat-stack-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vnf-type" type="xs:string" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="volume-groups">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:volume-group" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="volume">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="volume-id" type="xs:string" />
+                               <xs:element name="volume-selflink" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="volumes">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:volume" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="l3-interface-ipv4-address-list">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="l3-interface-ipv4-address" type="xs:string" />
+                               <xs:element name="l3-interface-ipv4-prefix-length" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="vlan-id-inner" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="vlan-id-outer" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="is-floating" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="neutron-network-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="neutron-subnet-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="l3-interface-ipv6-address-list">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="l3-interface-ipv6-address" type="xs:string" />
+                               <xs:element name="l3-interface-ipv6-prefix-length" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="vlan-id-inner" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="vlan-id-outer" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="is-floating" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="neutron-network-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="neutron-subnet-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vlan">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vlan-interface" type="xs:string" />
+                               <xs:element name="vlan-id-inner" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="vlan-id-outer" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="speed-value" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="speed-units" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vlan-description" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="backdoor-connection" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vpn-id" type="xs:string" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:l3-interface-ipv4-address-list"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                               <xs:element ref="tns:l3-interface-ipv6-address-list"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vlans">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vlan" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="sriov-vf">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="pci-id" type="xs:string" />
+                               <xs:element name="vf-vlan-filter" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vf-mac-filter" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vf-vlan-strip" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="vf-vlan-anti-spoof-check" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="vf-mac-anti-spoof-check" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="vf-mirrors" type="xs:string" minOccurs="0" />
+                               <xs:element name="vf-broadcast-allow" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="vf-unknown-multicast-allow" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="vf-unknown-unicast-allow" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="vf-insert-stag" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="vf-link-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="neutron-network-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="sriov-vfs">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:sriov-vf" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="l-interface">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="interface-name" type="xs:string" />
+                               <xs:element name="interface-role" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="v6-wan-link-ip" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="selflink" type="xs:string" minOccurs="0" />
+                               <xs:element name="interface-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="macaddr" type="xs:string" minOccurs="0" />
+                               <xs:element name="network-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="management-option" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:vlans" minOccurs="0" />
+                               <xs:element ref="tns:sriov-vfs" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:l3-interface-ipv4-address-list"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                               <xs:element ref="tns:l3-interface-ipv6-address-list"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="l-interfaces">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:l-interface" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vserver">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vserver-id" type="xs:string" />
+                               <xs:element name="vserver-name" type="xs:string" />
+                               <xs:element name="vserver-name2" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="prov-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vserver-selflink" type="xs:string" />
+                               <xs:element name="in-maint" type="xs:boolean" />
+                               <xs:element name="is-closed-loop-disabled" type="xs:boolean" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:volumes" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:l-interfaces" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vservers">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vserver" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="tenant">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="tenant-id" type="xs:string" />
+                               <xs:element name="tenant-name" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:vservers" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="tenants">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:tenant" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="flavor">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="flavor-id" type="xs:string" />
+                               <xs:element name="flavor-name" type="xs:string" />
+                               <xs:element name="flavor-vcpus" type="xs:int" minOccurs="0" />
+                               <xs:element name="flavor-ram" type="xs:int" minOccurs="0" />
+                               <xs:element name="flavor-disk" type="xs:int" minOccurs="0" />
+                               <xs:element name="flavor-ephemeral" type="xs:int"
+                                       minOccurs="0" />
+                               <xs:element name="flavor-swap" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="flavor-is-public" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="flavor-selflink" type="xs:string" />
+                               <xs:element name="flavor-disabled" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="flavors">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:flavor" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="group-assignment">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="group-id" type="xs:string" />
+                               <xs:element name="group-type" type="xs:string" />
+                               <xs:element name="group-name" type="xs:string" />
+                               <xs:element name="group-description" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="group-assignments">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:group-assignment" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="snapshot">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="snapshot-id" type="xs:string" />
+                               <xs:element name="snapshot-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="snapshot-architecture" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="snapshot-os-distro" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="snapshot-os-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="application" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="application-vendor" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="application-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="snapshot-selflink" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="prev-snapshot-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="snapshots">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:snapshot" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="metadatum">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="metaname" type="xs:string" />
+                               <xs:element name="metaval" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="metadata">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:metadatum" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="image">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="image-id" type="xs:string" />
+                               <xs:element name="image-name" type="xs:string" />
+                               <xs:element name="image-architecture" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="image-os-distro" type="xs:string" />
+                               <xs:element name="image-os-version" type="xs:string" />
+                               <xs:element name="application" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="application-vendor" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="application-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="image-selflink" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:metadata" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="images">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:image" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="availability-zones">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:availability-zone" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="cloud-region">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="cloud-owner" type="xs:string" />
+                               <xs:element name="cloud-region-id" type="xs:string" />
+                               <xs:element name="cloud-type" type="xs:string" minOccurs="0" />
+                               <xs:element name="owner-defined-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="cloud-region-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="identity-url" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="cloud-zone" type="xs:string" minOccurs="0" />
+                               <xs:element name="complex-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:volume-groups" minOccurs="0" />
+                               <xs:element ref="tns:tenants" minOccurs="0" />
+                               <xs:element ref="tns:flavors" minOccurs="0" />
+                               <xs:element ref="tns:group-assignments" minOccurs="0" />
+                               <xs:element ref="tns:snapshots" minOccurs="0" />
+                               <xs:element ref="tns:images" minOccurs="0" />
+                               <xs:element ref="tns:dvs-switches" minOccurs="0" />
+                               <xs:element ref="tns:oam-networks" minOccurs="0" />
+                               <xs:element ref="tns:availability-zones" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="cloud-regions">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:cloud-region" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="network-profile">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="nm-profile-name" type="xs:string" />
+                               <xs:element name="community-string" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="network-profiles">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:network-profile" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="p-interface">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="interface-name" type="xs:string" />
+                               <xs:element name="speed-value" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="speed-units" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="port-description" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="equipment-identifier" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="interface-role" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="interface-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:l-interfaces" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="p-interfaces">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:p-interface" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="lag-interface">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="interface-name" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="speed-value" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="speed-units" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:l-interfaces" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="lag-interfaces">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:lag-interface" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="pserver">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="hostname" type="xs:string" />
+                               <xs:element name="ptnii-equip-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="number-of-cpus" type="xs:int"
+                                       minOccurs="0" />
+                               <xs:element name="disk-in-gigabytes" type="xs:int"
+                                       minOccurs="0" />
+                               <xs:element name="ram-in-megabytes" type="xs:int"
+                                       minOccurs="0" />
+                               <xs:element name="equip-type" type="xs:string" minOccurs="0" />
+                               <xs:element name="equip-vendor" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="equip-model" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="fqdn" type="xs:string" minOccurs="0" />
+                               <xs:element name="pserver-selflink" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-oam-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="serial-number" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="pserver-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="internet-topology" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="in-maint" type="xs:boolean" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="pserver-name2" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="purpose" type="xs:string" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:p-interfaces" minOccurs="0" />
+                               <xs:element ref="tns:lag-interfaces" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="pservers">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:pserver" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="virtual-data-center">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vdc-id" type="xs:string" />
+                               <xs:element name="vdc-name" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="virtual-data-centers">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:virtual-data-center" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="cloud-infrastructure">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:complexes" minOccurs="0" />
+                               <xs:element ref="tns:cloud-regions" minOccurs="0" />
+                               <xs:element ref="tns:network-profiles" minOccurs="0" />
+                               <xs:element ref="tns:pservers" minOccurs="0" />
+                               <xs:element ref="tns:virtual-data-centers" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="license-key-resource">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="uuid" type="xs:string" />
+                               <xs:element name="assignment-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="assignment-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="assignment-group-uuid" type="xs:string" />
+                               <xs:element name="assignment-date" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="name" type="xs:string" minOccurs="0" />
+                               <xs:element name="model-uuid" type="xs:string" minOccurs="0" />
+                               <xs:element name="model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="license-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="license-key-file-url" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="supplier-release-list" type="xs:string"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="license-key-resources">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:license-key-resource" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="license-management">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:license-key-resources" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="connector">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="resource-instance-id" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:metadata" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="connectors">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:connector" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="service-instance">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="service-instance-id" type="xs:string" />
+                               <xs:element name="service-instance-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="bandwidth-total" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="bandwidth-up-wan1" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="bandwidth-down-wan1" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="bandwidth-up-wan2" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="bandwidth-down-wan2" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vhn-portal-url" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="operational-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="service-instance-location-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:metadata" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="service-instances">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:service-instance" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="service-subscription">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="service-type" type="xs:string" />
+                               <xs:element name="temp-ub-sub-account-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:service-instances" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="service-subscriptions">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:service-subscription" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="customer">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="global-customer-id" type="xs:string" />
+                               <xs:element name="subscriber-name" type="xs:string" />
+                               <xs:element name="subscriber-type" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:service-subscriptions" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="customers">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:customer" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="business">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:connectors" minOccurs="0" />
+                               <xs:element ref="tns:customers" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vnf-image">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="uuid" type="xs:string" />
+                               <xs:element name="application" type="xs:string" />
+                               <xs:element name="application-vendor" type="xs:string" />
+                               <xs:element name="application-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="selflink" type="xs:string" minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vnf-images">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vnf-image" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="service">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="service-id" type="xs:string" />
+                               <xs:element name="service-description" type="xs:string" />
+                               <xs:element name="service-selflink" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="service-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="services">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:service" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="service-capability">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="service-type" type="xs:string" />
+                               <xs:element name="vnf-type" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="service-capabilities">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:service-capability" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="element-choice-set">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="element-choice-set-uuid" type="xs:string" />
+                               <xs:element name="element-choice-set-name" type="xs:string" />
+                               <xs:element name="cardinality" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:model-elements" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="element-choice-sets">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:element-choice-set" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="constrained-element-set">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="constrained-element-set-uuid" type="xs:string" />
+                               <xs:element name="constraint-type" type="xs:string" />
+                               <xs:element name="check-type" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:element-choice-sets" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="constrained-element-sets">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:constrained-element-set" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="model-constraint">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="model-constraint-uuid" type="xs:string" />
+                               <xs:element name="constrained-element-set-uuid-to-replace"
+                                       type="xs:string" />
+                               <xs:element ref="tns:constrained-element-sets" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="model-constraints">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:model-constraint" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="model-element">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="model-element-uuid" type="xs:string" />
+                               <xs:element name="new-data-del-flag" type="xs:string" />
+                               <xs:element name="cardinality" type="xs:string" />
+                               <xs:element name="linkage-points" minOccurs="0">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:element name="linkage-point" type="xs:string"
+                                                               minOccurs="0" maxOccurs="unbounded" />
+                                               </xs:sequence>
+                                       </xs:complexType>
+                               </xs:element>
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:model-elements" minOccurs="0" />
+                               <xs:element ref="tns:model-constraints" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="model-elements">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:model-element" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="model">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="model-name-version-id" type="xs:string" />
+                               <xs:element name="model-type" type="xs:string" />
+                               <xs:element name="model-name" type="xs:string" />
+                               <xs:element name="model-id" type="xs:string" />
+                               <xs:element name="model-version" type="xs:string" />
+                               <xs:element name="model-description" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:model-elements" minOccurs="0" />
+                               <xs:element ref="tns:metadata" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="models">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:model" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="related-lookup">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="related-lookup-uuid" type="xs:string" />
+                               <xs:element name="source-node-type" type="xs:string" />
+                               <xs:element name="source-node-property" type="xs:string" />
+                               <xs:element name="target-node-type" type="xs:string" />
+                               <xs:element name="target-node-property" type="xs:string" />
+                               <xs:element name="property-collect-list" type="xs:string"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="related-lookups">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:related-lookup" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="property-constraint">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="property-constraint-uuid" type="xs:string" />
+                               <xs:element name="constraint-type" type="xs:string" />
+                               <xs:element name="property-name" type="xs:string" />
+                               <xs:element name="property-value" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="property-constraints">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:property-constraint" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="named-query-element">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="named-query-element-uuid" type="xs:string" />
+                               <xs:element name="property-collect-list" type="xs:string"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="property-limit-desc" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="do-not-output" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:named-query-elements" minOccurs="0" />
+                               <xs:element ref="tns:related-lookups" minOccurs="0" />
+                               <xs:element ref="tns:property-constraints" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="named-query-elements">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:named-query-element" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="named-query">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="named-query-uuid" type="xs:string" />
+                               <xs:element name="named-query-name" type="xs:string" />
+                               <xs:element name="named-query-version" type="xs:string" />
+                               <xs:element name="required-input-params" minOccurs="0">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:element name="required-input-param" type="xs:string"
+                                                               minOccurs="0" maxOccurs="unbounded" />
+                                               </xs:sequence>
+                                       </xs:complexType>
+                               </xs:element>
+                               <xs:element name="description" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:named-query-elements" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="named-queries">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:named-query" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="service-design-and-creation">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vnf-images" minOccurs="0" />
+                               <xs:element ref="tns:services" minOccurs="0" />
+                               <xs:element ref="tns:service-capabilities" minOccurs="0" />
+                               <xs:element ref="tns:models" minOccurs="0" />
+                               <xs:element ref="tns:named-queries" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="logical-link">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="link-name" type="xs:string" />
+                               <xs:element name="link-type" type="xs:string" />
+                               <xs:element name="speed-value" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="speed-units" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ip-version" type="xs:string" minOccurs="0" />
+                               <xs:element name="routing-protocol" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="operational-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="link-role" type="xs:string" minOccurs="0" />
+                               <xs:element name="link-name2" type="xs:string" minOccurs="0" />
+                               <xs:element name="link-id" type="xs:string" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="logical-links">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:logical-link" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="class-of-service">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="cos" type="xs:string" />
+                               <xs:element name="probe-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="probe-type" type="xs:string" minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="classes-of-service">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:class-of-service" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="site-pair">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="site-pair-id" type="xs:string" />
+                               <xs:element name="source-ip" type="xs:string" minOccurs="0" />
+                               <xs:element name="destination-ip" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ip-version" type="xs:string" minOccurs="0" />
+                               <xs:element name="destination-hostname" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="destination-equip-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:classes-of-service" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="site-pairs">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:site-pair" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="routing-instance">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="routing-instance-id" type="xs:string" />
+                               <xs:element name="rpm-owner" type="xs:string" minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:site-pairs" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="routing-instances">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:routing-instance" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="site-pair-set">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="site-pair-set-id" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:routing-instances" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="site-pair-sets">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:site-pair-set" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vpn-binding">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vpn-id" type="xs:string" />
+                               <xs:element name="vpn-name" type="xs:string" />
+                               <xs:element name="global-route-target" type="xs:string" />
+                               <xs:element name="vpn-platform" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vpn-bindings">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vpn-binding" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vpls-pe">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="equipment-name" type="xs:string" />
+                               <xs:element name="prov-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-oam-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="equipment-role" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vlan-id-outer" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:p-interfaces" minOccurs="0" />
+                               <xs:element ref="tns:lag-interfaces" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vpls-pes">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vpls-pe" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="multicast-configuration">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="multicast-configuration-id" type="xs:string" />
+                               <xs:element name="multicast-protocol" type="xs:string" />
+                               <xs:element name="rp-type" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="multicast-configurations">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:multicast-configuration" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="cvlan-tag-entry">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="cvlan-tag" type="xs:unsignedInt" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="cvlan-tags">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:cvlan-tag-entry" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="port-group">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="interface-id" type="xs:string" />
+                               <xs:element name="neutron-network-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="neutron-network-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="interface-role" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="port-group-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="port-group-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="switch-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string" />
+                               <xs:element name="heat-stack-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="mso-catalog-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:cvlan-tags" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="port-groups">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:port-group" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vce">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vnf-id" type="xs:string" />
+                               <xs:element name="vnf-name" type="xs:string" />
+                               <xs:element name="vnf-name2" type="xs:string" minOccurs="0" />
+                               <xs:element name="vnf-type" type="xs:string" />
+                               <xs:element name="service-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="regional-resource-zone" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="prov-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="operational-state" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="license-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="equipment-role" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="heat-stack-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="mso-catalog-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vpe-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="v6-vce-wan-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-oam-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-loopback0-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:port-groups" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vces">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vce" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vpe">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vnf-id" type="xs:string" />
+                               <xs:element name="vnf-name" type="xs:string" />
+                               <xs:element name="vnf-name2" type="xs:string" minOccurs="0" />
+                               <xs:element name="vnf-type" type="xs:string" />
+                               <xs:element name="service-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="regional-resource-zone" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="prov-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="operational-state" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="license-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="equipment-role" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="heat-stack-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="mso-catalog-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-oam-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-oam-gateway-address-prefix-length"
+                                       type="xs:int" minOccurs="0" />
+                               <xs:element name="ipv4-oam-gateway-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="v4-loopback0-ip-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vlan-id-outer" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="as-number" type="xs:string" minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="summary-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="encrypted-access-flag" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:l-interfaces" minOccurs="0" />
+                               <xs:element ref="tns:lag-interfaces" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vpes">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vpe" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vnfc">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vnfc-name" type="xs:string" />
+                               <xs:element name="vnfc-function-code" type="xs:string" />
+                               <xs:element name="vnfc-type" type="xs:string" />
+                               <xs:element name="prov-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipaddress-v4-oam-vip" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="in-maint" type="xs:boolean" />
+                               <xs:element name="is-closed-loop-disabled" type="xs:boolean" />
+                               <xs:element name="group-notation" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vnfcs">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vnfc" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="subnet">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="subnet-id" type="xs:string" />
+                               <xs:element name="subnet-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="neutron-subnet-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="gateway-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="network-start-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="cidr-mask" type="xs:string" minOccurs="0" />
+                               <xs:element name="ip-version" type="xs:string" minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="dhcp-enabled" type="xs:boolean" />
+                               <xs:element name="dhcp-start" type="xs:string" minOccurs="0" />
+                               <xs:element name="dhcp-end" type="xs:string" minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="subnets">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:subnet" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="ctag-assignment">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vlan-id-inner" type="xs:unsignedInt" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="ctag-assignments">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:ctag-assignment" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="segmentation-assignment">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="segmentation-id" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="segmentation-assignments">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:segmentation-assignment" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="l3-network">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="network-id" type="xs:string" />
+                               <xs:element name="network-name" type="xs:string" />
+                               <xs:element name="network-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="network-role" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="network-technology" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="neutron-network-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="is-bound-to-vpn" type="xs:boolean" />
+                               <xs:element name="service-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="network-role-instance" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="heat-stack-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="mso-catalog-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="contrail-network-fqdn" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="physical-network-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="is-provider-network" type="xs:boolean" />
+                               <xs:element name="is-shared-network" type="xs:boolean" />
+                               <xs:element name="is-external-network" type="xs:boolean" />
+                               <xs:element ref="tns:subnets" minOccurs="0" />
+                               <xs:element ref="tns:ctag-assignments" minOccurs="0" />
+                               <xs:element ref="tns:segmentation-assignments" minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="l3-networks">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:l3-network" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="network-policy">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="network-policy-id" type="xs:string" />
+                               <xs:element name="network-policy-fqdn" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="heat-stack-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="network-policies">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:network-policy" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vf-module">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vf-module-id" type="xs:string" />
+                               <xs:element name="vf-module-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="heat-stack-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="is-base-vf-module" type="xs:boolean" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="contrail-service-instance-fqdn" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vf-modules">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vf-module" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="generic-vnf">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vnf-id" type="xs:string" />
+                               <xs:element name="vnf-name" type="xs:string" />
+                               <xs:element name="vnf-name2" type="xs:string" minOccurs="0" />
+                               <xs:element name="vnf-type" type="xs:string" />
+                               <xs:element name="service-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="regional-resource-zone" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="prov-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="operational-state" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="license-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="equipment-role" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="heat-stack-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="mso-catalog-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="management-option" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-oam-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-loopback0-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="nm-lan-v6-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="management-v6-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vcpu" type="xs:unsignedInt" minOccurs="0" />
+                               <xs:element name="vcpu-units" type="xs:string" minOccurs="0" />
+                               <xs:element name="vmemory" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="vmemory-units" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="vdisk" type="xs:unsignedInt" minOccurs="0" />
+                               <xs:element name="vdisk-units" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="in-maint" type="xs:boolean" />
+                               <xs:element name="is-closed-loop-disabled" type="xs:boolean" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="summary-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="encrypted-access-flag" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="entitlement-assignment-group-uuid"
+                                       type="xs:string" minOccurs="0" />
+                               <xs:element name="entitlement-resource-uuid" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="license-assignment-group-uuid" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="license-key-uuid" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="persona-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="widget-model-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="as-number" type="xs:string" minOccurs="0" />
+                               <xs:element name="regional-resource-subzone" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:l-interfaces" minOccurs="0" />
+                               <xs:element ref="tns:lag-interfaces" minOccurs="0" />
+                               <xs:element ref="tns:vf-modules" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="generic-vnfs">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:generic-vnf" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="lag-link">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="link-name" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="lag-links">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:lag-link" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="newvce">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vnf-id2" type="xs:string" />
+                               <xs:element name="vnf-name" type="xs:string" />
+                               <xs:element name="vnf-name2" type="xs:string" minOccurs="0" />
+                               <xs:element name="vnf-type" type="xs:string" />
+                               <xs:element name="prov-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="operational-state" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="license-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-oam-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="equipment-role" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipv4-loopback0-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="heat-stack-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="mso-catalog-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:l-interfaces" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="newvces">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:newvce" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="pnf">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="pnf-name" type="xs:string" />
+                               <xs:element name="pnf-name2" type="xs:string" minOccurs="0" />
+                               <xs:element name="pnf-name2-source" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="pnf-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="equip-type" type="xs:string" minOccurs="0" />
+                               <xs:element name="equip-vendor" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="equip-model" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="management-option" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipaddress-v4-oam" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="sw-version" type="xs:string" minOccurs="0" />
+                               <xs:element name="orchestration-status" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="in-maint" type="xs:boolean" />
+                               <xs:element name="frame-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:p-interfaces" minOccurs="0" />
+                               <xs:element ref="tns:lag-interfaces" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="pnfs">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:pnf" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="physical-link">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="link-name" type="xs:string" />
+                               <xs:element name="speed-value" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="speed-units" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="circuit-id" type="xs:string" minOccurs="0" />
+                               <xs:element name="dual-mode" type="xs:string" minOccurs="0" />
+                               <xs:element name="management-option" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="service-provider-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="physical-links">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:physical-link" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vig-server">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vig-address-type" type="xs:string" />
+                               <xs:element name="ipaddress-v4-vig" type="xs:string"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                               <xs:element name="ipaddress-v6-vig" type="xs:string"
+                                       minOccurs="0" maxOccurs="unbounded" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vig-servers">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:vig-server" minOccurs="0" maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="ipsec-configuration">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="ipsec-configuration-id" type="xs:string" />
+                               <xs:element name="requested-vig-address-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="requested-encryption-strength" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="requested-dmz-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="shared-dmz-network-address" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="requested-customer-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ike-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ikev1-authentication" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ikev1-encryption" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ikev1-dh-group" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ikev1-am-group-id" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ikev1-am-password" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ikev1-sa-lifetime" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipsec-authentication" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipsec-encryption" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipsec-sa-lifetime" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="ipsec-pfs" type="xs:string" minOccurs="0" />
+                               <xs:element name="xauth-userid" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="xauth-user-password" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="dpd-interval" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="dpd-frequency" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                               <xs:element ref="tns:vig-servers" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="ipsec-configurations">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:ipsec-configuration" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="route-table-reference">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="route-table-reference-id" type="xs:string" />
+                               <xs:element name="route-table-reference-fqdn" type="xs:string" />
+                               <xs:element name="resource-version" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:relationship-list" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="route-table-references">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:route-table-reference" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="network">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:logical-links" minOccurs="0" />
+                               <xs:element ref="tns:site-pair-sets" minOccurs="0" />
+                               <xs:element ref="tns:vpn-bindings" minOccurs="0" />
+                               <xs:element ref="tns:vpls-pes" minOccurs="0" />
+                               <xs:element ref="tns:multicast-configurations" minOccurs="0" />
+                               <xs:element ref="tns:vces" minOccurs="0" />
+                               <xs:element ref="tns:vpes" minOccurs="0" />
+                               <xs:element ref="tns:vnfcs" minOccurs="0" />
+                               <xs:element ref="tns:l3-networks" minOccurs="0" />
+                               <xs:element ref="tns:network-policies" minOccurs="0" />
+                               <xs:element ref="tns:generic-vnfs" minOccurs="0" />
+                               <xs:element ref="tns:lag-links" minOccurs="0" />
+                               <xs:element ref="tns:newvces" minOccurs="0" />
+                               <xs:element ref="tns:pnfs" minOccurs="0" />
+                               <xs:element ref="tns:physical-links" minOccurs="0" />
+                               <xs:element ref="tns:ipsec-configurations" minOccurs="0" />
+                               <xs:element ref="tns:route-table-references" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="reserved-prop-names">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="last-mod-source-of-truth" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="aai-node-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="aai-created-ts" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="aai-unique-key" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="aai-last-mod-ts" type="xs:unsignedInt"
+                                       minOccurs="0" />
+                               <xs:element name="source-of-truth" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="edge-prop-names">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="edgeLabel" type="xs:string" minOccurs="0" />
+                               <xs:element name="direction" type="xs:string" minOccurs="0" />
+                               <xs:element name="multiplicityRule" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="isParent" type="xs:boolean" minOccurs="0" />
+                               <xs:element name="usesResource" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="hasDelTarget" type="xs:boolean"
+                                       minOccurs="0" />
+                               <xs:element name="SVC-INFRA" type="xs:string" minOccurs="0" />
+                               <xs:element name="SVC-INFRA-REV" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="aai-internal">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:reserved-prop-names" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                               <xs:element ref="tns:edge-prop-names" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="inventory">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:search" minOccurs="0" />
+                               <xs:element ref="tns:actions" minOccurs="0" />
+                               <xs:element ref="tns:cloud-infrastructure" minOccurs="0" />
+                               <xs:element ref="tns:license-management" minOccurs="0" />
+                               <xs:element ref="tns:business" minOccurs="0" />
+                               <xs:element ref="tns:service-design-and-creation"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:network" minOccurs="0" />
+                               <xs:element ref="tns:aai-internal" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="notification-event-header">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="id" type="xs:string" minOccurs="0" />
+                               <xs:element name="timestamp" type="xs:string" minOccurs="0" />
+                               <xs:element name="source-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="domain" type="xs:string" minOccurs="0" />
+                               <xs:element name="sequence-number" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="severity" type="xs:string" minOccurs="0" />
+                               <xs:element name="event-type" type="xs:string" minOccurs="0" />
+                               <xs:element name="version" type="xs:string" minOccurs="0" />
+                               <xs:element name="action" type="xs:string" minOccurs="0" />
+                               <xs:element name="entity-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="top-entity-type" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="entity-link" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="status" type="xs:string" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="notification-event">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="cambria.partition" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element ref="tns:notification-event-header"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="query-parameters">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:named-query" minOccurs="0" />
+                               <xs:element ref="tns:model" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="instance-filter">
+               <xs:complexType>
+                       <xs:sequence />
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="instance-filters">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:instance-filter" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="model-and-named-query-search">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:query-parameters" minOccurs="0" />
+                               <xs:element ref="tns:instance-filters" minOccurs="0" />
+                               <xs:element name="top-node-type" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="properties">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="property-name" type="xs:string"
+                                       minOccurs="0" />
+                               <xs:element name="property-value" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="extra-properties">
+               <xs:complexType>
+                       <xs:sequence />
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="inventory-response-item">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="model-name" type="xs:string" minOccurs="0" />
+                               <xs:element ref="tns:extra-properties" minOccurs="0" />
+                               <xs:element ref="tns:inventory-response-items" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="inventory-response-items">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:inventory-response-item" minOccurs="0"
+                                       maxOccurs="unbounded" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="response-list">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element ref="tns:inventory-response-items" minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="extra-property">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="property-name" type="xs:string"
+                                       minOccurs="0" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="vnf">
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="vnf-id" type="xs:string" />
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+</xs:schema>
diff --git a/src/main/resources/schema/vnfcatalog.xsd b/src/main/resources/schema/vnfcatalog.xsd
new file mode 100644 (file)
index 0000000..9789124
--- /dev/null
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+       <xsd:element name="vnf-catalog">
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element name="part-number-list" maxOccurs="unbounded">
+                                       <xsd:complexType>
+                                               <xsd:sequence>
+                                                       <xsd:element name="part-number" minOccurs="0"
+                                                               maxOccurs="1" type="xsd:normalizedString" />
+                                                       <xsd:element name="vnf-type" minOccurs="0" maxOccurs="1"
+                                                               type="xsd:normalizedString" />
+                                                       <xsd:element name="vendor-info" minOccurs="0"
+                                                               maxOccurs="1">
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence>
+                                                                               <xsd:element name="vendor-name" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                               <xsd:element name="vendor-part-number" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                               <xsd:element name="vendor-model" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                       </xsd:sequence>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                                       <xsd:element name="vcpu" minOccurs="0" maxOccurs="1">
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence>
+                                                                               <xsd:element name="vcpu-default" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:int" />
+                                                                               <xsd:element name="vcpu-min" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:int" />
+                                                                               <xsd:element name="vcpu-max" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:int" />
+                                                                       </xsd:sequence>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                                       <xsd:element name="vmemory" minOccurs="0" maxOccurs="1">
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence>
+                                                                               <xsd:element name="vmemory-default" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:int" />
+                                                                               <xsd:element name="vmemory-units" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                               <xsd:element name="vmemory-min" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:int" />
+                                                                               <xsd:element name="vmemory-max" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:int" />
+                                                                       </xsd:sequence>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                                       <xsd:element name="vdisk" minOccurs="0" maxOccurs="1">
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence>
+                                                                               <xsd:element name="vdisk-default" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:int" />
+                                                                               <xsd:element name="vdisk-units" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                               <xsd:element name="vdisk-min" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:int" />
+                                                                               <xsd:element name="vdisk-max" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:int" />
+                                                                       </xsd:sequence>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                                       <xsd:element name="software-version-list" maxOccurs="unbounded">
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence>
+                                                                               <xsd:element name="software-version" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                               <xsd:element name="software-version-state"
+                                                                                       minOccurs="0" maxOccurs="1" type="xsd:int" />
+                                                                               <xsd:element name="software-filetype" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                               <xsd:element name="file-md5-value" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                               <xsd:element name="software-filename" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                       </xsd:sequence>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                                       <xsd:element name="vnf-features-list" maxOccurs="unbounded">
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence>
+                                                                               <xsd:element name="vnf-feature" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                       </xsd:sequence>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                                       <xsd:element name="license-list" minOccurs="0"
+                                                               maxOccurs="1">
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence>
+                                                                               <xsd:element name="license-assignment-group"
+                                                                                       minOccurs="0" maxOccurs="1" type="xsd:normalizedString" />
+                                                                               <xsd:element name="license-required" minOccurs="0"
+                                                                                       maxOccurs="1" type="xsd:normalizedString" />
+                                                                       </xsd:sequence>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                               </xsd:sequence>
+                                       </xsd:complexType>
+                               </xsd:element>
+                       </xsd:sequence>
+               </xsd:complexType>
+       </xsd:element>
+</xsd:schema>
diff --git a/src/main/webapp/WEB-INF/applicationContext.xml b/src/main/webapp/WEB-INF/applicationContext.xml
new file mode 100644 (file)
index 0000000..efca1ce
--- /dev/null
@@ -0,0 +1,9 @@
+<beans xmlns="http://www.springframework.org/schema/beans"
+    xmlns:context="http://www.springframework.org/schema/context"
+    xmlns:mvc="http://www.springframework.org/schema/mvc"
+    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-4.0.xsd
+    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
+    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
+
+</beans>
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/rest-servlet.xml b/src/main/webapp/WEB-INF/rest-servlet.xml
new file mode 100644 (file)
index 0000000..e976951
--- /dev/null
@@ -0,0 +1,12 @@
+<beans xmlns="http://www.springframework.org/schema/beans"
+    xmlns:context="http://www.springframework.org/schema/context"
+    xmlns:mvc="http://www.springframework.org/schema/mvc"
+    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-4.0.xsd
+    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
+    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
+
+       <bean id="modelLoader" class="org.openecomp.modelloader.service.ModelLoaderService" init-method="start"/>
+               
+
+</beans>
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..7be34e7
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+  <display-name>model-loader</display-name>
+  
+  <listener>
+       <listener-class>
+               org.springframework.web.context.ContextLoaderListener
+       </listener-class>
+  </listener>
+  
+  <servlet>
+    <servlet-name>rest</servlet-name>
+    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>rest</servlet-name>
+    <url-pattern>/</url-pattern>
+  </servlet-mapping>
+</web-app>
\ No newline at end of file
diff --git a/src/test/java/org/openecomp/modelloader/config/ModelLoaderConfigTest.java b/src/test/java/org/openecomp/modelloader/config/ModelLoaderConfigTest.java
new file mode 100644 (file)
index 0000000..4018f14
--- /dev/null
@@ -0,0 +1,122 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+
+import org.eclipse.jetty.util.security.Password;
+import org.junit.Test;
+import org.openecomp.modelloader.restclient.AaiRestClient;
+
+import org.openecomp.sdc.utils.ArtifactTypeEnum;
+
+public class ModelLoaderConfigTest {
+
+  @Test
+  public void testYangModelArtifactType() {
+    Properties props = new Properties();
+    props.setProperty("ml.distribution.ARTIFACT_TYPES",
+        "MODEL_INVENTORY_PROFILE,MODEL_QUERY_SPEC,VNF_CATALOG");
+    ModelLoaderConfig config = new ModelLoaderConfig(props);
+
+    List<String> types = config.getRelevantArtifactTypes();
+
+    System.out.println("ArtifactType: " + types.get(0));
+    assertEquals(0,
+        types.get(0).compareToIgnoreCase(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.toString()));
+
+    System.out.println("ArtifactType: " + types.get(1));
+    assertEquals(0, types.get(1).compareToIgnoreCase(ArtifactTypeEnum.MODEL_QUERY_SPEC.toString()));
+
+    System.out.println("ArtifactType: " + types.get(2));
+    assertEquals(0, types.get(2).compareToIgnoreCase(ArtifactTypeEnum.VNF_CATALOG.toString()));
+
+    assertEquals(3, types.size());
+  }
+
+  @Test
+  public void testDecryptPassword() {
+    Properties props = new Properties();
+    String testPass = "youshallnotpass";
+    String encryptedTestPass = Password.obfuscate(testPass);
+
+    System.out.println("Encrypt " + testPass + " ==> " + encryptedTestPass);
+
+    props.put(ModelLoaderConfig.PROP_ML_DISTRIBUTION_PASSWORD, encryptedTestPass);
+    ModelLoaderConfig config = new ModelLoaderConfig(props);
+
+    assertEquals(testPass, config.getPassword());
+  }
+
+  @Test
+  public void testDecryptKeystorePassword() {
+    Properties props = new Properties();
+    String testPass = "youshallnotpass";
+    String encryptedTestPass = Password.obfuscate(testPass);
+
+    System.out.println("Encrypt " + testPass + " ==> " + encryptedTestPass);
+
+    props.put(ModelLoaderConfig.PROP_ML_DISTRIBUTION_KEYSTORE_PASSWORD, encryptedTestPass);
+    ModelLoaderConfig config = new ModelLoaderConfig(props);
+
+    assertEquals(testPass, config.getKeyStorePassword());
+  }
+
+  @Test
+  public void testDecryptAAIPassword() {
+
+    Properties props = new Properties();
+    String testPassword = "myvoiceismypassword";
+    String encryptedTestPassword = Password.obfuscate(testPassword);
+
+    props.put(ModelLoaderConfig.PROP_AAI_AUTHENTICATION_PASSWORD, encryptedTestPassword);
+    ModelLoaderConfig config = new ModelLoaderConfig(props);
+
+    assertEquals(testPassword, config.getAaiAuthenticationPassword());
+  }
+
+  @Test
+  public void testNoAAIAuth() throws IOException {
+
+    Properties props = new Properties();
+    props.load(
+        new FileInputStream("src/test/resources/model-loader-empty-auth-password.properties"));
+
+    ModelLoaderConfig config = new ModelLoaderConfig(props);
+    AaiRestClient aaiClient = new AaiRestClient(config);
+
+    assertFalse("Empty AAI Password should result in no basic authentication",
+        aaiClient.useBasicAuth());
+
+    props.load(new FileInputStream("src/test/resources/model-loader-no-auth-password.properties"));
+    config = new ModelLoaderConfig(props);
+    aaiClient = new AaiRestClient(config);
+
+    assertFalse("No AAI Password should result in no basic authentication",
+        aaiClient.useBasicAuth());
+  }
+}
diff --git a/src/test/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandlerTest.java b/src/test/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandlerTest.java
new file mode 100644 (file)
index 0000000..1b1d955
--- /dev/null
@@ -0,0 +1,98 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity.catalog;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+import org.openecomp.modelloader.entity.Artifact;
+import org.openecomp.modelloader.restclient.AaiRestClient;
+import org.openecomp.modelloader.restclient.AaiRestClient.MimeType;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ VnfCatalogArtifactHandler.class, ClientResponse.class, AaiRestClient.class })
+public class VnfCatalogArtifactHandlerTest {
+
+  protected static String CONFIG_FILE = "model-loader.properties";
+
+  @Test
+  public void testWithMocks() throws Exception {
+
+    Properties configProperties = new Properties();
+    try {
+      configProperties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE));
+    } catch (IOException e) {
+      fail();
+    }
+    ModelLoaderConfig config = new ModelLoaderConfig(configProperties);
+
+    ClientResponse mockGetResp = PowerMockito.mock(ClientResponse.class);
+    PowerMockito.when(mockGetResp.getStatus()).thenReturn(200).thenReturn(200).thenReturn(404)
+        .thenReturn(404).thenReturn(200); // only second two will be PUT
+    ClientResponse mockPutResp = PowerMockito.mock(ClientResponse.class);
+    PowerMockito.when(mockPutResp.getStatus()).thenReturn(201);
+
+    AaiRestClient mockRestClient = PowerMockito.mock(AaiRestClient.class);
+    PowerMockito.whenNew(AaiRestClient.class).withAnyArguments().thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.getResource(Mockito.anyString(), Mockito.anyString(),
+        Mockito.any(MimeType.class))).thenReturn(mockGetResp);
+    PowerMockito.when(mockRestClient.putResource(Mockito.anyString(), Mockito.anyString(),
+        Mockito.anyString(), Mockito.any(MimeType.class))).thenReturn(mockPutResp);
+
+    VnfCatalogArtifactHandler vnfCAH = new VnfCatalogArtifactHandler(config);
+
+    String examplePath = "src/test/resources/vnfcatalogexample.xml";
+
+    byte[] encoded = Files.readAllBytes(Paths.get(examplePath));
+    String payload = new String(encoded, "utf-8");
+
+    VnfCatalogArtifact artifact = new VnfCatalogArtifact(payload);
+    List<Artifact> artifacts = new ArrayList<Artifact>();
+    artifacts.add(artifact);
+
+    String distributionID = "test";
+
+    assertTrue(vnfCAH.pushArtifacts(artifacts, distributionID));
+    // times(2) bc with above get returns should only get to this part twice
+    ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
+    Mockito.verify(mockRestClient, Mockito.times(2)).putResource(Mockito.anyString(),
+        argument.capture(), Mockito.anyString(), Mockito.any(MimeType.class));
+    assertTrue(argument.getAllValues().get(0).contains("5.2.5"));
+    assertTrue(argument.getAllValues().get(1).contains("5.2.4"));
+  }
+}
diff --git a/src/test/java/org/openecomp/modelloader/entity/model/ModelArtifactParserTest.java b/src/test/java/org/openecomp/modelloader/entity/model/ModelArtifactParserTest.java
new file mode 100644 (file)
index 0000000..448e5d3
--- /dev/null
@@ -0,0 +1,151 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity.model;
+
+import static org.junit.Assert.assertTrue;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
+import org.junit.Test;
+import org.openecomp.modelloader.entity.Artifact;
+
+public class ModelArtifactParserTest {
+
+  @Test
+  public void testParseModelFileNoDeps() throws Exception {
+    final String MODEL_FILE = "src/test/resources/models/vnf-model.xml";
+
+    try {
+      byte[] xmlBytes = Files.readAllBytes(Paths.get(MODEL_FILE));
+
+      ModelArtifactParser parser = new ModelArtifactParser();
+      List<Artifact> modelList = parser.parse(xmlBytes, "test-artifact");
+
+      assertTrue(modelList.size() == 1);
+
+      ModelArtifact model = (ModelArtifact) modelList.get(0);
+      System.out.println(model.toString());
+
+      assertTrue(model.getNameVersionId().equalsIgnoreCase("model-vid"));
+      assertTrue(model.getType().toString().equalsIgnoreCase("MODEL"));
+      assertTrue(model.getDependentModelIds().size() == 0);
+    } catch (Exception e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+  }
+
+  @Test
+  public void testParseModelFileDeps() throws Exception {
+    final String MODEL_FILE = "src/test/resources/models/wan-connector-model.xml";
+
+    try {
+      byte[] xmlBytes = Files.readAllBytes(Paths.get(MODEL_FILE));
+
+      ModelArtifactParser parser = new ModelArtifactParser();
+      List<Artifact> modelList = parser.parse(xmlBytes, "test-artifact");
+
+      assertTrue(modelList.size() == 1);
+
+      ModelArtifact model = (ModelArtifact) modelList.get(0);
+      System.out.println(model.toString());
+
+      assertTrue(model.getNameVersionId().equalsIgnoreCase("93d9d45d-7eec-4371-9083-675e4c353de3"));
+      assertTrue(model.getType().toString().equalsIgnoreCase("MODEL"));
+      assertTrue(model.getDependentModelIds().size() == 7);
+      assertTrue(model.getDependentModelIds().contains("d09dd9da-0148-46cd-a947-591afc844d24"));
+      assertTrue(model.getDependentModelIds().contains("ae16244f-4d29-4801-a559-e25f2db2a4c3"));
+      assertTrue(model.getDependentModelIds().contains("a6d9de88-4046-4b78-a59e-5691243d292a"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+  }
+
+  @Test
+  public void testParseCompleteModel() throws Exception {
+    final String MODEL_FILE = "src/test/resources/models/complete-model.xml";
+
+    try {
+      byte[] xmlBytes = Files.readAllBytes(Paths.get(MODEL_FILE));
+
+      ModelArtifactParser parser = new ModelArtifactParser();
+      List<Artifact> modelList = parser.parse(xmlBytes, "test-artifact");
+
+      for (Artifact art : modelList) {
+        ModelArtifact model = (ModelArtifact) art;
+        System.out.println(model.toString());
+      }
+
+      assertTrue(modelList.size() == 14);
+
+      ModelArtifact modelVdc = (ModelArtifact) modelList.get(0);
+      assertTrue(
+          modelVdc.getNameVersionId().equalsIgnoreCase("997fc7-fca1-451f-b953-9a1e6197b4d6"));
+      assertTrue(modelVdc.getType().toString().equalsIgnoreCase("MODEL"));
+      assertTrue(modelVdc.getDependentModelIds().size() == 1);
+      assertTrue(modelVdc.getDependentModelIds().contains("93d9d45d-7eec-4371-9083-675e4c353de3"));
+
+      ModelArtifact modelPserver = (ModelArtifact) modelList.get(9);
+      assertTrue(
+          modelPserver.getNameVersionId().equalsIgnoreCase("f2b24d95-c582-48d5-b2d6-c5b3a94ce812"));
+      assertTrue(modelPserver.getType().toString().equalsIgnoreCase("MODEL"));
+      assertTrue(modelPserver.getDependentModelIds().size() == 2);
+      assertTrue(
+          modelPserver.getDependentModelIds().contains("35be1acf-1298-48c6-a128-66850083b8bd"));
+      assertTrue(
+          modelPserver.getDependentModelIds().contains("759dbd4a-2473-46f3-a932-48d987c9b4a1"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+  }
+
+  @Test
+  public void testParseNamedQuery() throws Exception {
+    final String MODEL_FILE = "src/test/resources/models/named-query-wan-connector.xml";
+
+    try {
+      byte[] xmlBytes = Files.readAllBytes(Paths.get(MODEL_FILE));
+
+      ModelArtifactParser parser = new ModelArtifactParser();
+      List<Artifact> modelList = parser.parse(xmlBytes, "test-artifact");
+
+      assertTrue(modelList.size() == 1);
+
+      ModelArtifact model = (ModelArtifact) modelList.get(0);
+      System.out.println(model.toString());
+
+      assertTrue(model.getNameVersionId().equalsIgnoreCase("94cac189-8d88-4d63-a194-f44214e080ff"));
+      assertTrue(model.getType().toString().equalsIgnoreCase("NAMED_QUERY"));
+      assertTrue(model.getDependentModelIds().size() == 4);
+      assertTrue(model.getDependentModelIds().contains("d09dd9da-0148-46cd-a947-591afc844d24"));
+      assertTrue(model.getDependentModelIds().contains("997fc7-fca1-451f-b953-9a1e6197b4d6"));
+      assertTrue(model.getDependentModelIds().contains("897df7ea-8938-42b0-bc57-46e913a4d93b"));
+      assertTrue(model.getDependentModelIds().contains("f2b24d95-c582-48d5-b2d6-c5b3a94ce812"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+  }
+}
diff --git a/src/test/java/org/openecomp/modelloader/entity/model/ModelSorterTest.java b/src/test/java/org/openecomp/modelloader/entity/model/ModelSorterTest.java
new file mode 100644 (file)
index 0000000..dea537f
--- /dev/null
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.entity.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+import org.openecomp.modelloader.entity.Artifact;
+
+public class ModelSorterTest {
+
+  @Test
+  public void noModels() {
+
+    List<Artifact> emptyList = Collections.emptyList();
+
+    ModelSorter sorter = new ModelSorter();
+    sorter = new ModelSorter();
+
+    List<Artifact> sortedList = sorter.sort(emptyList);
+    assertNotNull(sortedList);
+    assertEquals(0, sortedList.size());
+
+  }
+
+  @Test
+  public void singleModel() {
+
+    List<Artifact> modelList = new ArrayList<Artifact>();
+
+    ModelArtifact model = new ModelArtifact();
+    model.setNameVersionId("aaaaa");
+    model.addDependentModelId("xyz");
+    modelList.add(model);
+
+    ModelSorter sorter = new ModelSorter();
+    sorter = new ModelSorter();
+
+    List<Artifact> sortedList = sorter.sort(modelList);
+    assertNotNull(sortedList);
+    assertEquals(1, sortedList.size());
+
+  }
+
+  /**
+   * 
+   * depends on depends on B ------> A -------> C
+   *
+   *
+   * Input list = a, b, c Sorted list = c, a, b
+   *
+   */
+  @Test
+  public void multipleModels() {
+
+    List<Artifact> modelList = new ArrayList<Artifact>();
+
+    ModelArtifact aaaa = new ModelArtifact();
+    aaaa.setNameVersionId("aaaa");
+    aaaa.addDependentModelId("cccc");
+
+    ModelArtifact bbbb = new ModelArtifact();
+    bbbb.setNameVersionId("bbbb");
+    bbbb.addDependentModelId("aaaa");
+
+    ModelArtifact cccc = new ModelArtifact();
+    cccc.setNameVersionId("cccc");
+
+    modelList.add(aaaa);
+    modelList.add(bbbb);
+    modelList.add(cccc);
+
+    ModelSorter sorter = new ModelSorter();
+    sorter = new ModelSorter();
+
+    List<Artifact> sortedList = sorter.sort(modelList);
+    assertNotNull(sortedList);
+    assertEquals(3, sortedList.size());
+
+    assertEquals(cccc, sortedList.get(0));
+    assertEquals(aaaa, sortedList.get(1));
+    assertEquals(bbbb, sortedList.get(2));
+  }
+
+  @Test(expected = RuntimeException.class)
+  public void circularDependency() {
+
+    List<Artifact> modelList = new ArrayList<Artifact>();
+
+    ModelArtifact aaaa = new ModelArtifact();
+    aaaa.setNameVersionId("aaaa");
+    aaaa.addDependentModelId("bbbb");
+
+    ModelArtifact bbbb = new ModelArtifact();
+    bbbb.setNameVersionId("bbbb");
+    bbbb.addDependentModelId("aaaa");
+
+    modelList.add(aaaa);
+    modelList.add(bbbb);
+
+    ModelSorter sorter = new ModelSorter();
+    sorter = new ModelSorter();
+
+    List<Artifact> sortedList = sorter.sort(modelList);
+    assertNotNull(sortedList);
+    assertEquals(3, sortedList.size());
+
+  }
+
+}
diff --git a/src/test/java/org/openecomp/modelloader/restclient/AAIRestClientTest.java b/src/test/java/org/openecomp/modelloader/restclient/AAIRestClientTest.java
new file mode 100644 (file)
index 0000000..08d7afe
--- /dev/null
@@ -0,0 +1,119 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.restclient;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+import org.openecomp.modelloader.entity.ArtifactType;
+import org.openecomp.modelloader.entity.model.ModelArtifact;
+
+public class AAIRestClientTest {
+
+  // This test requires a running A&AI system. Uncomment to test locally.
+  /*
+   * @Test public void testRestClient() throws Exception { final String
+   * MODEL_FILE = "src/test/resources/models/vnf-model.xml";
+   * 
+   * Properties props = new Properties();
+   * props.setProperty("ml.distribution.ARTIFACT_TYPES",
+   * "MODEL_INVENTORY_PROFILE,MODEL_QUERY_SPEC,VNF_CATALOG");
+   * props.setProperty("ml.aai.BASE_URL", "https://127.0.0.1:4321");
+   * props.setProperty("ml.aai.MODEL_URL",
+   * "/aai/v8/service-design-and-creation/models/model/");
+   * props.setProperty("ml.aai.KEYSTORE_FILE", "aai-client-cert.p12");
+   * props.setProperty("ml.aai.KEYSTORE_PASSWORD",
+   * "OBF:1i9a1u2a1unz1lr61wn51wn11lss1unz1u301i6o");
+   * 
+   * ModelLoaderConfig config = new ModelLoaderConfig(props, "");
+   * 
+   * String payload = readFile(MODEL_FILE); System.out.println("FILE:" +
+   * payload);
+   * 
+   * File xmlFile = new File(MODEL_FILE); DocumentBuilderFactory dbFactory =
+   * DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder =
+   * dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(xmlFile);
+   * 
+   * // Get the ID of the model String modelId = null; NodeList nodeList =
+   * doc.getDocumentElement().getChildNodes(); for (int i = 0; i <
+   * nodeList.getLength(); i++) { Node currentNode = nodeList.item(i); if
+   * (currentNode.getNodeName().equals("model-name-version-id")) { modelId =
+   * currentNode.getTextContent(); break; } }
+   * 
+   * // Add the model try { ModelArtifact model = new ModelArtifact();
+   * model.setNameVersionId(modelId); model.setType(ArtifactType.MODEL);
+   * model.setPayload(payload);
+   * 
+   * AAIRestClient aaiClient = new AAIRestClient(config);
+   * 
+   * // GET model System.out.println("Calling GET API ..."); ClientResponse
+   * getResponse = aaiClient.getResource(getURL(model, config),
+   * "example-trans-id-0", AAIRestClient.MimeType.XML); System.out.println(
+   * "GET result: " + getResponse.getStatus());
+   * assertTrue(getResponse.getStatus() ==
+   * Response.Status.NOT_FOUND.getStatusCode());
+   * 
+   * // Add the model System.out.println("Calling PUT API ..."); ClientResponse
+   * res = aaiClient.putResource(getURL(model, config), model.getPayload(),
+   * "example-trans-id-1", AAIRestClient.MimeType.XML); System.out.println(
+   * "PUT result: " + res.getStatus()); assertTrue(res.getStatus() ==
+   * Response.Status.CREATED.getStatusCode());
+   * 
+   * // Delete the model System.out.println("Calling DELETE API ..."); res =
+   * aaiClient.getAndDeleteResource(getURL(model, config),
+   * "example-trans-id-3"); System.out.println("DELETE result: " +
+   * res.getStatus()); assertTrue(res.getStatus() ==
+   * Response.Status.NO_CONTENT.getStatusCode()); } catch (Exception e) {
+   * e.printStackTrace(); } }
+   */
+
+  static String readFile(String path) throws IOException {
+    byte[] encoded = Files.readAllBytes(Paths.get(path));
+    return new String(encoded);
+  }
+
+  private String getURL(ModelArtifact model, ModelLoaderConfig config) {
+    String baseURL = config.getAaiBaseUrl().trim();
+    String subURL = null;
+    if (model.getType().equals(ArtifactType.MODEL)) {
+      subURL = config.getAaiModelUrl().trim();
+    } else {
+      subURL = config.getAaiNamedQueryUrl().trim();
+    }
+
+    if ((!baseURL.endsWith("/")) && (!subURL.startsWith("/"))) {
+      baseURL = baseURL + "/";
+    }
+
+    if (baseURL.endsWith("/") && subURL.startsWith("/")) {
+      baseURL = baseURL.substring(0, baseURL.length() - 1);
+    }
+
+    if (!subURL.endsWith("/")) {
+      subURL = subURL + "/";
+    }
+
+    String url = baseURL + subURL + model.getNameVersionId();
+    return url;
+  }
+}
diff --git a/src/test/java/org/openecomp/modelloader/service/ModelLoaderServiceTest.java b/src/test/java/org/openecomp/modelloader/service/ModelLoaderServiceTest.java
new file mode 100644 (file)
index 0000000..c2893a9
--- /dev/null
@@ -0,0 +1,115 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.service;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+import org.openecomp.modelloader.notification.EventCallback;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.impl.DistributionClientFactory;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+
+@PrepareForTest({ DistributionClientFactory.class })
+@RunWith(PowerMockRunner.class)
+public class ModelLoaderServiceTest {
+
+  /*
+   * //TODO this should be re-added once we come up with a strategy to fail
+   * gracefully
+   * 
+   * @Test public void testNonExistentConfiguration(){
+   * ModelLoaderService.CONFIG_LOCATION = "FAKELOCATION";
+   * 
+   * try{ new ModelLoaderService().start(); }catch(RuntimeException e){
+   * assertTrue("Got unexpected message from error log",
+   * e.getMessage().contains("Failed to load configuration")); return; }
+   * 
+   * fail("Expecting runtime exception"); }
+   */
+
+  @Test
+  public void testConfigureStartDistributionClient() {
+    PowerMockito.mockStatic(DistributionClientFactory.class);
+
+    IDistributionClient mockClient = mock(IDistributionClient.class);
+    ModelLoaderConfig mockConfig = mock(ModelLoaderConfig.class);
+
+    when(DistributionClientFactory.createDistributionClient()).thenReturn(mockClient);
+
+    IDistributionClientResult result = mock(IDistributionClientResult.class);
+
+    when(result.getDistributionActionResult()).thenReturn(DistributionActionResultEnum.SUCCESS);
+    when(mockClient.init(Matchers.<ModelLoaderConfig> any(), Matchers.<EventCallback> any()))
+        .thenReturn(result);
+    when(mockClient.start()).thenReturn(result);
+
+    new ModelLoaderService().init();
+
+    // Validate that the client was initialized and started
+    verify(mockClient, times(1)).init(Matchers.<ModelLoaderConfig> any(),
+        Matchers.<EventCallback> any());
+    verify(mockClient, times(1)).start();
+  }
+
+  @Test
+  public void testInitializeButNotStarted() {
+    PowerMockito.mockStatic(DistributionClientFactory.class);
+
+    IDistributionClient mockClient = mock(IDistributionClient.class);
+    ModelLoaderConfig mockConfig = mock(ModelLoaderConfig.class);
+
+    DistributionActionResultEnum failureReason = DistributionActionResultEnum.ASDC_CONNECTION_FAILED;
+
+    when(DistributionClientFactory.createDistributionClient()).thenReturn(mockClient);
+
+    IDistributionClientResult initResult = mock(IDistributionClientResult.class);
+    when(initResult.getDistributionActionResult()).thenReturn(DistributionActionResultEnum.SUCCESS);
+    IDistributionClientResult startResult = mock(IDistributionClientResult.class);
+    when(startResult.getDistributionActionResult()).thenReturn(failureReason);
+
+    when(mockClient.init(Matchers.<ModelLoaderConfig> any(), Matchers.<EventCallback> any()))
+        .thenReturn(initResult);
+    when(mockClient.start()).thenReturn(startResult);
+
+    // TODO this should be re-added once we come up with a strategy to fail
+    // gracefully
+    /*
+     * try{ new ModelLoaderService().init(mockConfig); }catch(RuntimeException
+     * e){ assertTrue(e.getMessage().contains(failureReason.toString()));
+     * return; }
+     * 
+     * fail("Expecting runtime exception with failure: " +
+     * failureReason.toString());
+     */
+  }
+}
diff --git a/src/test/java/org/openecomp/modelloader/util/JsonXmlConverterTest.java b/src/test/java/org/openecomp/modelloader/util/JsonXmlConverterTest.java
new file mode 100644 (file)
index 0000000..4654c93
--- /dev/null
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * MODEL LOADER SERVICE
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.openecomp.modelloader.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class JsonXmlConverterTest {
+
+  @Test
+  public void testConversion() throws Exception {
+    final String XML_MODEL_FILE = "src/test/resources/models/vnf-model.xml";
+    final String JSON_MODEL_FILE = "src/test/resources/models/vnf-model.json";
+
+    try {
+      byte[] encoded = Files.readAllBytes(Paths.get(XML_MODEL_FILE));
+      String originalXML = new String(encoded);
+
+      assertFalse(JsonXmlConverter.isValidJson(originalXML));
+
+      encoded = Files.readAllBytes(Paths.get(JSON_MODEL_FILE));
+      String originalJSON = new String(encoded);
+
+      assertTrue(JsonXmlConverter.isValidJson(originalJSON));
+
+      String xmlFromJson = JsonXmlConverter.convertJsonToXml(originalJSON);
+
+      // Spot check one of the attributes
+      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+      DocumentBuilder builder = factory.newDocumentBuilder();
+      Document doc = builder.parse(new ByteArrayInputStream(xmlFromJson.getBytes()));
+      NodeList nodeList = doc.getDocumentElement().getChildNodes();
+
+      String modelVid = "notFound";
+      for (int i = 0; i < nodeList.getLength(); i++) {
+        Node currentNode = nodeList.item(i);
+        if (currentNode.getNodeName().equals("model-name-version-id")) {
+          modelVid = currentNode.getTextContent();
+          break;
+        }
+      }
+
+      assertTrue(modelVid.equals("model-vid"));
+    } catch (Exception e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+  }
+}
diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml
new file mode 100644 (file)
index 0000000..1252135
--- /dev/null
@@ -0,0 +1,37 @@
+<!--
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<configuration debug="false">
+
+       <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+               <!-- encoders are by default assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
+               <encoder>
+                       <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+               </encoder>
+       </appender>
+
+       <logger name="com.att.eelf" level="DEBUG" additivity="false">
+               <appender-ref ref="STDOUT" />
+       </logger>
+
+       <root level="debug">
+               <appender-ref ref="STDOUT" />
+       </root>
+</configuration>
diff --git a/src/test/resources/model-loader-empty-auth-password.properties b/src/test/resources/model-loader-empty-auth-password.properties
new file mode 100644 (file)
index 0000000..69f3da1
--- /dev/null
@@ -0,0 +1,43 @@
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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=========================================================
+###
+
+# Model Loader Distribution Client Configuration
+ml.distribution.ACTIVE_SERVER_TLS_AUTH=false
+ml.distribution.ASDC_ADDRESS=
+ml.distribution.CONSUMER_GROUP=aai-ml-group-test
+ml.distribution.CONSUMER_ID=aai-ml-id-test
+ml.distribution.ENVIRONMENT_NAME=
+ml.distribution.KEYSTORE_PASSWORD=
+ml.distribution.KEYSTORE_FILE=asdc-client.jks
+ml.distribution.PASSWORD=
+ml.distribution.POLLING_INTERVAL=30
+ml.distribution.POLLING_TIMEOUT=20
+ml.distribution.USER=ci
+ml.distribution.ARTIFACT_TYPES=MODEL_INVENTORY_PROFILE,MODEL_QUERY_SPEC,VNF_CATALOG
+
+# Model Loader AAI REST Client Configuration
+ml.aai.BASE_URL=
+ml.aai.MODEL_URL=/aai/v8/service-design-and-creation/models/model/
+ml.aai.NAMED_QUERY_URL=/aai/v8/service-design-and-creation/named-queries/named-query/
+ml.aai.VNF_IMAGE_URL=/aai/v8/service-design-and-creation/vnf-images
+ml.aai.KEYSTORE_FILE=aai-client-cert.p12
+ml.aai.KEYSTORE_PASSWORD=
+ml.aai.AUTH_USER=ModelLoader
+ml.aai.AUTH_PASSWORD=
diff --git a/src/test/resources/model-loader-no-auth-password.properties b/src/test/resources/model-loader-no-auth-password.properties
new file mode 100644 (file)
index 0000000..8d59db1
--- /dev/null
@@ -0,0 +1,41 @@
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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=========================================================
+###
+
+# Model Loader Distribution Client Configuration
+ml.distribution.ACTIVE_SERVER_TLS_AUTH=false
+ml.distribution.ASDC_ADDRESS=
+ml.distribution.CONSUMER_GROUP=aai-ml-group-test
+ml.distribution.CONSUMER_ID=aai-ml-id-test
+ml.distribution.ENVIRONMENT_NAME=
+ml.distribution.KEYSTORE_PASSWORD=
+ml.distribution.KEYSTORE_FILE=asdc-client.jks
+ml.distribution.PASSWORD=
+ml.distribution.POLLING_INTERVAL=30
+ml.distribution.POLLING_TIMEOUT=20
+ml.distribution.USER=ci
+ml.distribution.ARTIFACT_TYPES=MODEL_INVENTORY_PROFILE,MODEL_QUERY_SPEC,VNF_CATALOG
+
+# Model Loader AAI REST Client Configuration
+ml.aai.BASE_URL=
+ml.aai.MODEL_URL=/aai/v8/service-design-and-creation/models/model/
+ml.aai.NAMED_QUERY_URL=/aai/v8/service-design-and-creation/named-queries/named-query/
+ml.aai.VNF_IMAGE_URL=/aai/v8/service-design-and-creation/vnf-images
+ml.aai.KEYSTORE_FILE=aai-client-cert.p12
+ml.aai.KEYSTORE_PASSWORD=
diff --git a/src/test/resources/model-loader.properties b/src/test/resources/model-loader.properties
new file mode 100644 (file)
index 0000000..69f3da1
--- /dev/null
@@ -0,0 +1,43 @@
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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=========================================================
+###
+
+# Model Loader Distribution Client Configuration
+ml.distribution.ACTIVE_SERVER_TLS_AUTH=false
+ml.distribution.ASDC_ADDRESS=
+ml.distribution.CONSUMER_GROUP=aai-ml-group-test
+ml.distribution.CONSUMER_ID=aai-ml-id-test
+ml.distribution.ENVIRONMENT_NAME=
+ml.distribution.KEYSTORE_PASSWORD=
+ml.distribution.KEYSTORE_FILE=asdc-client.jks
+ml.distribution.PASSWORD=
+ml.distribution.POLLING_INTERVAL=30
+ml.distribution.POLLING_TIMEOUT=20
+ml.distribution.USER=ci
+ml.distribution.ARTIFACT_TYPES=MODEL_INVENTORY_PROFILE,MODEL_QUERY_SPEC,VNF_CATALOG
+
+# Model Loader AAI REST Client Configuration
+ml.aai.BASE_URL=
+ml.aai.MODEL_URL=/aai/v8/service-design-and-creation/models/model/
+ml.aai.NAMED_QUERY_URL=/aai/v8/service-design-and-creation/named-queries/named-query/
+ml.aai.VNF_IMAGE_URL=/aai/v8/service-design-and-creation/vnf-images
+ml.aai.KEYSTORE_FILE=aai-client-cert.p12
+ml.aai.KEYSTORE_PASSWORD=
+ml.aai.AUTH_USER=ModelLoader
+ml.aai.AUTH_PASSWORD=
diff --git a/src/test/resources/models/complete-model.xml b/src/test/resources/models/complete-model.xml
new file mode 100644 (file)
index 0000000..f6aaf1e
--- /dev/null
@@ -0,0 +1,500 @@
+<!--
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<models xmlns="http://org.openecomp.aai.inventory/v7">
+       <model>
+               <model-name-version-id>997fc7-fca1-451f-b953-9a1e6197b4d6
+               </model-name-version-id>
+               <model-type>widget</model-type>
+               <model-name>vdc</model-name>
+               <model-id>897df7ea-8938-42b0-bc57-46e913a4d93b</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175188</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/ccb3a5a4-1722-4213-8785-2b6b5527d453/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>ccb3a5a4-1722-4213-8785-2b6b5527d453
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>df2e4cc0-18ca-4046-9c1b-2abec86a58d6
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>93d9d45d-7eec-4371-9083-675e4c353de3
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>8da97b81-e0e9-4157-a4cd-af3ba52871d6
+               </model-name-version-id>
+               <model-type>resource</model-type>
+               <model-name>vDbe</model-name>
+               <model-id>77b83c95-7707-4624-8bfe-9110b9c2dc88</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175188</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/fc3a2260-d0ee-4c8e-b7e9-74791d7c5721/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>fc3a2260-d0ee-4c8e-b7e9-74791d7c5721
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>element-choice-set.element-choice-set-uuid
+                                       </relationship-key>
+                                       <relationship-value>646ee687-1475-419d-bd10-f3760d5430dc
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>constrained-element-set.constrained-element-set-uuid
+                                       </relationship-key>
+                                       <relationship-value>999</relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>df2e4cc0-18ca-4046-9c1b-2abec86a58d6
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>93d9d45d-7eec-4371-9083-675e4c353de3
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>d09dd9da-0148-46cd-a947-591afc844d24
+               </model-name-version-id>
+               <model-type>widget</model-type>
+               <model-name>connector</model-name>
+               <model-id>63ac2806-4d47-467f-bf9d-5a8a83a13cac</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175188</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/df2e4cc0-18ca-4046-9c1b-2abec86a58d6/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>df2e4cc0-18ca-4046-9c1b-2abec86a58d6
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>93d9d45d-7eec-4371-9083-675e4c353de3
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>93a6166f-b3d5-4f06-b4ba-aed48d009ad9
+               </model-name-version-id>
+               <model-type>widget</model-type>
+               <model-name>generic-vnf</model-name>
+               <model-id>acc6edd8-a8d4-4b93-afaa-0994068be14c</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175177</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/88a0e5fd-0254-41dc-a9d5-7a7db446f2f3/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>88a0e5fd-0254-41dc-a9d5-7a7db446f2f3
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>8da97b81-e0e9-4157-a4cd-af3ba52871d6
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/baefe75b-30f2-43d2-bd73-553f65ea1405/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>baefe75b-30f2-43d2-bd73-553f65ea1405
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>a6d9de88-4046-4b78-a59e-5691243d292a
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>759dbd4a-2473-46f3-a932-48d987c9b4a1
+               </model-name-version-id>
+               <model-type>resource</model-type>
+               <model-name>ipe</model-name>
+               <model-id>323ac9c1-b345-44a2-9d07-dd7653137705</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175188</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/746b864c-333b-4da9-806e-c70f883f8c9d/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>746b864c-333b-4da9-806e-c70f883f8c9d
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>element-choice-set.element-choice-set-uuid
+                                       </relationship-key>
+                                       <relationship-value>1c69d7dc-ddf1-4cf3-86dd-929aa886429c
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>constrained-element-set.constrained-element-set-uuid
+                                       </relationship-key>
+                                       <relationship-value>999</relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>df2e4cc0-18ca-4046-9c1b-2abec86a58d6
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>93d9d45d-7eec-4371-9083-675e4c353de3
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>93d9d45d-7eec-4371-9083-675e4c353de3
+               </model-name-version-id>
+               <model-type>service</model-type>
+               <model-name>wan-connector</model-name>
+               <model-id>e4a9901b-6c94-4e07-b8d8-b877d3df554c</model-id>
+               <model-version>v1.0</model-version>
+               <model-description>Connects a customer vpn to the border elements of
+                       an AT&amp;T product</model-description>
+               <resource-version>1463175188</resource-version>
+               <relationship-list />
+       </model>
+       <model>
+               <model-name-version-id>35be1acf-1298-48c6-a128-66850083b8bd
+               </model-name-version-id>
+               <model-type>resource</model-type>
+               <model-name>pBgf</model-name>
+               <model-id>897fb848-3b38-4d0d-a6a7-2543070fc450</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175188</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/d985355f-a162-493b-8cb9-0b5b948bb7b0/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>d985355f-a162-493b-8cb9-0b5b948bb7b0
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>element-choice-set.element-choice-set-uuid
+                                       </relationship-key>
+                                       <relationship-value>646ee687-1475-419d-bd10-f3760d5430dc
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>constrained-element-set.constrained-element-set-uuid
+                                       </relationship-key>
+                                       <relationship-value>999</relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>df2e4cc0-18ca-4046-9c1b-2abec86a58d6
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>93d9d45d-7eec-4371-9083-675e4c353de3
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>a6d9de88-4046-4b78-a59e-5691243d292a
+               </model-name-version-id>
+               <model-type>resource</model-type>
+               <model-name>vSbg</model-name>
+               <model-id>326690fa-9747-4ebd-9d9f-a5ef02943e1a</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175188</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/b989a7b6-907a-431d-b54e-262d29c45b6f/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>b989a7b6-907a-431d-b54e-262d29c45b6f
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>element-choice-set.element-choice-set-uuid
+                                       </relationship-key>
+                                       <relationship-value>646ee687-1475-419d-bd10-f3760d5430dc
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>constrained-element-set.constrained-element-set-uuid
+                                       </relationship-key>
+                                       <relationship-value>999</relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>df2e4cc0-18ca-4046-9c1b-2abec86a58d6
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>93d9d45d-7eec-4371-9083-675e4c353de3
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>ae16244f-4d29-4801-a559-e25f2db2a4c3
+               </model-name-version-id>
+               <model-type>resource</model-type>
+               <model-name>l2-bridge-for-wan-connector</model-name>
+               <model-id>9494e925-04a0-4f52-983b-36fa8f75d97e</model-id>
+               <model-version>v1.0</model-version>
+               <model-description>An l2-bridge used by a wan connector connects an
+                       ipe to a product border element</model-description>
+               <resource-version>1463175188</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/061f2f1d-d76f-4b4a-810c-1f9a452a4db3/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>061f2f1d-d76f-4b4a-810c-1f9a452a4db3
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>df2e4cc0-18ca-4046-9c1b-2abec86a58d6
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>93d9d45d-7eec-4371-9083-675e4c353de3
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>f2b24d95-c582-48d5-b2d6-c5b3a94ce812
+               </model-name-version-id>
+               <model-type>widget</model-type>
+               <model-name>pserver</model-name>
+               <model-id>a033a95f-93af-4dc6-811e-f818baf13ef1</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175178</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/5eab2693-78ec-446a-afe4-14332e348246/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>5eab2693-78ec-446a-afe4-14332e348246
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>35be1acf-1298-48c6-a128-66850083b8bd
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/f7659dac-6311-45b6-b483-60b39364a85a/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>f7659dac-6311-45b6-b483-60b39364a85a
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>759dbd4a-2473-46f3-a932-48d987c9b4a1
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>53be71b0-c689-4841-9fe6-c7fab529d310
+               </model-name-version-id>
+               <model-type>widget</model-type>
+               <model-name>p-interface</model-name>
+               <model-id>759dbd4a-2473-46f3-a932-48d987c9b4a1</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175178</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/f118b348-1231-4895-ad26-0b227253cdf0/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>f118b348-1231-4895-ad26-0b227253cdf0
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>f7659dac-6311-45b6-b483-60b39364a85a
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>759dbd4a-2473-46f3-a932-48d987c9b4a1
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>706c7e05-8faf-4258-acca-8e4cf556961d
+               </model-name-version-id>
+               <model-type>widget</model-type>
+               <model-name>l-interface</model-name>
+               <model-id>92e579cc-eb63-490f-b9eb-16b7af2660c7</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175178</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/82f1cf8a-470b-4aaa-a1eb-27b83ba8f176/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>82f1cf8a-470b-4aaa-a1eb-27b83ba8f176
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>f7659dac-6311-45b6-b483-60b39364a85a
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>759dbd4a-2473-46f3-a932-48d987c9b4a1
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+       <model>
+               <model-name-version-id>897df7ea-8938-42b0-bc57-46e913a4d93b
+               </model-name-version-id>
+               <model-type>widget</model-type>
+               <model-name>logical-link</model-name>
+               <model-id>c575bd11-6907-4b44-82d8-f55294fff63f</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175143</resource-version>
+               <relationship-list />
+       </model>
+       <model>
+               <model-name-version-id>f749dc48-4f58-4601-9d3e-605a06a0899e
+               </model-name-version-id>
+               <model-type>widget</model-type>
+               <model-name>vlan</model-name>
+               <model-id>76544264-9287-45c6-871b-6e7a456a9f32</model-id>
+               <model-version>v1.0</model-version>
+               <resource-version>1463175178</resource-version>
+               <relationship-list>
+                       <relationship>
+                               <related-to>model-element</related-to>
+                               <related-link>https://localhost:8443/aai/v7/service-design-and-creation/model-elements/model-element/fd994cef-bc62-460f-bd21-cc8c07fbccc4/
+                               </related-link>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>fd994cef-bc62-460f-bd21-cc8c07fbccc4
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model-element.model-element-uuid
+                                       </relationship-key>
+                                       <relationship-value>f7659dac-6311-45b6-b483-60b39364a85a
+                                       </relationship-value>
+                               </relationship-data>
+                               <relationship-data>
+                                       <relationship-key>model.model-name-version-id</relationship-key>
+                                       <relationship-value>759dbd4a-2473-46f3-a932-48d987c9b4a1
+                                       </relationship-value>
+                               </relationship-data>
+                       </relationship>
+               </relationship-list>
+       </model>
+</models>
diff --git a/src/test/resources/models/named-query-wan-connector.xml b/src/test/resources/models/named-query-wan-connector.xml
new file mode 100644 (file)
index 0000000..d0d5a05
--- /dev/null
@@ -0,0 +1,90 @@
+<!--
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<named-query xmlns="http://org.openecomp.aai.inventory/v7">
+       <named-query-uuid>94cac189-8d88-4d63-a194-f44214e080ff
+       </named-query-uuid>
+       <named-query-name>wan-connector</named-query-name>
+       <named-query-version>v1.0</named-query-version>
+       <description>Named Query - Wan Connector</description>
+       <named-query-elements>
+               <named-query-element>
+                       <relationship-list>
+                               <relationship>
+                                       <related-to>model</related-to>
+                                       <relationship-data>
+                                               <!-- connector -->
+                                               <relationship-key>model.model-name-version-id</relationship-key>
+                                               <relationship-value>d09dd9da-0148-46cd-a947-591afc844d24
+                                               </relationship-value>
+                                       </relationship-data>
+                               </relationship>
+                       </relationship-list>
+                       <named-query-elements>
+                               <named-query-element>
+                                       <relationship-list>
+                                               <relationship>
+                                                       <related-to>model</related-to>
+                                                       <relationship-data>
+                                                               <!-- vdc -->
+                                                               <relationship-key>model.model-name-version-id</relationship-key>
+                                                               <relationship-value>997fc7-fca1-451f-b953-9a1e6197b4d6
+                                                               </relationship-value>
+                                                       </relationship-data>
+                                               </relationship>
+                                       </relationship-list>
+                                       <named-query-elements>
+                                               <named-query-element>
+                                                       <relationship-list>
+                                                               <relationship>
+                                                                       <related-to>model</related-to>
+                                                                       <relationship-data>
+                                                                               <!-- logical-link -->
+                                                                               <relationship-key>model.model-name-version-id
+                                                                               </relationship-key>
+                                                                               <relationship-value>897df7ea-8938-42b0-bc57-46e913a4d93b
+                                                                               </relationship-value>
+                                                                       </relationship-data>
+                                                               </relationship>
+                                                       </relationship-list>
+                                                       <named-query-elements>
+                                                               <named-query-element>
+                                                                       <relationship-list>
+                                                                               <relationship>
+                                                                                       <related-to>model</related-to>
+                                                                                       <relationship-data>
+                                                                                               <!-- pserver -->
+                                                                                               <relationship-key>model.model-name-version-id
+                                                                                               </relationship-key>
+                                                                                               <relationship-value>f2b24d95-c582-48d5-b2d6-c5b3a94ce812
+                                                                                               </relationship-value>
+                                                                                       </relationship-data>
+                                                                               </relationship>
+                                                                       </relationship-list>
+                                                               </named-query-element>
+                                                       </named-query-elements>
+                                               </named-query-element>
+                                       </named-query-elements>
+                               </named-query-element>
+                       </named-query-elements>
+               </named-query-element>
+       </named-query-elements>
+</named-query>
+
diff --git a/src/test/resources/models/vnf-model.json b/src/test/resources/models/vnf-model.json
new file mode 100644 (file)
index 0000000..5bebe59
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "model": 
+  {
+    "model-name-version-id":"model-vid",
+    "model-type":"widget",
+    "model-version":"v1.0",
+    "model-id":"model-id",
+    "model-name":"generic-vnf"
+  }
+}
diff --git a/src/test/resources/models/vnf-model.xml b/src/test/resources/models/vnf-model.xml
new file mode 100644 (file)
index 0000000..616f4b9
--- /dev/null
@@ -0,0 +1,27 @@
+<!--
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<model xmlns="http://org.openecomp.aai.inventory/v7">
+       <model-id>model-id</model-id>
+       <model-type>widget</model-type>
+       <model-name>generic-vnf</model-name>
+       <model-version>v1.0</model-version>
+       <model-name-version-id>model-vid</model-name-version-id>
+</model>
diff --git a/src/test/resources/models/wan-connector-model.xml b/src/test/resources/models/wan-connector-model.xml
new file mode 100644 (file)
index 0000000..5e3ff10
--- /dev/null
@@ -0,0 +1,186 @@
+<!--
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<model xmlns="http://org.openecomp.aai.inventory/v7">
+       <model-id>e4a9901b-6c94-4e07-b8d8-b877d3df554c</model-id>
+       <model-type>service</model-type>
+       <model-name>wan-connector</model-name>
+       <model-version>v1.0</model-version>
+       <model-name-version-id>93d9d45d-7eec-4371-9083-675e4c353de3
+       </model-name-version-id>
+       <model-description>Connects a customer vpn to the border elements of an
+               AT&amp;T product</model-description>
+       <metadata>
+               <metadatum>
+                       <metaname>a</metaname>
+                       <metaval>vpn-id</metaval>
+               </metadatum>
+               <metadatum>
+                       <metaname>b</metaname>
+                       <metaval>product</metaval>
+               </metadatum>
+       </metadata>
+       <model-elements>
+               <model-element>
+                       <new-data-del-flag>true</new-data-del-flag>
+                       <cardinality>unbounded</cardinality>
+                       <relationship-list>
+                               <relationship>
+                                       <related-to>model</related-to>
+                                       <relationship-data>
+                                               <!-- connector -->
+                                               <relationship-key>model.model-name-version-id</relationship-key>
+                                               <relationship-value>d09dd9da-0148-46cd-a947-591afc844d24
+                                               </relationship-value>
+                                       </relationship-data>
+                               </relationship>
+                       </relationship-list>
+                       <model-elements>
+                               <model-element>
+                                       <new-data-del-flag>true</new-data-del-flag>
+                                       <cardinality>unbounded</cardinality>
+                                       <relationship-list>
+                                               <relationship>
+                                                       <related-to>model</related-to>
+                                                       <relationship-data>
+                                                               <!-- vdc -->
+                                                               <relationship-key>model.model-name-version-id</relationship-key>
+                                                               <relationship-value>997fc7-fca1-451f-b953-9a1e6197b4d6
+                                                               </relationship-value>
+                                                       </relationship-data>
+                                               </relationship>
+                                       </relationship-list>
+                                       <model-elements>
+                                               <model-element>
+                                                       <new-data-del-flag>true</new-data-del-flag>
+                                                       <cardinality>unbounded</cardinality>
+                                                       <relationship-list>
+                                                               <relationship>
+                                                                       <related-to>model</related-to>
+                                                                       <relationship-data>
+                                                                               <!-- l2-bridge-for-wan-connector -->
+                                                                               <relationship-key>model.model-name-version-id
+                                                                               </relationship-key>
+                                                                               <relationship-value>ae16244f-4d29-4801-a559-e25f2db2a4c3
+                                                                               </relationship-value>
+                                                                       </relationship-data>
+                                                               </relationship>
+                                                       </relationship-list>
+                                                       <model-constraint>
+                                                               <constrained-element-sets>
+                                                                       <constrained-element-set>
+                                                                               <path>logical-link</path>
+                                                                               <constrained-element-set-uuid>999
+                                                                               </constrained-element-set-uuid>
+                                                                               <constraint-type>combination</constraint-type>
+                                                                               <check-type>AND</check-type>
+                                                                               <element-choice-sets>
+                                                                                       <element-choice-set>
+                                                                                               <element-choice-set-name>A</element-choice-set-name>
+                                                                                               <cardinality>1</cardinality>
+                                                                                               <model-elements>
+                                                                                                       <model-element>
+                                                                                                               <cardinality>unbounded</cardinality>
+                                                                                                               <new-data-del-flag>false</new-data-del-flag>
+                                                                                                               <relationship-list>
+                                                                                                                       <relationship>
+                                                                                                                               <related-to>model</related-to>
+                                                                                                                               <relationship-data>
+                                                                                                                                       <!-- ipe -->
+                                                                                                                                       <relationship-key>model.model-name-version-id
+                                                                                                                                       </relationship-key>
+                                                                                                                                       <relationship-value>759dbd4a-2473-46f3-a932-48d987c9b4a1
+                                                                                                                                       </relationship-value>
+                                                                                                                               </relationship-data>
+                                                                                                                       </relationship>
+                                                                                                               </relationship-list>
+                                                                                                               <linkage-points>
+                                                                                                                       <linkage-point>l-interface|p-interface|pserver
+                                                                                                                       </linkage-point>
+                                                                                                               </linkage-points>
+                                                                                                       </model-element>
+                                                                                               </model-elements>
+                                                                                       </element-choice-set>
+                                                                                       <element-choice-set>
+                                                                                               <element-choice-set-name>B</element-choice-set-name>
+                                                                                               <cardinality>1</cardinality>
+                                                                                               <model-elements>
+                                                                                                       <model-element>
+                                                                                                               <cardinality>unbounded</cardinality>
+                                                                                                               <new-data-del-flag>false</new-data-del-flag>
+                                                                                                               <relationship-list>
+                                                                                                                       <relationship>
+                                                                                                                               <related-to>model</related-to>
+                                                                                                                               <relationship-data>
+                                                                                                                                       <!-- vDbe -->
+                                                                                                                                       <relationship-key>model.model-name-version-id
+                                                                                                                                       </relationship-key>
+                                                                                                                                       <relationship-value>8da97b81-e0e9-4157-a4cd-af3ba52871d6
+                                                                                                                                       </relationship-value>
+                                                                                                                               </relationship-data>
+                                                                                                                       </relationship>
+                                                                                                               </relationship-list>
+                                                                                                       </model-element>
+                                                                                                       <model-element>
+                                                                                                               <cardinality>unbounded</cardinality>
+                                                                                                               <new-data-del-flag>false</new-data-del-flag>
+                                                                                                               <relationship-list>
+                                                                                                                       <relationship>
+                                                                                                                               <related-to>model</related-to>
+                                                                                                                               <relationship-data>
+                                                                                                                                       <!-- vSbg -->
+                                                                                                                                       <relationship-key>model.model-name-version-id
+                                                                                                                                       </relationship-key>
+                                                                                                                                       <relationship-value>a6d9de88-4046-4b78-a59e-5691243d292a
+                                                                                                                                       </relationship-value>
+                                                                                                                               </relationship-data>
+                                                                                                                       </relationship>
+                                                                                                               </relationship-list>
+                                                                                                       </model-element>
+                                                                                                       <model-element>
+                                                                                                               <cardinality>unbounded</cardinality>
+                                                                                                               <new-data-del-flag>false</new-data-del-flag>
+                                                                                                               <relationship-list>
+                                                                                                                       <relationship>
+                                                                                                                               <related-to>model</related-to>
+                                                                                                                               <relationship-data>
+                                                                                                                                       <!-- pBgf -->
+                                                                                                                                       <relationship-key>model.model-name-version-id
+                                                                                                                                       </relationship-key>
+                                                                                                                                       <relationship-value>35be1acf-1298-48c6-a128-66850083b8bd
+                                                                                                                                       </relationship-value>
+                                                                                                                               </relationship-data>
+                                                                                                                       </relationship>
+                                                                                                               </relationship-list>
+                                                                                                       </model-element>
+                                                                                               </model-elements>
+                                                                                       </element-choice-set>
+                                                                               </element-choice-sets>
+                                                                       </constrained-element-set>
+                                                               </constrained-element-sets>
+                                                       </model-constraint>
+                                               </model-element>
+                                       </model-elements>
+                               </model-element>
+                       </model-elements>
+               </model-element>
+       </model-elements>
+</model>
+
diff --git a/src/test/resources/vnfcatalogexample.xml b/src/test/resources/vnfcatalogexample.xml
new file mode 100644 (file)
index 0000000..1557efa
--- /dev/null
@@ -0,0 +1,1878 @@
+<!--
+  ============LICENSE_START=======================================================
+  MODEL LOADER SERVICE
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<vnf-catalog>
+       <part-number-list>
+               <att-part-number>FortiGate-VM00</att-part-number>
+               <vnf-type>FW</vnf-type>
+               <vendor-info>
+                       <vendor-name>FORTINET</vendor-name>
+                       <vendor-part-number>FortiGate-VM00</vendor-part-number>
+                       <vendor-model>VM00</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>1</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>1</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>1</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>1</vmemory-min>
+                       <vmemory-max>1</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>2</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>2</vdisk-min>
+                       <vdisk-max>32</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>5.2.7</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>1c59a521885c465004456f74d003726c</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.7.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.5</software-version>
+                       <software-version-state>1</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>C4D2CBE51669796E48623E006782F7DC</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.5.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.4</software-version>
+                       <software-version-state>2</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>4987E1E743FD641C879E1D3C5D50BCE0</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.4.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>APPID</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>IPS-IDS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>URLF</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Anti-Virus</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>FortiGate-VM00</license-assignment-group>
+                       <license-required>FALSE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>FortiGate-VM01</att-part-number>
+               <vnf-type>FW</vnf-type>
+               <vendor-info>
+                       <vendor-name>FORTINET</vendor-name>
+                       <vendor-part-number>FortiGate-VM01</vendor-part-number>
+                       <vendor-model>VM01</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>1</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>1</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>2</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>1</vmemory-min>
+                       <vmemory-max>2</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>2</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>2</vdisk-min>
+                       <vdisk-max>32</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>5.2.7</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>1c59a521885c465004456f74d003726c</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.7.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.5</software-version>
+                       <software-version-state>1</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>C4D2CBE51669796E48623E006782F7DC</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.5.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.4</software-version>
+                       <software-version-state>2</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>4987E1E743FD641C879E1D3C5D50BCE0</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.4.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>APPID</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>IPS-IDS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>URLF</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Anti-Virus</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>FortiGate-VM01</license-assignment-group>
+                       <license-required>FALSE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>FortiGate-VM02</att-part-number>
+               <vnf-type>FW</vnf-type>
+               <vendor-info>
+                       <vendor-name>FORTINET</vendor-name>
+                       <vendor-part-number>FortiGate-VM02</vendor-part-number>
+                       <vendor-model>VM02</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>1</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>4</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>2</vdisk-min>
+                       <vdisk-max>32</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>5.2.7</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>1c59a521885c465004456f74d003726c</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.7.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.5</software-version>
+                       <software-version-state>1</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>C4D2CBE51669796E48623E006782F7DC</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.5.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.4</software-version>
+                       <software-version-state>2</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>4987E1E743FD641C879E1D3C5D50BCE0</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.4.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>APPID</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>IPS-IDS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>URLF</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Anti-Virus</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>FortiGate-VM02</license-assignment-group>
+                       <license-required>FALSE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>FortiGate-VM04</att-part-number>
+               <vnf-type>FW</vnf-type>
+               <vendor-info>
+                       <vendor-name>FORTINET</vendor-name>
+                       <vendor-part-number>FortiGate-VM04</vendor-part-number>
+                       <vendor-model>VM04</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>4</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>4</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>6</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>1</vmemory-min>
+                       <vmemory-max>6</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>8</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>2</vdisk-min>
+                       <vdisk-max>32</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>5.2.7</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>1c59a521885c465004456f74d003726c</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.7.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.5</software-version>
+                       <software-version-state>1</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>C4D2CBE51669796E48623E006782F7DC</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.5.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.4</software-version>
+                       <software-version-state>2</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>4987E1E743FD641C879E1D3C5D50BCE0</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.4.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>APPID</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>IPS-IDS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>URLF</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Anti-Virus</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>FortiGate-VM04</license-assignment-group>
+                       <license-required>FALSE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>FortiGate-VM08</att-part-number>
+               <vnf-type>FW</vnf-type>
+               <vendor-info>
+                       <vendor-name>FORTINET</vendor-name>
+                       <vendor-part-number>FortiGate-VM08</vendor-part-number>
+                       <vendor-model>VM08</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>8</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>8</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>12</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>1</vmemory-min>
+                       <vmemory-max>12</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>16</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>2</vdisk-min>
+                       <vdisk-max>32</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>5.2.7</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>1c59a521885c465004456f74d003726c</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.7.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.5</software-version>
+                       <software-version-state>1</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>C4D2CBE51669796E48623E006782F7DC</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.5.qcow2</software-filename>
+               </software-version-list>
+               <software-version-list>
+                       <software-version>5.2.4</software-version>
+                       <software-version-state>2</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>4987E1E743FD641C879E1D3C5D50BCE0</file-md5-value>
+                       <software-filename>fortinet-FW-IMG-5.2.4.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>APPID</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>IPS-IDS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>URLF</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Anti-Virus</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>FortiGate-VM08</license-assignment-group>
+                       <license-required>FALSE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>L-CSR-10M-APP-1Y</att-part-number>
+               <vnf-type>RT</vnf-type>
+               <vendor-info>
+                       <vendor-name>CISCO</vendor-name>
+                       <vendor-part-number>L-CSR-10M-APP-1Y</vendor-part-number>
+                       <vendor-model>L-CSR-10M-APP-1Y</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>1</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>1</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>8</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>8</vdisk-min>
+                       <vdisk-max>8</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>3.16.1aS</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <software-filename>cisco-RT-IMG-csr1000v-universalk9.03.16.01a.S.155-3.S1a-ext.qcow2</software-filename>
+                       <file-md5-value>D034E0BC74A84EFFE667113E5ABAC6E1</file-md5-value>
+               </software-version-list>
+
+               <vnf-features-list>
+                       <vnf-feature>IPv6</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NetFLOW v9</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NTP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>SNMP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>GRE Tunnel</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Border Gateway Protocol (BGP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Open Shortest Path First (OSPF)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Enhanced Interior Gateway Routing Protocol (EIGRP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NAT</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Server</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Relay</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRF-Lite</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>COS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Multicast</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>HSRP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRRP</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>L-CSR-10M-APP-1Y</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>L-CSR-50M-APP-1Y</att-part-number>
+               <vnf-type>RT</vnf-type>
+               <vendor-info>
+                       <vendor-name>CISCO</vendor-name>
+                       <vendor-part-number>L-CSR-50M-APP-1Y</vendor-part-number>
+                       <vendor-model>L-CSR-50M-APP-1Y</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>1</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>1</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>8</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>8</vdisk-min>
+                       <vdisk-max>8</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>3.16.1aS</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <software-filename>cisco-RT-IMG-csr1000v-universalk9.03.16.01a.S.155-3.S1a-ext.qcow2</software-filename>
+                       <file-md5-value>D034E0BC74A84EFFE667113E5ABAC6E1</file-md5-value>
+               </software-version-list>
+
+               <vnf-features-list>
+                       <vnf-feature>IPv6</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NetFLOW v9</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NTP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>SNMP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>GRE Tunnel</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Border Gateway Protocol (BGP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Open Shortest Path First (OSPF)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Enhanced Interior Gateway Routing Protocol (EIGRP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NAT</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Server</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Relay</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRF-Lite</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>COS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Multicast</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>HSRP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRRP</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>L-CSR-50M-APP-1Y</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>L-CSR-100M-APP-1Y</att-part-number>
+               <vnf-type>RT</vnf-type>
+               <vendor-info>
+                       <vendor-name>CISCO</vendor-name>
+                       <vendor-part-number>L-CSR-100M-APP-1Y</vendor-part-number>
+                       <vendor-model>L-CSR-100M-APP-1Y</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>1</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>1</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>8</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>8</vdisk-min>
+                       <vdisk-max>8</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>3.16.1aS</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <software-filename>cisco-RT-IMG-csr1000v-universalk9.03.16.01a.S.155-3.S1a-ext.qcow2</software-filename>
+                       <file-md5-value>D034E0BC74A84EFFE667113E5ABAC6E1</file-md5-value>
+               </software-version-list>
+
+               <vnf-features-list>
+                       <vnf-feature>IPv6</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NetFLOW v9</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NTP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>SNMP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>GRE Tunnel</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Border Gateway Protocol (BGP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Open Shortest Path First (OSPF)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Enhanced Interior Gateway Routing Protocol (EIGRP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NAT</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Server</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Relay</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRF-Lite</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>COS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Multicast</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>HSRP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRRP</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>L-CSR-100M-APP-1Y</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>L-CSR-250M-APP-1Y</att-part-number>
+               <vnf-type>RT</vnf-type>
+               <vendor-info>
+                       <vendor-name>CISCO</vendor-name>
+                       <vendor-part-number>L-CSR-250M-APP-1Y</vendor-part-number>
+                       <vendor-model>L-CSR-250M-APP-1Y</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>1</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>1</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>8</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>8</vdisk-min>
+                       <vdisk-max>8</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>3.16.1aS</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <software-filename>cisco-RT-IMG-csr1000v-universalk9.03.16.01a.S.155-3.S1a-ext.qcow2</software-filename>
+                       <file-md5-value>D034E0BC74A84EFFE667113E5ABAC6E1</file-md5-value>
+               </software-version-list>
+
+               <vnf-features-list>
+                       <vnf-feature>IPv6</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NetFLOW v9</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NTP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>SNMP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>GRE Tunnel</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Border Gateway Protocol (BGP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Open Shortest Path First (OSPF)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Enhanced Interior Gateway Routing Protocol (EIGRP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NAT</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Server</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Relay</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRF-Lite</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>COS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Multicast</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>HSRP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRRP</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>L-CSR-250M-APP-1Y</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>L-CSR-500M-APP-1Y</att-part-number>
+               <vnf-type>RT</vnf-type>
+               <vendor-info>
+                       <vendor-name>CISCO</vendor-name>
+                       <vendor-part-number>L-CSR-500M-APP-1Y</vendor-part-number>
+                       <vendor-model>L-CSR-500M-APP-1Y</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>1</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>1</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>8</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>8</vdisk-min>
+                       <vdisk-max>8</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>3.16.1aS</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <software-filename>cisco-RT-IMG-csr1000v-universalk9.03.16.01a.S.155-3.S1a-ext.qcow2</software-filename>
+                       <file-md5-value>D034E0BC74A84EFFE667113E5ABAC6E1</file-md5-value>
+               </software-version-list>
+
+               <vnf-features-list>
+                       <vnf-feature>IPv6</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NetFLOW v9</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NTP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>SNMP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>GRE Tunnel</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Border Gateway Protocol (BGP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Open Shortest Path First (OSPF)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Enhanced Interior Gateway Routing Protocol (EIGRP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NAT</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Server</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Relay</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRF-Lite</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>COS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Multicast</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>HSRP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRRP</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>L-CSR-500M-APP-1Y</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>L-CSR-1G-APP-1Y</att-part-number>
+               <vnf-type>RT</vnf-type>
+               <vendor-info>
+                       <vendor-name>CISCO</vendor-name>
+                       <vendor-part-number>L-CSR-1G-APP-1Y</vendor-part-number>
+                       <vendor-model>L-CSR-1G-APP-1Y</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>1</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>1</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>8</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>8</vdisk-min>
+                       <vdisk-max>8</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>3.16.1aS</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <software-filename>cisco-RT-IMG-csr1000v-universalk9.03.16.01a.S.155-3.S1a-ext.qcow2</software-filename>
+                       <file-md5-value>D034E0BC74A84EFFE667113E5ABAC6E1</file-md5-value>
+               </software-version-list>
+
+               <vnf-features-list>
+                       <vnf-feature>IPv6</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NetFLOW v9</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NTP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>SNMP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>GRE Tunnel</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Border Gateway Protocol (BGP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Open Shortest Path First (OSPF)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Enhanced Interior Gateway Routing Protocol (EIGRP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NAT</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Server</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Relay</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRF-Lite</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>COS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Multicast</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>HSRP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRRP</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>L-CSR-1G-APP-1Y</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>L-CSR-2.5G-APP-1Y</att-part-number>
+               <vnf-type>RT</vnf-type>
+               <vendor-info>
+                       <vendor-name>CISCO</vendor-name>
+                       <vendor-part-number>L-CSR-2.5G-APP-1Y</vendor-part-number>
+                       <vendor-model>L-CSR-2.5G-APP-1Y</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>1</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>1</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>8</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>8</vdisk-min>
+                       <vdisk-max>8</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>3.16.1aS</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <software-filename>cisco-RT-IMG-csr1000v-universalk9.03.16.01a.S.155-3.S1a-ext.qcow2</software-filename>
+                       <file-md5-value>D034E0BC74A84EFFE667113E5ABAC6E1</file-md5-value>
+               </software-version-list>
+
+               <vnf-features-list>
+                       <vnf-feature>IPv6</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NetFLOW v9</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NTP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>SNMP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>GRE Tunnel</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Border Gateway Protocol (BGP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Open Shortest Path First (OSPF)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Enhanced Interior Gateway Routing Protocol (EIGRP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NAT</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Server</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Relay</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRF-Lite</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>COS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Multicast</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>HSRP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRRP</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>L-CSR-2.5G-APP-1Y</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00255-U</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00255-U</vendor-part-number>
+                       <vendor-model>VCX-SUB-00255-U</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>2</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>2</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>50</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>50</vdisk-min>
+                       <vdisk-max>50</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00255-U</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00255-L</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00255-L</vendor-part-number>
+                       <vendor-model>VCX-SUB-00255-L</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>2</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>2</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>50</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>50</vdisk-min>
+                       <vdisk-max>50</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00255-L</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00255-M</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00255-M</vendor-part-number>
+                       <vendor-model>VCX-SUB-00255-M</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>2</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>2</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>50</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>50</vdisk-min>
+                       <vdisk-max>50</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00255-M</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00255-H</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00255-H</vendor-part-number>
+                       <vendor-model>VCX-SUB-00255-H</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>2</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>2</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>50</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>50</vdisk-min>
+                       <vdisk-max>50</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00255-H</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00555-L</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00555-L</vendor-part-number>
+                       <vendor-model>VCX-SUB-00555-L</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>80</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>80</vdisk-min>
+                       <vdisk-max>80</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00555-L</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00555-M</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00555-M</vendor-part-number>
+                       <vendor-model>VCX-SUB-00555-M</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>80</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>80</vdisk-min>
+                       <vdisk-max>80</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00555-M</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00555-H</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00555-H</vendor-part-number>
+                       <vendor-model>VCX-SUB-00555-H</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>80</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>80</vdisk-min>
+                       <vdisk-max>80</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00555-H</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00755-L</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00755-L</vendor-part-number>
+                       <vendor-model>VCX-SUB-00755-L</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>4</vcpu-default>
+                       <vcpu-min>2</vcpu-min>
+                       <vcpu-max>4</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>8</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>8</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>150</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>150</vdisk-min>
+                       <vdisk-max>150</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00755-L</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00755-M</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00755-M</vendor-part-number>
+                       <vendor-model>VCX-SUB-00755-M</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>4</vcpu-default>
+                       <vcpu-min>2</vcpu-min>
+                       <vcpu-max>4</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>8</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>8</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>150</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>150</vdisk-min>
+                       <vdisk-max>150</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00755-M</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00755-H</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00755-H</vendor-part-number>
+                       <vendor-model>VCX-SUB-00755-H</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>4</vcpu-default>
+                       <vcpu-min>2</vcpu-min>
+                       <vcpu-max>4</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>8</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>8</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>150</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>150</vdisk-min>
+                       <vdisk-max>150</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00755-H</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00255-UB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00255-UB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00255-UB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>2</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>2</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>50</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>50</vdisk-min>
+                       <vdisk-max>50</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00255-UB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00255-LB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00255-LB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00255-LB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>2</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>2</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>50</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>50</vdisk-min>
+                       <vdisk-max>50</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00255-LB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00255-MB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00255-MB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00255-MB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>2</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>2</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>50</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>50</vdisk-min>
+                       <vdisk-max>50</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00255-MB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00255-HB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00255-HB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00255-HB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>2</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>2</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>50</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>50</vdisk-min>
+                       <vdisk-max>50</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00255-HB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00555-LB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00555-LB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00555-LB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>80</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>80</vdisk-min>
+                       <vdisk-max>80</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00555-LB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00555-MB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00555-MB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00555-MB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>80</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>80</vdisk-min>
+                       <vdisk-max>80</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00555-MB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00555-HB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00555-HB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00555-HB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>1</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>2</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>80</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>80</vdisk-min>
+                       <vdisk-max>80</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00555-HB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00755-LB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00755-LB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00755-LB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>4</vcpu-default>
+                       <vcpu-min>2</vcpu-min>
+                       <vcpu-max>4</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>8</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>8</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>150</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>150</vdisk-min>
+                       <vdisk-max>150</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00755-LB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00755-MB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00755-MB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00755-MB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>4</vcpu-default>
+                       <vcpu-min>2</vcpu-min>
+                       <vcpu-max>4</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>8</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>8</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>150</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>150</vdisk-min>
+                       <vdisk-max>150</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00755-MB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>VCX-SUB-00755-HB</att-part-number>
+               <vnf-type>WX</vnf-type>
+               <vendor-info>
+                       <vendor-name>RIVERBED</vendor-name>
+                       <vendor-part-number>VCX-SUB-00755-HB</vendor-part-number>
+                       <vendor-model>VCX-SUB-00755-HB</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>4</vcpu-default>
+                       <vcpu-min>2</vcpu-min>
+                       <vcpu-max>4</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>8</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>8</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>150</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>150</vdisk-min>
+                       <vdisk-max>150</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>9.2.0</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <file-md5-value>386CF5D3482F068EC9C480B51F6BCE42</file-md5-value>
+                       <software-filename>riverbed-WX-IMG-9.2.0.qcow2</software-filename>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>TCP OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>APPLICATION OPTIMIZATION</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>VCX-SUB-00755-HB</license-assignment-group>
+                       <license-required>TRUE</license-required>
+               </license-list>
+       </part-number-list>
+       <part-number-list>
+               <att-part-number>JUN-vSRX-15X</att-part-number>
+               <vnf-type>RT</vnf-type>
+               <vendor-info>
+                       <vendor-name>JUNIPER</vendor-name>
+                       <vendor-part-number>JUN-vSRX-15X</vendor-part-number>
+                       <vendor-model>VSRX</vendor-model>
+               </vendor-info>
+               <vcpu>
+                       <vcpu-default>2</vcpu-default>
+                       <vcpu-min>2</vcpu-min>
+                       <vcpu-max>2</vcpu-max>
+               </vcpu>
+               <vmemory>
+                       <vmemory-default>4</vmemory-default>
+                       <vmemory-units>GB</vmemory-units>
+                       <vmemory-min>4</vmemory-min>
+                       <vmemory-max>4</vmemory-max>
+               </vmemory>
+               <vdisk>
+                       <vdisk-default>8</vdisk-default>
+                       <vdisk-units>GB</vdisk-units>
+                       <vdisk-min>8</vdisk-min>
+                       <vdisk-max>8</vdisk-max>
+               </vdisk>
+               <software-version-list>
+                       <software-version>15.1X49-D40.6</software-version>
+                       <software-version-state>0</software-version-state>
+                       <software-filetype>IMAGE</software-filetype>
+                       <software-filename>media-vsrx-vmdisk-15.1X49-D40.6.qcow2</software-filename>
+                       <file-md5-value>4b874dbd75fc83dc2494b90b2012d514</file-md5-value>
+               </software-version-list>
+               <vnf-features-list>
+                       <vnf-feature>IPv6</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NetFLOW v9</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NTP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>SNMP</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>GRE Tunnel</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Border Gateway Protocol (BGP)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Open Shortest Path First (OSPF)</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>NAT</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Server</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>DHCP Relay</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRF-Lite</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>COS</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>Multicast</vnf-feature>
+               </vnf-features-list>
+               <vnf-features-list>
+                       <vnf-feature>VRRP</vnf-feature>
+               </vnf-features-list>
+               <license-list>
+                       <license-assignment-group>JUN-vSRX-15X</license-assignment-group>
+                       <license-required>FALSE</license-required>
+               </license-list>
+       </part-number-list>
+</vnf-catalog>