diff options
430 files changed, 60541 insertions, 11 deletions
diff --git a/.gitignore b/.gitignore new file mode 100755 index 000000000..42cca13bb --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +#####standard .git ignore entries##### + +## IDE Specific Files ## +org.eclipse.core.resources.prefs +.classpath +.project +.settings +.idea +.externalToolBuilders +maven-eclipse.xml +workspace +.checkstyle +.vscode + +## Compilation Files ## +*.class +**/target +target +target-ide +MANIFEST.MF + +## Misc Ignores (OS specific etc) ## +bin/ +dist +*~ +*.ipr +*.iml +*.iws +classes +out/ +.DS_STORE +.metadata +.vscode +provider/src/main/java/META-INF/ +provider/src/main/java/inventory/ +logs/ +debug-logs/ +*.log +*.versionsBackup + +## BlackDuck generated file +ccsdk-adaptors_bdio.jsonld +blackDuckHubProjectName.txt +blackDuckHubProjectVersionName.txt + +#Generated dependencies list +direct-dependencies.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 000000000..3ea5081a0 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +/* + * ============LICENSE_START========================================== + * =================================================================== + * Copyright © 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============================================ + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + * + */ diff --git a/README.md b/README.md new file mode 100644 index 000000000..c906c67da --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +This source repository contains the code for the SDN Controller adaptors. +To compile this code: + +1. Make sure your local Maven settings file ($HOME/.m2/settings.xml) contains references to the ONAP repositories and OpenDaylight repositories. See example-settings.xml for an example. + +2. To compile, run "mvn clean install". + + diff --git a/aai-service/.gitignore b/aai-service/.gitignore new file mode 100755 index 000000000..e9143ef85 --- /dev/null +++ b/aai-service/.gitignore @@ -0,0 +1,35 @@ +#####standard .git ignore entries##### + +## IDE Specific Files ## +org.eclipse.core.resources.prefs +.classpath +.project +.settings +.idea +.externalToolBuilders +maven-eclipse.xml +workspace + +## Compilation Files ## +*.class +**/target +target +target-ide +MANIFEST.MF +AutoGenerated*.txt + +## Misc Ignores (OS specific etc) ## +bin/ +dist +*~ +*.ipr +*.iml +*.iws +classes +out/ +.DS_STORE +.metadata + +## Folders which contain auto generated source code ## +yang-gen-config +yang-gen-sal diff --git a/aai-service/README.md b/aai-service/README.md new file mode 100755 index 000000000..e69de29bb --- /dev/null +++ b/aai-service/README.md diff --git a/aai-service/installer/pom.xml b/aai-service/installer/pom.xml new file mode 100755 index 000000000..591e9bc20 --- /dev/null +++ b/aai-service/installer/pom.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>aai-service-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: aai-service :: ${project.artifactId}</name> + + <properties> + <application.name>ccsdk-aai-service</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>${application.name}</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + <version>${project.version}</version> + </dependency> + + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>org.onap.ccsdk.sli.adaptors,org.jvnet.jaxb2_commons</includeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/aai-service/installer/src/assembly/assemble_installer_zip.xml b/aai-service/installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..b6fd65582 --- /dev/null +++ b/aai-service/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>installer_zip</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/aai-service/installer/src/assembly/assemble_mvnrepo_zip.xml b/aai-service/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..9cdc78879 --- /dev/null +++ b/aai-service/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,49 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/aai-service/installer/src/main/resources/scripts/install-feature.sh b/aai-service/installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..0eab001d5 --- /dev/null +++ b/aai-service/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/aai-service/pom.xml b/aai-service/pom.xml new file mode 100755 index 000000000..322291043 --- /dev/null +++ b/aai-service/pom.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>aai-service</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: aai-service</name> + <description>The AAI Interface service exposes an interface to AAI as an OSGi service</description> + + <modules> + <module>provider</module> + <module>installer</module> + </modules> +</project> diff --git a/aai-service/provider/pom.xml b/aai-service/provider/pom.xml new file mode 100755 index 000000000..ca3fda288 --- /dev/null +++ b/aai-service/provider/pom.xml @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-adaptors :: aai-service :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-core-artifacts</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <scope>provided</scope> + </dependency> + <!-- let filters project deliver this to the karaf container --> + <dependency> + <groupId>org.onap.logging-analytics</groupId> + <artifactId>logging-filter-base</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.module</groupId> + <artifactId>jackson-module-jaxb-annotations</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + <dependency> + <groupId>org.jsoup</groupId> + <artifactId>jsoup</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.jvnet.jaxb2.maven2</groupId> + <artifactId>maven-jaxb2-plugin</artifactId> + <version>0.14.0</version> + <executions> + <execution> + <id>gen-xjc</id> + <goals> + <goal>generate</goal> + </goals> + </execution> + </executions> + <configuration> + <schemaDirectory>${project.basedir}/src/main/resources</schemaDirectory> + <schemaIncludes> + <value>aai_schema_v21.xsd</value> + </schemaIncludes> + <bindingIncludes> + <include>aai-schema-bindings.xjb</include> + </bindingIncludes> + <generateDirectory>${project.build.directory}/generated-sources/main/java</generateDirectory> + <generatePackage>org.onap.aai.inventory.v21</generatePackage> + <extension>true</extension> + <args> + <arg>-Xannotate</arg> + </args> + <plugins> + <plugin> + <groupId>org.jvnet.jaxb2_commons</groupId> + <artifactId>jaxb2-basics-annotate</artifactId> + <version>0.6.5</version> + </plugin> + </plugins> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIClient.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIClient.java new file mode 100755 index 000000000..5390d45de --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIClient.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * Modifications Copyright © 2018 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Map; + +import org.onap.aai.inventory.v21.*; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.onap.ccsdk.sli.adaptors.aai.data.notify.NotifyEvent; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +public interface AAIClient extends SvcLogicResource, SvcLogicJavaPlugin { + + public SearchResults requestServiceInstanceURL(String svcInstanceId) throws AAIServiceException; + + // VServers + public Vserver requestVServerData(String tenantId, String vserverId, String cloudOwner, String cloudRegionId) throws AAIServiceException; + + public URL requestVserverURLNodeQuery(String vserverName) throws AAIServiceException; + public String getTenantIdFromVserverUrl(URL url); + public String getCloudOwnerFromVserverUrl(URL url); + public String getCloudRegionFromVserverUrl(URL url); + public String getVServerIdFromVserverUrl(URL url, String tennantId); + public Vserver requestVServerDataByURL(URL url) throws AAIServiceException; + + + + // ----------------- Release 1510 ---------------------- + // // GenericVNF + public GenericVnf requestGenericVnfData(String vnfId) throws AAIServiceException; + public boolean postGenericVnfData(String vnfId, GenericVnf request) throws AAIServiceException; + + // Physical Link + public PhysicalLink requestPhysicalLinkData(String vnfId) throws AAIServiceException; + public boolean postPhysicalLinkData(String vnfId, PhysicalLink request) throws AAIServiceException; + public boolean deletePhysicalLinkData(String vnfId, String resourceVersion) throws AAIServiceException; + + // UBB Notify + public boolean sendNotify(NotifyEvent event, String serviceInstanceId, String pathCode) throws AAIServiceException; + + // Node Query - 1602 + public SearchResults requestNodeQuery(String type, String entityIdentifier, String entityName) throws AAIServiceException; + public String requestDataByURL(URL url) throws AAIServiceException; + public GenericVnf requestGenericVnfeNodeQuery(String vnfName) throws AAIServiceException; + + public QueryStatus backup(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException; + public QueryStatus restore(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException; + + public void logKeyError(String keys); + + public QueryStatus processResponseData(String rv, String resource, AAIRequest request, String prefix, SvcLogicContext ctx, Map<String, String> nameValues, String modifier) throws JsonParseException, JsonMappingException, IOException, AAIServiceException ; + public String getPathTemplateForResource(String resoourceName, String join, SvcLogicContext ctx) throws MalformedURLException; + public boolean isDeprecatedFormat(String resource, Map<String, String> nameValues); + + String query(AAIRequest request) throws AAIServiceException; + String save(AAIRequest request) throws AAIServiceException; + boolean delete(AAIRequest request, String resourceVersion) throws AAIServiceException; + boolean update(AAIRequest request, String resourceVersion) throws AAIServiceException; + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIClientRESTExecutor.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIClientRESTExecutor.java new file mode 100755 index 000000000..446ec4b6a --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIClientRESTExecutor.java @@ -0,0 +1,781 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; +import java.util.Properties; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; + +import org.apache.commons.codec.binary.Base64; +import org.onap.ccsdk.sli.adaptors.aai.AAIService.TransactionIdTracker; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.ccsdk.sli.adaptors.aai.data.ErrorResponse; +import org.onap.ccsdk.sli.adaptors.aai.data.RequestError; +import org.onap.ccsdk.sli.adaptors.aai.data.ResourceVersion; +import org.onap.ccsdk.sli.adaptors.aai.data.ServiceException; +import org.onap.ccsdk.sli.core.sli.MetricLogger; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.impl.EnglishReasonPhraseCatalog; + +/** + * The AAIClientRESTExecutor class provides CRUD API for AAI Client service. + * @author Rich Tabedzki + */ +public class AAIClientRESTExecutor implements AAIExecutorInterface { + + private final String truststorePath; + private final String truststorePassword; + private final String keystorePath; + private final String keystorePassword; + private final Boolean ignoreCertificateHostError; + // authentication credentials + private String userName; + private String userPassword; + private final String applicationId; + private static final String HTTP_URL_CONNECTION_RESULT="HttpURLConnection result: {} : {}"; + private static final String ENTRY_DOESNT_EXIST="Entry does not exist."; + + /** + * class Constructor + * @param props - properties to initialize an instance. + */ + public AAIClientRESTExecutor(Properties props) { + super(); + + userName = props.getProperty(AAIService.CLIENT_NAME); + userPassword = props.getProperty(AAIService.CLIENT_PWWD); + + if(userName == null || userName.isEmpty()){ + LOG.debug("Basic user name is not set"); + } + if(userPassword == null || userPassword.isEmpty()) { + LOG.debug("Basic password is not set"); + } + + truststorePath = props.getProperty(AAIService.TRUSTSTORE_PATH); + truststorePassword = props.getProperty(AAIService.TRUSTSTORE_PSSWD); + keystorePath = props.getProperty(AAIService.KEYSTORE_PATH); + keystorePassword = props.getProperty(AAIService.KEYSTORE_PSSWD); + + String tmpApplicationId =props.getProperty(AAIService.APPLICATION_ID); + if(tmpApplicationId == null || tmpApplicationId.isEmpty()) { + tmpApplicationId = "SDNC"; + } + applicationId = tmpApplicationId; + + String iche = props.getProperty(AAIService.CERTIFICATE_HOST_ERROR); + boolean host_error = false; + if(iche != null && !iche.isEmpty()) { + host_error = Boolean.valueOf(iche); + } + + ignoreCertificateHostError = host_error; + + HttpsURLConnection.setDefaultHostnameVerifier( (String string,SSLSession ssls) -> { + return ignoreCertificateHostError; + + }); + + if(truststorePath != null && truststorePassword != null && (new File(truststorePath)).exists()) { + System.setProperty("javax.net.ssl.trustStore", truststorePath); + System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword); + } + + if(keystorePath != null && keystorePassword != null && (new File(keystorePath)).exists()) + { + //both jersey and HttpURLConnection can use this + SSLContext ctx = null; + try { + ctx = SSLContext.getInstance("TLS"); + + KeyManagerFactory kmf = null; + try (FileInputStream fin = new FileInputStream(keystorePath)){ + String storeType = "PKCS12"; + String def = KeyStore.getDefaultType(); + kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + + String extension = keystorePath.substring(keystorePath.lastIndexOf(".") + 1); + + if(extension != null && !extension.isEmpty() && "JKS".equalsIgnoreCase(extension)) { + storeType = "JKS"; + } + KeyStore ks = KeyStore.getInstance(storeType); + + char[] pwd = keystorePassword.toCharArray(); + ks.load(fin, pwd); + kmf.init(ks, pwd); + } catch (Exception ex) { + LOG.error("AAIResource", ex); + } + + ctx.init(kmf.getKeyManagers(), null, null); + + CTX = ctx; + LOG.debug("SSLContext created"); + + } catch (KeyManagementException | NoSuchAlgorithmException exc) { + LOG.error("AAIResource", exc); + } + } + + try { + Field methodsField = HttpURLConnection.class.getDeclaredField("methods"); + methodsField.setAccessible(true); + // get the methods field modifiers + Field modifiersField = Field.class.getDeclaredField("modifiers"); + // bypass the "private" modifier + modifiersField.setAccessible(true); + + // remove the "final" modifier + modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL); + + /* valid HTTP methods */ + String[] methods = { + "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH" + }; + // set the new methods - including patch + methodsField.set(null, methods); + + } catch (SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchFieldException e) { + LOG.warn("Adding PATCH method", e); + } + LOG.info("AAIResource.ctor initialized."); + + } + + private static final Logger LOG = LoggerFactory.getLogger(AAIService.class); + private static final String NOT_PROVIDED = "NOT PROVIDED"; + private final MetricLogger ml = new MetricLogger(); + + private SSLContext CTX; + + + private int connection_timeout = 300000; + + private int read_timeout = 300000; + + /** + * Returns an String that contains JSON data returned from the AAI Server. + * <p> + * This method always returns immediately, whether or not the + * data exists. + * + * @param request an instance of AAIRequiest representing + * the request made by DirectedGraph node. + * @return the JSON based representation of data instance requested. + * @see String + */ + @Override + public String get(AAIRequest request) throws AAIServiceException { + String response = null; + InputStream inputStream = null; + HttpURLConnection con = null; + URL requestUrl = null; + + StringBuilder errorStringBuilder = new StringBuilder(); + + try { + + if(request.getRequestObject() != null) { + requestUrl = request.getRequestUrl(HttpMethod.POST, null); + requestUrl = appendDepth(requestUrl, request); + con = getConfiguredConnection(requestUrl, HttpMethod.POST); + String json_text = request.toJSONString(); + LOGwriteDateTrace("data", json_text); + logMetricRequest("POST "+requestUrl.getPath(), json_text, requestUrl.getPath()); + OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream()); + osw.write(json_text); + osw.flush(); + } else { + requestUrl = request.getRequestUrl(HttpMethod.GET, null); + requestUrl = appendDepth(requestUrl, request); + con = getConfiguredConnection(requestUrl, HttpMethod.GET); + logMetricRequest("GET "+requestUrl.getPath(), "", requestUrl.getPath()); + } + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + String responseMessage = null; + try { + responseMessage = con.getResponseMessage(); + } catch(Exception exc) { + responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null); + } finally { + if(responseMessage == null) + responseMessage = NOT_PROVIDED; + } + + // Process the response + LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage); + logMetricResponse(responseCode, responseMessage); + + if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); + BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ); + + ObjectMapper mapper = AAIService.getObjectMapper(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + StringBuilder stringBuilder = new StringBuilder(); + String line = null; + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append( line ); + } + response = stringBuilder.toString(); + try { + Object object = mapper.readValue(response, Object.class); + LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(object)); + } catch(Exception exc) { + LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, responseMessage, mapper.writeValueAsString(response)); + } + } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) { + LOGwriteEndingTrace(responseCode, responseMessage, ENTRY_DOESNT_EXIST); + ErrorResponse errorresponse = null; + try { + errorresponse = mapper.readValue(reader, ErrorResponse.class); + } catch(Exception exc) { + errorresponse = new ErrorResponse(); + RequestError requestError = new RequestError(); + ServiceException serviceException = new ServiceException(); + serviceException.setText(ENTRY_DOESNT_EXIST); + requestError.setServiceException(serviceException); + errorresponse.setRequestError(requestError ); + } + throw new AAIServiceException(responseCode, errorresponse); + } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { + StringBuilder stringBuilder = new StringBuilder(); + String line = null; + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append( line ); + } + LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString()); + ServiceException serviceException = new ServiceException(); + serviceException.setMessageId("HTTP_UNAUTHORIZED"); + serviceException.setText(stringBuilder.toString()); + RequestError requestError = new RequestError(); + requestError.setServiceException(serviceException); + ErrorResponse errorresponse = new ErrorResponse(); + errorresponse.setRequestError(requestError); + throw new AAIServiceException(responseCode, errorresponse); + } else { + String line = null; + while( ( line = reader.readLine() ) != null ) { + errorStringBuilder.append("\n").append( line ); + } + + ErrorResponse errorresponse = mapper.readValue(errorStringBuilder.toString(), ErrorResponse.class); + LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse)); + throw new AAIServiceException(responseCode, errorresponse); + } + + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn(errorStringBuilder.toString(), exc); + throw new AAIServiceException(exc); + } finally { + if(inputStream != null){ + try { + inputStream.close(); + } catch(Exception exc) { + LOG.warn("", exc); + } + } + } + return response; + } + + /** + * Returns an String that contains JSON data returned from the AAI Server. + * <p> + * This method always returns immediately, whether or not the + * data exists. + * + * @param request an instance of AAIRequiest representing + * the request made by DirectedGraph node. + * @return the JSON based representation of data instance requested. + * @see String + */ + @Override + public String post(AAIRequest request) throws AAIServiceException { + InputStream inputStream = null; + + try { + String resourceVersion = null; + AAIDatum instance = request.getRequestObject(); + + try { + Method getResourceVersionMethod = instance.getClass().getMethod("getResourceVersion"); + if(getResourceVersionMethod != null){ + try { + Object object = getResourceVersionMethod.invoke(instance); + if(object != null) + resourceVersion = object.toString(); + } catch (InvocationTargetException exc) { + LOG.warn("", exc); + } + } + } catch(Exception exc) { + LOG.error("", exc); + } + + URL requestUrl = request.getRequestUrl(HttpMethod.PUT, resourceVersion); + HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.PUT); + ObjectMapper mapper = AAIService.getObjectMapper(); + String jsonText = request.toJSONString(); + + LOGwriteDateTrace("data", jsonText); + logMetricRequest("PUT "+requestUrl.getPath(), jsonText, requestUrl.getPath()); + + OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream()); + osw.write(jsonText); + osw.flush(); + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + String responseMessage = null; + try { + responseMessage = con.getResponseMessage(); + } catch(Exception exc) { + responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null); + } finally { + if(responseMessage == null) + responseMessage = NOT_PROVIDED; + } + + LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage); + logMetricResponse(responseCode, responseMessage); + + // Process the response + BufferedReader reader; + String line = null; + reader = new BufferedReader( new InputStreamReader( inputStream ) ); + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + StringBuilder stringBuilder = new StringBuilder(); + + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append( line ); + } + LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}"); + return stringBuilder.toString(); + } else { + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse)); + + throw new AAIServiceException(responseCode, errorresponse); + } + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("AAIRequestExecutor.post", exc); + throw new AAIServiceException(exc); + } finally { + try { + if(inputStream != null) + inputStream.close(); + } catch (Exception exc) { + LOG.warn("AAIRequestExecutor.post", exc); + } + } + } + + /** + * Returns Boolean that contains completion state of the command executed. + * <p> + * This method always returns immediately, whether or not the + * data exists. + * + * @param request an instance of AAIRequiest representing + * @param resourceVersion a resource version of the data instacne to be deleted. + * the request made by DirectedGraph node. + * @return completion state of the command. + * @see String + */ + @Override + public Boolean delete(AAIRequest request, String resourceVersion) throws AAIServiceException { + Boolean response = null; + InputStream inputStream = null; + + if(resourceVersion == null) { + throw new AAIServiceException("resource-version is required for DELETE request"); + } + + try { + URL requestUrl = request.getRequestUrl(HttpMethod.DELETE, resourceVersion); + HttpURLConnection conn = getConfiguredConnection(requestUrl, HttpMethod.DELETE); + logMetricRequest("DELETE "+requestUrl.getPath(), "", requestUrl.getPath()); + conn.setDoOutput(true); + + // Check for errors + int responseCode = conn.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + inputStream = conn.getInputStream(); + } else { + inputStream = conn.getErrorStream(); + } + String responseMessage = null; + try { + responseMessage = conn.getResponseMessage(); + } catch(Exception exc) { + responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null); + } finally { + if(responseMessage == null) + responseMessage = NOT_PROVIDED; + } + + // Process the response + LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage); + logMetricResponse(responseCode, responseMessage); + + if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); + BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ); + String line = null; + + ObjectMapper mapper = AAIService.getObjectMapper(); + + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + StringBuilder stringBuilder = new StringBuilder(); + + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append( line ); + } + LOGwriteEndingTrace(responseCode, responseMessage, stringBuilder.toString()); + response = true; + } else if(responseCode == HttpURLConnection.HTTP_NOT_FOUND ) { + LOGwriteEndingTrace(responseCode, responseMessage, ENTRY_DOESNT_EXIST); + response = false; + } else { + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse)); + throw new AAIServiceException(responseCode, errorresponse); + } + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("delete", exc); + throw new AAIServiceException(exc); + } finally { + if(inputStream != null){ + try { + inputStream.close(); + } catch(Exception exc) { + LOG.warn("delete", exc); + } + } + } + return response; + } + + /** + * Returns an String that contains JSON data returned from the AAI Server. + * <p> + * This method always returns immediately, whether or not the + * data exists. + * + * @param request an instance of AAIRequiest representing + * the request made by DirectedGraph node. + * @param clas an definition of the class for which data will be returned + * @return the instance of the class with data. + * @see String + */ + @Override + public Object query(AAIRequest request, Class clas) throws AAIServiceException { + Object response = null; + InputStream inputStream = null; + + try { + URL requestUrl = request.getRequestQueryUrl(HttpMethod.GET); + HttpURLConnection con = getConfiguredConnection(requestUrl, HttpMethod.GET); + logMetricRequest("GET "+requestUrl.getPath(), "", requestUrl.getPath()); + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + String responseMessage = null; + try { + responseMessage = con.getResponseMessage(); + } catch(Exception exc) { + responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null); + } finally { + if(responseMessage == null) + responseMessage = NOT_PROVIDED; + } + + LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage); + logMetricResponse(responseCode, responseMessage); + ObjectMapper mapper = AAIService.getObjectMapper(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + // Process the response + BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ); + response = mapper.readValue(reader, clas); + LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, "SUCCESS", mapper.writeValueAsString(response)); + } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) { + LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", ENTRY_DOESNT_EXIST); + return response; + } else { + BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ); + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse)); + throw new AAIServiceException(responseCode, errorresponse); + } + + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("GET", exc); + throw new AAIServiceException(exc); + } finally { + if(inputStream != null){ + try { + inputStream.close(); + } catch(Exception exc) { + LOG.warn("GET", exc); + } + } + } + return response; + } + + @Override + public Boolean patch(AAIRequest request, String resourceVersion) throws AAIServiceException { + InputStream inputStream = null; + + try { + AAIDatum instance = request.getRequestObject(); + if(instance instanceof ResourceVersion) { + resourceVersion = ((ResourceVersion)instance).getResourceVersion(); + } + + URL requestUrl = null; + requestUrl = request.getRequestUrl("PATCH", resourceVersion); + HttpURLConnection con = getConfiguredConnection(requestUrl, "PATCH"); + ObjectMapper mapper = AAIService.getObjectMapper(); + String jsonText = request.toJSONString(); + + LOGwriteDateTrace("data", jsonText); + logMetricRequest("PATCH "+requestUrl.getPath(), jsonText, requestUrl.getPath()); + + OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream()); + osw.write(jsonText); + osw.flush(); + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + String responseMessage = null; + try { + responseMessage = con.getResponseMessage(); + } catch(Exception exc) { + LOG.info("Exception occured", exc.getMessage()); + responseMessage = EnglishReasonPhraseCatalog.INSTANCE.getReason(responseCode,null); + } finally { + if(responseMessage == null) + responseMessage = NOT_PROVIDED; + } + + LOG.info(HTTP_URL_CONNECTION_RESULT, responseCode, responseMessage); + logMetricResponse(responseCode, responseMessage); + + // Process the response + BufferedReader reader; + String line = null; + reader = new BufferedReader( new InputStreamReader( inputStream ) ); + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + StringBuilder stringBuilder = new StringBuilder(); + + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append( line ); + } + LOGwriteEndingTrace(responseCode, responseMessage, (stringBuilder.length() > 0) ? stringBuilder.toString() : "{no-data}"); + return true; + } else { + StringBuilder stringBuilder = new StringBuilder(); + + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append("\n").append( line ); + } + LOG.info(stringBuilder.toString()); + + + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, responseMessage, mapper.writeValueAsString(errorresponse)); + + throw new AAIServiceException(responseCode, errorresponse); + } + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("AAIRequestExecutor.patch", exc); + throw new AAIServiceException(exc); + } finally { + try { + if(inputStream != null) + inputStream.close(); + } catch (Exception exc) { + LOG.warn("AAIRequestExecutor.patch", exc); + } + } + } + + /** + * + * @param httpReqUrl + * @param method + * @return + * @throws Exception + */ + protected HttpURLConnection getConfiguredConnection(URL httpReqUrl, String method) throws Exception { + HttpURLConnection con = (HttpURLConnection) httpReqUrl.openConnection(); + + // Set up the connection properties + con.setRequestProperty("Connection", "close"); + con.setDoInput(true); + con.setDoOutput(true); + con.setUseCaches(false); + con.setConnectTimeout(connection_timeout); + con.setReadTimeout(read_timeout); + con.setRequestMethod(method); + con.setRequestProperty("Accept", "application/json"); + con.setRequestProperty("Transfer-Encoding","chunked"); + con.setRequestProperty("Content-Type", + "PATCH".equalsIgnoreCase(method) ? "application/merge-patch+json" : "application/json"); + con.setRequestProperty("X-FromAppId", applicationId); + con.setRequestProperty("X-TransactionId", TransactionIdTracker.getNextTransactionId()); + String mlId = ml.getRequestID(); + if (mlId != null && !mlId.isEmpty()) { + LOG.debug(String.format("MetricLogger requestId = %s", mlId)); + con.setRequestProperty(ONAPLogConstants.MDCs.REQUEST_ID, mlId); + } else { + LOG.debug("MetricLogger requestId is null"); + } + + if (userName != null && !userName.isEmpty() && userPassword != null && !userPassword.isEmpty()) { + String basicAuth = "Basic " + new String(Base64.encodeBase64((userName + ":" + userPassword).getBytes())); + con.setRequestProperty("Authorization", basicAuth); + } + + if (con instanceof HttpsURLConnection && CTX != null) { + SSLSocketFactory sockFact = CTX.getSocketFactory(); + HttpsURLConnection.class.cast(con).setSSLSocketFactory(sockFact); + } + return con; + } + + private URL appendDepth(URL requestUrl, AAIRequest request) throws MalformedURLException { + + String depth = request.requestProperties.getProperty("depth", "1"); + String path = requestUrl.toString(); + if(path.contains("?depth=") || path.contains("&depth=")) { + return requestUrl; + } else { + if(path.contains("?")) { + path = String.format("%s&depth=%s", path, depth); + } else { + path = String.format("%s?depth=%s", path, depth); + } + return new URL(path); + } + } + + public void logMetricRequest(String targetServiceName, String msg, String path){ + String svcInstanceId = ""; + String svcName = null; + String partnerName = null; + String targetEntity = "A&AI"; + String targetVirtualEntity = null; + + ml.logRequest(svcInstanceId, svcName, partnerName, targetEntity, targetServiceName, targetVirtualEntity, msg); + } + + public void logMetricResponse(int responseCode, String responseDescription){ + ml.logResponse(responseCode < 400 ? "COMPLETE" : "ERROR", Integer.toString(responseCode), responseDescription); + } + + protected void LOGwriteFirstTrace(String method, String url) { + String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(System.currentTimeMillis()); + LOG.info("A&AI transaction :"); + LOG.info("Request Time : " + time + ", Method : " + method); + LOG.info("Request URL : "+ url); + } + + protected void LOGwriteDateTrace(String name, String data) { + LOG.info("Input - " + name + " : " + data); + } + + protected void LOGwriteEndingTrace(int response_code, String comment, String data) { + LOG.info("Response code : " + response_code +", " + comment); + LOG.info(String.format("Response data : %s", data)); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIDeclarations.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIDeclarations.java new file mode 100755 index 000000000..6765e152b --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIDeclarations.java @@ -0,0 +1,2041 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2019 IBM. + * ================================================================================ + * 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========================================================= + */ + +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.NoSuchMethodException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.bind.annotation.XmlType; + +import org.apache.commons.lang.StringUtils; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.ccsdk.sli.adaptors.aai.query.FormattedQueryResultList; +import org.onap.ccsdk.sli.adaptors.aai.query.Result; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.aai.inventory.v21.GenericVnf; +import org.onap.aai.inventory.v21.Image; +import org.onap.aai.inventory.v21.Metadata; +import org.onap.aai.inventory.v21.Metadatum; +import org.onap.aai.inventory.v21.RelatedToProperty; +import org.onap.aai.inventory.v21.Relationship; +import org.onap.aai.inventory.v21.RelationshipData; +import org.onap.aai.inventory.v21.RelationshipList; +import org.onap.aai.inventory.v21.ResultData; +import org.onap.aai.inventory.v21.SearchResults; +import org.onap.aai.inventory.v21.ServiceInstance; +import org.onap.aai.inventory.v21.Vlan; +import org.onap.aai.inventory.v21.Vlans; +import org.onap.aai.inventory.v21.Vserver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + + +public abstract class AAIDeclarations implements AAIClient { + + public static final String TRUSTSTORE_PATH = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust"; + public static final String TRUSTSTORE_PSSWD = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust.psswd"; + public static final String KEYSTORE_PATH = "org.onap.ccsdk.sli.adaptors.aai.ssl.key"; + public static final String KEYSTORE_PSSWD = "org.onap.ccsdk.sli.adaptors.aai.ssl.key.psswd"; + + public static final String APPLICATION_ID = "org.onap.ccsdk.sli.adaptors.aai.application"; + + public static final String CLIENT_NAME = "org.onap.ccsdk.sli.adaptors.aai.client.name"; + public static final String CLIENT_PWWD = "org.onap.ccsdk.sli.adaptors.aai.client.psswd"; + + + public static final String CONNECTION_TIMEOUT = "connection.timeout"; + public static final String READ_TIMEOUT = "read.timeout"; + + public static final String TARGET_URI = "org.onap.ccsdk.sli.adaptors.aai.uri"; + + public static final String AAI_VERSION = "org.onap.ccsdk.sli.adaptors.aai.version"; + + // Availability zones query + public static final String QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.query"; + + // Update + public static final String UPDATE_PATH = "org.onap.ccsdk.sli.adaptors.aai.update"; + + // Service instance + public static final String SVC_INSTANCE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst"; + public static final String SVC_INST_QRY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst.query"; + + // VServer + public static final String NETWORK_VSERVER_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vserver"; + + public static final String VNF_IMAGE_QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query"; + + public static final String PARAM_SERVICE_TYPE = "org.onap.ccsdk.sli.adaptors.aai.param.service.type"; + public static final String CERTIFICATE_HOST_ERROR = "org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore"; + + // UBB Notify + public static final String UBB_NOTIFY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.notify"; + public static final String SELFLINK_AVPN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.avpn"; + public static final String SELFLINK_FQDN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.fqdn"; + + //Service + public static final String SERVICE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.service"; + + // site-pair-sets + public static final String SITE_PAIR_SET_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.site.pair.set"; + + // node query (1602) + public static final String QUERY_NODES_PATH = "org.onap.ccsdk.sli.adaptors.aai.query.nodes"; + + private static final String VERSION_PATTERN = "/v$/"; + + private static final String AAI_SERVICE_EXCEPTION = "AAI Service Exception"; + + protected abstract Logger getLogger(); + public abstract AAIExecutorInterface getExecutor(); + + private static final String RELATIONSHIP_DATA= "Retrofitting relationship data: "; + + + @Override + public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) + throws SvcLogicException { + + getLogger().debug("AAIService.query \tresource = "+resource); + + String vnfId; + String vnfName = null; + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + getLogger().debug("key = "+ nameValues.toString()); + + if(!AAIServiceUtils.isValidFormat(resource, nameValues)) { + ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource)); + return QueryStatus.FAILURE; + } + + if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) { + ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource)); + return QueryStatus.FAILURE; + } + + // process data using new model + boolean useNewModelProcessing = true; + // process server query by name the old way + if("vserver".equals(resource) || "vserver2".equals(resource)){ + if(nameValues.containsKey("vserver_name") || nameValues.containsKey("vserver-name") || nameValues.containsKey("vserver.vserver_name") || nameValues.containsKey("vserver.vserver-name")) + useNewModelProcessing = false; + } + if("generic-vnf".equals(resource)){ + if(nameValues.containsKey("vnf_name") || nameValues.containsKey("vnf-name") || nameValues.containsKey("generic_vnf.vnf_name") || nameValues.containsKey("generic-vnf.vnf-name")) + useNewModelProcessing = false; + } + + // process data using new model + if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) { + + try { + return newModelQuery(resource, localOnly, select, key, prefix, orderBy, ctx); + } catch (Exception exc) { + getLogger().warn("Failed query - returning FAILURE", exc); + return QueryStatus.FAILURE; + } + } + + ObjectMapper mapper = AAIService.getObjectMapper(); + Map<String,Object> attributes = new HashMap<>(); + + String modifier = null; + + if(resource.contains(":")) { + String[] tokens = resource.split(":"); + resource = tokens[0]; + if(tokens.length > 1) { + modifier = tokens[1]; + } + } + + resource = resource.toLowerCase().replace("-", "_"); + + try { + + switch(resource) { + case "generic_vnf": + vnfId = nameValues.get("vnf_id"); + if(nameValues.containsKey("vnf_id")) + vnfId = nameValues.get("vnf_id"); + else if(nameValues.containsKey("generic_vnf.vnf_name")) + vnfId = nameValues.get("generic_vnf.vserver_name"); + + if(nameValues.containsKey("vnf_name")) + vnfName = nameValues.get("vnf_name"); + else if(nameValues.containsKey("generic_vnf.vnf_name")) + vnfName = nameValues.get("generic_vnf.vnf_name"); + + if(vnfId != null && !vnfId.isEmpty()) { + // at this point of the project this part should not be executed + vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", ""); + GenericVnf vnf = this.requestGenericVnfData(vnfId); + if(vnf == null) { + return QueryStatus.NOT_FOUND; + } + + attributes = mapper.convertValue(vnf, attributes.getClass()); + } else if(vnfName != null && !vnfName.isEmpty()) { + try { + vnfName = vnfName.trim().replace("'", "").replace("$", "").replace("'", ""); + GenericVnf vnf = this.requestGenericVnfeNodeQuery(vnfName); + if(vnf == null) { + return QueryStatus.NOT_FOUND; + } + vnfId=vnf.getVnfId(); + nameValues.put("vnf_id", vnfId); + attributes = mapper.convertValue(vnf, attributes.getClass()); + } catch (AAIServiceException exc) { + int errorCode = exc.getReturnCode(); + switch(errorCode) { + case 400: + case 404: + case 412: + break; + default: + getLogger().warn("Caught exception trying to refresh generic VNF", exc); + } + ctx.setAttribute(prefix + ".error.message", exc.getMessage()); + if(errorCode >= 300) { + ctx.setAttribute(prefix + ".error.http.response-code", + Integer.toString(exc.getReturnCode())); + } + return QueryStatus.FAILURE; + } + } else { + getLogger().warn("No arguments are available to process generic VNF"); + return QueryStatus.FAILURE; + } + break; + case "vserver": + case "vserver2": + String vserverName = null; + if(nameValues.containsKey("vserver_name")) + vserverName = nameValues.get("vserver_name"); + else if(nameValues.containsKey("vserver.vserver_name")) + vserverName = nameValues.get("vserver.vserver_name"); + + String vserverId = null; + if(nameValues.containsKey("vserver_id")) + vserverId = nameValues.get("vserver_id"); + if(nameValues.containsKey("vserver.vserver_id")) + vserverId = nameValues.get("vserver.vserver_id"); + String tenantId = nameValues.get("teannt_id"); + + if(vserverName != null) vserverName = vserverName.trim().replace("'", "").replace("$", "").replace("'", ""); + if(vserverId != null) vserverId = vserverId.trim().replace("'", "").replace("$", "").replace("'", ""); + if(tenantId != null) tenantId = tenantId.trim().replace("'", "").replace("$", "").replace("'", ""); + + if (vserverName != null) { + URL vserverUrl = null; + try { + vserverUrl = this.requestVserverURLNodeQuery(vserverName); + } catch (AAIServiceException aaiexc) { + getLogger().warn(AAI_SERVICE_EXCEPTION, aaiexc); + ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage()); + if (aaiexc.getReturnCode() >= 300) { + ctx.setAttribute(prefix + ".error.http" + "" + ".response-code", Integer.toString(aaiexc.getReturnCode())); + } + + if (aaiexc.getReturnCode() == 404) + return QueryStatus.NOT_FOUND; + else + return QueryStatus.FAILURE; + } + if (vserverUrl == null) { + return QueryStatus.NOT_FOUND; + } + + tenantId = getTenantIdFromVserverUrl(vserverUrl); + String cloudOwner = getCloudOwnerFromVserverUrl(vserverUrl); + String cloudRegionId = getCloudRegionFromVserverUrl(vserverUrl); + + Vserver vserver = null; + try { + vserver = this.requestVServerDataByURL(vserverUrl); + } catch (AAIServiceException aaiexc) { + getLogger().warn(AAI_SERVICE_EXCEPTION, aaiexc); + ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage()); + if (aaiexc.getReturnCode() >= 300) { + ctx.setAttribute(prefix + ".error.http" + ".response-code", Integer.toString(aaiexc.getReturnCode())); + } + + if (aaiexc.getReturnCode() == 404) + return QueryStatus.NOT_FOUND; + else + return QueryStatus.FAILURE; + } + if (vserver == null) { + return QueryStatus.NOT_FOUND; + } + attributes = mapper.convertValue(vserver, attributes.getClass()); + if (!attributes.containsKey("tenant-id") && tenantId != null) { + attributes.put("tenant-id", tenantId); + } + if (!attributes.containsKey("cloud-owner") && cloudOwner != null) { + attributes.put("cloud-owner", cloudOwner); + } + if (!attributes.containsKey("cloud-region-id") && cloudRegionId != null) { + attributes.put("cloud-region-id", cloudRegionId); + } + } else if (vserverId != null && tenantId != null) { + Vserver vserver = this.requestVServerData(tenantId, vserverId, "att-aic", "AAIAIC25"); + if(vserver == null) { + return QueryStatus.NOT_FOUND; + } + attributes = mapper.convertValue(vserver, attributes.getClass()); + if(!attributes.containsKey("tenant-id") && tenantId != null){ + attributes.put("tenant-id", tenantId); + } + } else { + return QueryStatus.FAILURE; + } + break; + + default: + return QueryStatus.FAILURE; + } + + QueryStatus retval = QueryStatus.SUCCESS; + + if (attributes == null || attributes.isEmpty()) { + retval = QueryStatus.NOT_FOUND; + getLogger().debug("No data found"); + } else { + if (ctx != null) { + if (prefix != null) { + ArrayList<String> keys = new ArrayList<>(attributes.keySet()); + + int numCols = keys.size(); + + for (int i = 0; i < numCols; i++) { + String colValue; + String colName = keys.get(i); + Object object = attributes.get(colName); + + if(object != null && object instanceof String) { + colValue = (String)object; + + if (prefix != null) { + getLogger().debug("Setting "+prefix + "." + colName.replaceAll("_", "-")+" = "+ colValue); + ctx.setAttribute(prefix + "." + colName.replaceAll("_", "-"), colValue); + } else { + getLogger().debug("Setting " + colValue.replaceAll("_", "-")+" = "+colValue); + ctx.setAttribute(colValue.replaceAll("_", "-"), colValue); + } + } else if(object != null && object instanceof Map) { + if(colName.equals(modifier) || "relationship-list".equals(colName)){ + String localNodifier = modifier; + if(localNodifier == null) + localNodifier = "relationship-list"; + Map<String, Object> properties = (Map<String, Object>)object; + writeMap(properties, prefix+"."+localNodifier, ctx); + } + } + } + } + } + } + getLogger().debug("Query - returning " + retval); + return retval; + + } catch (Exception exc) { + getLogger().warn("Failed query - returning FAILURE", exc); + return QueryStatus.FAILURE; + } + } + + + public void writeMap(Map<String, Object> properties, String prefix, SvcLogicContext ctx) { + Set<String> mapKeys = properties.keySet(); + + for(String mapKey : mapKeys) { + Object entity = properties.get(mapKey); + if(entity instanceof ArrayList) { + writeList((ArrayList<?>)entity, prefix + "." + mapKey, ctx); + } else + if(entity instanceof String || entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) { + ctx.setAttribute(prefix + "." + mapKey, entity.toString()); + getLogger().debug(prefix + "." + mapKey + " : " + entity.toString()); + } else if(entity instanceof Map) { + String localPrefix = prefix; + if(mapKey != null) { + localPrefix = String.format("%s.%s", prefix, mapKey); + } + writeMap( (Map<String, Object>)entity, localPrefix, ctx); + } + } + } + + private void writeList(ArrayList<?> list, String prefix, SvcLogicContext ctx) { + for(int i = 0; i < list.size(); i++ ) { + Object entity = list.get(i); + if(entity instanceof Map) { + writeMap( (Map<String, Object>)entity, prefix + "[" + i + "]", ctx); + } else + if(entity instanceof String || entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) { + ctx.setAttribute(prefix, entity.toString()); + getLogger().debug(prefix + " : " + entity.toString()); + } + } + + if(!list.isEmpty()) { + ctx.setAttribute(prefix + "_length", Integer.toString(list.size())); + getLogger().debug(prefix + "_length" + " : " + Integer.toString(list.size())); + } + } + + @Override + public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + + getLogger().debug("AAIService.save\tresource="+resource); + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + + if(!AAIServiceUtils.isValidFormat(resource, nameValues)) { + ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource)); + return QueryStatus.FAILURE; + } + + if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) { + getLogger().warn("AAIService.save has unspecified resource"); + ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource)); + return QueryStatus.FAILURE; + } + // keys passed + getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray())); + + // process params + if(params.containsKey("prefix")) { + Map<String, String> tmpParams = ctxGetBeginsWith(ctx, params.get("prefix")); + if(!tmpParams.isEmpty()) { + params.putAll(tmpParams); +// params.remove("prefix"); + } + } + // params passed + getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray())); + + boolean useNewModelProcessing = true; + // process server query by name the old way + if("vserver".equals(resource) || "vserver2".equals(resource)){ + if(nameValues.containsKey("vserver-name")) { + useNewModelProcessing = false; + } + + if(!params.containsKey("vserver-selflink")) { + + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + URL path = null; + try { + request.processRequestPathValues(nameValues); + path = request.getRequestUrl("GET", null); + params.put("vserver-selflink", path.toString()); + } catch (UnsupportedEncodingException | MalformedURLException | URISyntaxException e) { + getLogger().warn("URL error Exception", e); + params.put("vserver-selflink", "/vserver"); + } + } + } + + // process data using new model + if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) { + + try { + if(!resource.contains(":")){ + return newModelSave(resource, force, key, params, prefix, ctx); + } else { + String[] tokens = resource.split(":"); + String localResource = tokens[0]; + String dependency = tokens[1]; + + AAIDatum instance = newModelObjectRequest( localResource, nameValues, prefix, ctx); + if(instance == null) { + return QueryStatus.NOT_FOUND; + } + + switch(dependency){ + case "relationship-list": + newModelProcessRelationshipList(instance, params, prefix, ctx); + break; + case "metadata": + newModelProcessMetadata(instance, params, prefix, ctx); + break; + } + // create a method to update relationship-list + AAIRequest request = AAIRequest.createRequest(localResource, nameValues); + request.setRequestObject(instance); + request.processRequestPathValues(nameValues); + + getExecutor().post(request); + getLogger().debug("Save relationship list - returning SUCCESS"); + return QueryStatus.SUCCESS; + } + } catch (Exception exc) { + ctx.setAttribute(prefix + ".error.message", exc.getMessage()); + if(exc instanceof AAIServiceException) { + AAIServiceException aaiexc = (AAIServiceException)exc; + if(aaiexc.getReturnCode() >= 300) { + ctx.setAttribute(prefix + ".error.http" + ".response-code", Integer.toString(aaiexc.getReturnCode())); + } + + if(aaiexc.getReturnCode() == 404) { + return QueryStatus.NOT_FOUND; + } + } + getLogger().warn("Failed save() - returning FAILURE", exc); + return QueryStatus.FAILURE; + } + } else { + getLogger().debug("Save() request for {} is not supported- returning FAILURE", resource); + return QueryStatus.FAILURE; + } + } + + @Override + public QueryStatus update(String resource, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) throws SvcLogicException { + + resource = resource.toLowerCase(); + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray())); + if(!AAIServiceUtils.isValidFormat(resource, nameValues)) { + ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource)); + return QueryStatus.FAILURE; + } + + if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) { + ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource)); + return QueryStatus.FAILURE; + } + + // check if request is for groups + if(!AAIServiceUtils.containsResource(resource, nameValues)) { + ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not permitted in 'update' operation", resource)); + return QueryStatus.FAILURE; + } + + getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray())); + + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + request = new UpdateRequest(request, params); + + String[] arguments = request.getArgsList(); + for(String name : arguments) { + String modifiedKey = name.replaceAll("-", "_"); + if(nameValues.containsKey(modifiedKey)) { + String argValue = nameValues.get(modifiedKey); + if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", ""); + request.addRequestProperty(name, argValue); + } + } + + try { + QueryStatus retval = QueryStatus.SUCCESS; + + retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx); + + if(retval == null || retval != QueryStatus.SUCCESS) { + return retval; + } + + String resourceVersion = ctx.getAttribute("tmpDelete.resource-version"); + if(resourceVersion == null) { + return QueryStatus.NOT_FOUND; + } + params.put("resource-version", resourceVersion); + + request.processRequestPathValues(nameValues); + getExecutor().patch(request, resourceVersion); + } catch(AAIServiceException aaiexc) { + getLogger().warn(AAI_SERVICE_EXCEPTION, aaiexc); + if(aaiexc.getReturnCode() == 404) + return QueryStatus.NOT_FOUND; + else + return QueryStatus.FAILURE; + } catch (Exception exc) { + getLogger().warn("Failed update - returning FAILURE", exc); + return QueryStatus.FAILURE; + } + + getLogger().debug("Update - returning SUCCESS"); + return QueryStatus.SUCCESS; + } + + @Override + public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException { + getLogger().debug("AAIService.delete\tresource="+resource); + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray())); + + if(!AAIServiceUtils.isValidFormat(resource, nameValues)) { + ctx.setAttribute(String.format("%s.error.message", "aaiData"), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource)); + return QueryStatus.FAILURE; + } + + if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) { + ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not supported", resource)); + return QueryStatus.FAILURE; + } + + // check if request is for groups + if(!AAIServiceUtils.containsResource(resource, nameValues)) { + ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not permitted in 'delete' operation", resource)); + return QueryStatus.FAILURE; + } + + if(AAIRequest.createRequest(resource, nameValues) != null) { + if(resource.contains(":")) { + switch (resource.split(":")[1]){ + case "relationship-list": + return processDeleteRelationshipList(resource, key, ctx, nameValues); + case "metadata": + return processDeleteMetadata(resource, key, ctx, nameValues); + } + } + + + try { + QueryStatus retval = QueryStatus.SUCCESS; + + retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx); + + if(retval == null || retval != QueryStatus.SUCCESS) { + return retval; + } + + String resourceVersion = ctx.getAttribute("tmpDelete.resource-version"); + if(resourceVersion == null) { + return QueryStatus.NOT_FOUND; + } + + try { + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + if(request == null) { + return QueryStatus.FAILURE; + } + + request.processRequestPathValues(nameValues); + + if(getExecutor().delete(request, resourceVersion)) { + return QueryStatus.SUCCESS; + } + } catch(AAIServiceException aaiexc) { + getLogger().warn(AAI_SERVICE_EXCEPTION, aaiexc); + if(aaiexc.getReturnCode() == 404) + return QueryStatus.NOT_FOUND; + else + return QueryStatus.FAILURE; + + } catch (Exception exc) { + getLogger().warn("requestGenericVnfData", exc); + return QueryStatus.FAILURE; + } + + } catch (Exception exc) { + getLogger().warn("Failed delete - returning FAILURE", exc); + return QueryStatus.FAILURE; + } + } else { + String resourceName = resource; + String identifier = null; + + if(resourceName.contains(":")) { + String[] tokens = resourceName.split(":"); + if(tokens != null && tokens.length > 0) { + resourceName = tokens[0]; + identifier = tokens[1]; + } + } + if("relationship-list".equals(identifier) || "relationshipList".equals(identifier)) { +// RelationshipRequest relationshipRequest = new RelationshipRequest(); + if("generic-vnf".equals(resourceName)){ + String vnfId = nameValues.get("vnf_id"); + String relatedTo = nameValues.get("related_to"); + vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", ""); + relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", ""); + + GenericVnf vnf; + try { + vnf = this.requestGenericVnfData(vnfId); + if(vnf == null) + return QueryStatus.NOT_FOUND; + } catch (AAIServiceException exc) { + getLogger().warn("Failed delete - returning NOT_FOUND", exc); + return QueryStatus.NOT_FOUND; + } + boolean itemRemoved = false; + RelationshipList relationshipList = vnf.getRelationshipList(); + List<Relationship> relationships = relationshipList.getRelationship(); + List<Relationship> iterableList = new LinkedList<>(relationships); + for(Relationship relationship : iterableList) { + if(relationship.getRelatedTo().equals(relatedTo)) { + relationships.remove(relationship); + itemRemoved = true; + } + } + + if(!itemRemoved) + return QueryStatus.NOT_FOUND; + try { + this.postGenericVnfData(vnf.getVnfId(), vnf); + } catch (AAIServiceException exc) { + if(exc.getReturnCode() == 404){ + return QueryStatus.NOT_FOUND; + } else { + getLogger().warn("Failed delete - returning FAILURE", exc); + return QueryStatus.FAILURE; + } + } + return QueryStatus.SUCCESS; + } + } + } + return QueryStatus.FAILURE; + } + + @Override + public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException { + return query(resource, false, null, key, prefix, null, ctx); + } + + @Override + public QueryStatus isAvailable(String arg0, String arg1, String arg2, SvcLogicContext arg3) + throws SvcLogicException { + throw new SvcLogicException("Method AAIService.isAvailable() has not been implemented yet"); + } + + @Override + public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) throws SvcLogicException { + throw new SvcLogicException("Method AAIService.notify() has not been implemented yet"); + } + + // @Override + public QueryStatus newModelQuery(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) { + + QueryStatus retval = QueryStatus.SUCCESS; + String modifier = null; + + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + if(resource.contains(":")) { + modifier = resource.split(":")[1]; + } + + try { + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + if(request == null) { + return QueryStatus.FAILURE; + } + + Map<String, String> params = new HashMap<>(); + + request.processRequestPathValues(nameValues); + if(nameValues.containsKey("prefix")){ + Map<String, String> tmpParams = ctxGetBeginsWith(ctx, nameValues.get("prefix")); + if(!tmpParams.isEmpty()) { + params.putAll(tmpParams); + } + } + String rv = getExecutor().get(request); + + retval = processResponseData(rv, resource, request, prefix, ctx, nameValues, modifier); + + } catch(AAIServiceException aaiexc) { + getLogger().warn(AAI_SERVICE_EXCEPTION, aaiexc); + int errorCode = aaiexc.getReturnCode(); + ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage()); + if(errorCode >= 300) { + ctx.setAttribute(prefix + ".error.http.response-code", + Integer.toString(aaiexc.getReturnCode())); + } + + if(aaiexc.getReturnCode() == 404) + return QueryStatus.NOT_FOUND; + + return QueryStatus.FAILURE; + } catch (Exception exc) { + getLogger().warn("requestGenericVnfData", exc); + ctx.setAttribute(prefix + ".error.message", exc.getMessage()); + return QueryStatus.FAILURE; + } + + return retval; + } + + public QueryStatus processResponseData(String rv, String resource, AAIRequest request, String prefix, SvcLogicContext ctx, Map<String, String> nameValues, String modifier) throws JsonParseException, JsonMappingException, IOException, AAIServiceException + { + Object response; + + if(rv == null) { + return QueryStatus.NOT_FOUND; + } + + response = request.jsonStringToObject(rv); + if(response == null) { + return QueryStatus.NOT_FOUND; + } + + if("generic-query".equals(resource)) { + SearchResults rd = SearchResults.class.cast(response); + List<ResultData> rdList = rd.getResultData(); + if(rdList == null || rdList.isEmpty()) { + return QueryStatus.NOT_FOUND; + } + ResultData rDatum = rdList.get(0); + nameValues.put("selflink", rDatum.getResourceLink()); + AAIRequest req2 = AAIRequest.createRequest(rDatum.getResourceType(), nameValues); + req2.processRequestPathValues(nameValues); + rv = getExecutor().get(req2); + if(rv == null) { + return QueryStatus.NOT_FOUND; + } + + response = req2.jsonStringToObject(rv); + if(response == null) { + return QueryStatus.NOT_FOUND; + } + } + + if("nodes-query".equals(resource)) { + SearchResults rd = SearchResults.class.cast(response); + List<ResultData> rdList = rd.getResultData(); + if(rdList == null || rdList.isEmpty()) { + return QueryStatus.NOT_FOUND; + } + ResultData rDatum = rdList.get(0); + response = rDatum; + } + + if("formatted-query".equals(resource) || "custom-query".equals(resource)) { + FormattedQueryResultList rd = FormattedQueryResultList.class.cast(response); + List<Result> iRIlist = rd.getResults(); + if(iRIlist == null || iRIlist.isEmpty()) { + return QueryStatus.NOT_FOUND; + } + } + + // process relationship list + // this is a temporary soluton to address the realationship handling changes added in Release 17.07 + try { + Class<?> clazz = response.getClass(); + Method getter = clazz.getMethod("getRelationshipList"); + Object obj = getter.invoke(response); + if(obj != null && obj instanceof RelationshipList) { + RelationshipList list = RelationshipList.class.cast(obj); + AAIServiceUtils.populateRelationshipDataFromPath(list); + } + } catch(Exception exc) { + getLogger().debug(RELATIONSHIP_DATA + exc.getMessage()); + } + + String preFix; + if(prefix == null || prefix.isEmpty()) { + preFix = ""; + } else { + preFix = prefix + "."; + } + + Map<String,Object> props = objectToProperties(response); + Set<String> keys = props.keySet(); + for(String theKey: keys) { + if(getLogger().isTraceEnabled()) + getLogger().trace(theKey); + + Object value = props.get(theKey); + if(value == null) + continue; + Object type = value.getClass(); + if(value instanceof String) { + ctx.setAttribute(preFix + theKey, value.toString()); + continue; + } + if(value instanceof Boolean) { + ctx.setAttribute(preFix + theKey, value.toString()); + continue; + } + if(value instanceof Integer) { + ctx.setAttribute(preFix + theKey, value.toString()); + continue; + } + if(value instanceof Long) { + ctx.setAttribute(preFix + theKey, value.toString()); + continue; + } + + if(value instanceof ArrayList) { + ArrayList<?> array = ArrayList.class.cast(value); + for(int i = 0; i < array.size(); i++) { + writeList(array, String.format("%s.%s", prefix, theKey), ctx); + } + continue; + } + + if("relationship-list".equals(theKey)){ + Map<String, Object> relationshipList = (Map<String, Object>)value; + // we are interested in seeing just the selected relationship + if(theKey.equals(modifier)) { + List<?> relationships = (List<?>)relationshipList.get("relationship"); + if(relationships != null && !relationships.isEmpty()) { + + List newRelationships = new LinkedList(); + newRelationships.addAll(relationships); + + for(Object obj : newRelationships){ + if(obj instanceof Map<?, ?>) { + Map<?, ?> relProperties = (Map<?, ?>)obj; + if(relProperties.containsKey("related-to")) { + Object relPropsRelatedTo = relProperties.get("related-to"); + + String relatedTo = nameValues.get("related_to"); + if(relatedTo != null) { + relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", ""); + if(!relatedTo.equals(relPropsRelatedTo)) { + relationships.remove(relProperties); + } + continue; + } else { + continue; + } + } + } + } + } + } + writeMap(relationshipList, String.format("%s.%s", prefix, theKey), ctx); + continue; + } + + if(value instanceof Map) { + Map<String, Object> subnetsList = (Map<String, Object>)value; + writeMap(subnetsList, String.format("%s.%s", prefix, theKey), ctx); + continue; + } + + } + return QueryStatus.SUCCESS; + } + + + public QueryStatus newModelBackupRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx) { + + QueryStatus retval = QueryStatus.SUCCESS; + HashMap<String, String> nameValues = new HashMap<>(); + + try { + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + if(request == null) { + return QueryStatus.FAILURE; + } + + boolean argsFound = false; + String[] arguments = request.getArgsList(); + for(String name : arguments) { + String tmpName = name.replaceAll("-", "_"); + String value = params.get(tmpName); + if(value != null && !value.isEmpty()) { + value = value.trim().replace("'", "").replace("$", "").replace("'", ""); + request.addRequestProperty(name, value); + argsFound = true; + } + } + if(!argsFound) { + getLogger().warn("No arguments were found. Terminating backup request."); + return QueryStatus.FAILURE; + } + + String rv = getExecutor().get(request); + ctx.setAttribute(prefix, rv); + } catch(AAIServiceException aaiexc) { + getLogger().warn(AAI_SERVICE_EXCEPTION, aaiexc); + if(aaiexc.getReturnCode() == 404) + return QueryStatus.NOT_FOUND; + + return QueryStatus.FAILURE; + } catch (Exception exc) { + getLogger().warn("newModelBackupRequest", exc); + return QueryStatus.FAILURE; + } + + return retval; + } + + public AAIDatum newModelObjectRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx) + throws AAIServiceException { + + AAIDatum response = null; + + try { + AAIRequest request = AAIRequest.createRequest(resource, params); + if(request == null) { + return null; + } + + request.processRequestPathValues(params); + String rv = getExecutor().get(request); + response = request.jsonStringToObject(rv); + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + getLogger().warn("newModelBackupRequest", exc); + throw new AAIServiceException(exc); + } + + return response; + } + + + @Override + public QueryStatus release(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException { + throw new SvcLogicException("Method AAIService.release() has not been implemented yet"); + } + + @Override + public QueryStatus reserve(String arg0, String arg1, String arg2, String arg3, SvcLogicContext arg4) + throws SvcLogicException { + throw new SvcLogicException("Method AAIService.reserve() has not been implemented yet"); + } + + private QueryStatus newModelSave(String resource, boolean force, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) { + getLogger().debug("Executing newModelSave for resource : " + resource); + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + + try { + ArrayList<String> subResources = new ArrayList<>(); + Set<String> set = params.keySet(); + Map<String, Method> setters = new HashMap<>(); + Map<String, Method> getters = new HashMap<>(); + + // 1. find class + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + Class<? extends AAIDatum> resourceClass = request.getModelClass(); + getLogger().debug(resourceClass.getName()); + AAIDatum instance = resourceClass.newInstance(); + + { + Annotation[] annotations = resourceClass.getAnnotations(); + for(Annotation annotation : annotations) { + Class<? extends Annotation> anotationType = annotation.annotationType(); + String annotationName = anotationType.getName(); + + // 2. find string property setters and getters for the lists + if("javax.xml.bind.annotation.XmlType".equals(annotationName)){ + XmlType order = (XmlType)annotation; + String[] values = order.propOrder(); + for(String value : values) { + String id = AAIServiceUtils.camelCaseToDashedString(value); + Field field = resourceClass.getDeclaredField(value); + Class<?> type = field.getType(); + + try { + if(type.getName().startsWith("java.lang") || "boolean".equals(type.getName()) || "long".equals(type.getName()) || "int".equals(type.getName())) { + try { + Method setter = resourceClass.getMethod("set"+StringUtils.capitalize(value), type); + Object arglist[] = new Object[1]; + arglist[0] = params.get(id); + + if(arglist[0] != null) { + if(!type.getName().equals("java.lang.String")) { +// getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value)); + if("java.lang.Long".equals(type.getName()) || "java.lang.Integer".equals(type.getName())) { + String fv = params.get(id); + if(fv == null || fv.isEmpty()) { + arglist[0] = null; + } else { + arglist[0] = valueOf(type, params.get(id)); + } + } else if("boolean".equals(type.getName())) { + arglist[0] = valueOf(Boolean.class, params.get(id)); + } else if("int".equals(type.getName())) { + arglist[0] = valueOf(Integer.class, params.get(id)); + } else if("long".equals(type.getName())) { + String fv = params.get(id); + if(fv == null || fv.isEmpty()) { + arglist[0] = null; + } else { + arglist[0] = valueOf(Long.class, params.get(id)); + } + } else { + arglist[0] = valueOf(type, params.get(id)); + } + } + Object obj = setter.invoke(instance, arglist); + } + set.remove(id); + + } catch (Exception x) { + Throwable cause = x.getCause(); + getLogger().warn("Failed process for " + resourceClass.getName(), x); + } + } else if("java.util.List".equals(type.getName())) { + List<String> newValues = new ArrayList<>(); + String length = id+"_length"; + if(!params.isEmpty() && params.containsKey(length)) { + String tmp = params.get(length); + int count = Integer.parseInt(tmp); + for(int i=0; i<count; i++) { + String tmpValue = params.get(String.format("%s[%d]", id, i)); + newValues.add(tmpValue); + } + if(!newValues.isEmpty()) { + Method setter = findSetterFor(resourceClass, value); + if(setter != null) { + Object o = setter.invoke(instance, newValues); + } else { + try { + Method listGetter = resourceClass.getMethod("get"+StringUtils.capitalize(value)); + Object o = listGetter.invoke(instance); + if(o != null && o instanceof java.util.List ) { + List innerList = List.class.cast(o); + innerList.addAll(newValues); + } + } catch(NoSuchMethodException nsme) { + getLogger().warn(AAI_SERVICE_EXCEPTION, nsme); + } + } + } + } + set.remove(id); + } else { + Method setter = resourceClass.getMethod("set"+StringUtils.capitalize(value), type); + setters.put(id, setter); + } + } catch(Exception exc) { + getLogger().warn(AAI_SERVICE_EXCEPTION, exc); + } + + Method getter; + try { + getter = resourceClass.getMethod("get"+StringUtils.capitalize(value)); + if(!type.getName().equals("java.lang.String")) { + getters.put(id, getter); + } + } catch(NoSuchMethodException exc) { + try { + if(type.getName().equals("java.lang.Boolean")) { + getter = resourceClass.getMethod("is"+StringUtils.capitalize(value)); + getters.put(id, getter); + } else { + getLogger().warn(AAI_SERVICE_EXCEPTION, exc); + } + } catch(Exception iexc) { + getLogger().warn(AAI_SERVICE_EXCEPTION, iexc); + } + } catch(Exception exc) { + getLogger().warn(AAI_SERVICE_EXCEPTION, exc); + } + + } + subResources.addAll(Arrays.asList(values)); + } + } + } + + // remove getters that have matching setter + for(String setKey : setters.keySet()) { + if(getters.containsKey(setKey)) { + getters.remove(setKey); + } + } + + Set<String> relationshipKeys = new TreeSet<>(); + Set<String> vlansKeys = new TreeSet<>(); + Set<String> metadataKeys = new TreeSet<>(); + + for(String attribute : set) { + String value = params.get(attribute); + if(attribute.startsWith("relationship-list")) { + relationshipKeys.add(attribute); + } else if(attribute.startsWith("vlans")) { + vlansKeys.add(attribute); + } else if(attribute.startsWith("metadata")) { + metadataKeys.add(attribute); + } + } + // 3. find list property getters + for(String attribute : set) { + String value = params.get(attribute); + Method method = getters.get(attribute); + if(method != null) { + try { + Object arglist[] = new Object[0]; +// arglist[0] = value; + Class<?>[] types = method.getParameterTypes(); + if(types.length == 0){ + Object o = method.invoke(instance, arglist); + if(o instanceof ArrayList) { + ArrayList<String> values = (ArrayList<String>)o; + value = value.replace("[", "").replace("]", ""); + List<String> items = Arrays.asList(value.split("\\s*,\\s*")); + for(String s : items) { + values.add(s.trim()); + } + } + } + } catch (Exception x) { + Throwable cause = x.getCause(); + getLogger().warn("Failed process for " + resourceClass.getName(), x); + } + } + } + // 4. Process Relationships + // add relationship list + if( (subResources.contains("relationship-list") || subResources.contains("relationshipList")) && !relationshipKeys.isEmpty()) { + RelationshipList relationshipList = null; + Object obj = null; + Method getRelationshipListMethod = null; + try { + getRelationshipListMethod = resourceClass.getMethod("getRelationshipList"); + } catch(Exception exc) { + getLogger().debug(RELATIONSHIP_DATA + exc.getMessage()); + } + + if(getRelationshipListMethod != null){ + try { + obj = getRelationshipListMethod.invoke(instance); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + if(obj != null && obj instanceof RelationshipList){ + relationshipList = (RelationshipList)obj; + } else { + relationshipList = new RelationshipList(); + Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class); + if(setRelationshipListMethod != null){ + try { + Object arglist[] = new Object[1]; + arglist[0] = relationshipList; + + obj = setRelationshipListMethod.invoke(instance, arglist); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + } + + List<Relationship> relationships = relationshipList.getRelationship(); + + int i = 0; + while(true){ + String searchKey = "relationship-list.relationship[" + i + "].related-to"; + if(!params.containsKey(searchKey)) + break; + int j = 0; + String relatedTo = params.get(searchKey); + String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link"; + String relatedLink = null; + if(params.containsKey(relatedLinkKey)) { + relatedLink = params.get(relatedLinkKey); + } + Relationship relationship = new Relationship(); + relationships.add(relationship); + relationship.setRelatedTo(relatedTo); + String relationshipLabel = "relationship-list.relationship[" + i + "].relationship-label"; + if(params.containsKey(searchKey)) { + relationship.setRelationshipLabel(params.get(relationshipLabel)); + } + getLogger().debug("About to process related link of {}", relatedLink); + if(relatedLink != null) { + if(relatedLink.contains("v$")) + relatedLink = relatedLink.replace(VERSION_PATTERN, "/v21/"); + relationship.setRelatedLink(relatedLink); + } else { + Map<String, String> relParams = new HashMap<>(); + + while(true) { + String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-key"; + String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-value"; + if(!params.containsKey(searchRelationshipKey)) + break; + + relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue)); + j++; + } + AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams); + for(Map.Entry<String,String> entry : relParams.entrySet()) { + rlRequest.addRequestProperty(entry.getKey(), entry.getValue()); + } + String path = rlRequest.updatePathDataValues(null); + relationship.setRelatedLink(path); + } + { + int k = 0; + // process related to properties + Map<String, String> relParams = new HashMap<String, String>(); + + while(true) { + String searchRelatedToKey = "relationship-list.relationship[" + i + "].related-to-property[" + k + "].property-key"; + String searchRelatedToValue = "relationship-list.relationship[" + i + "].related-to-property[" + k + "].property-value"; + if(!params.containsKey(searchRelatedToKey)) + break; + + RelatedToProperty relDatum = new RelatedToProperty(); + relDatum.setPropertyKey(params.get(searchRelatedToKey)); + relDatum.setPropertyValue(params.get(searchRelatedToValue)); + relationship.getRelatedToProperty().add(relDatum); + + relParams.put(params.get(searchRelatedToKey), params.get(searchRelatedToValue)); + k++; + } + } + i++; + } + } + + // 4. vlans + if(subResources.contains("vlans") && !vlansKeys.isEmpty()) { + Object obj = null; + Vlans vlanList = null; + Method getVLansMethod = resourceClass.getMethod("getVlans"); + if(getVLansMethod != null){ + try { + obj = getVLansMethod.invoke(instance); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + if(obj != null && obj instanceof Vlans){ + vlanList = (Vlans)obj; + } else { + vlanList = new Vlans(); + Method setVlansMethod = resourceClass.getMethod("setVlans", Vlans.class); + if(setVlansMethod != null){ + try { + Object arglist[] = new Object[1]; + arglist[0] = vlanList; + + obj = setVlansMethod.invoke(instance, arglist); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + } + + int i = 0; + while(true){ + String searchKey = "vlans.vlan[" + i + "].vlan-interface"; + if(!params.containsKey(searchKey)) + break; + + String vlanInterface = params.get("vlans.vlan[" + i + "].vlan-interface"); + String vlanIdInner = params.get("vlans.vlan[" + i + "].vlan-id-inner"); + String vlanIdOute = params.get("vlans.vlan[" + i + "].vlan-id-outer"); + String speedValue = params.get("vlans.vlan[" + i + "].speed-value"); + String speedUnits = params.get("vlans.vlan[" + i + "].speed-units"); + + Vlan vlan = new Vlan(); + vlan.setVlanInterface(vlanInterface); + + if(vlanIdInner != null) { + Long iVlanIdInner = Long.parseLong(vlanIdInner); + vlan.setVlanIdInner(iVlanIdInner); + } + + if(vlanIdOute != null) { + Long iVlanIdOuter = Long.parseLong(vlanIdOute); + vlan.setVlanIdOuter(iVlanIdOuter); + } + + if(speedValue != null) { + vlan.setSpeedValue(speedValue); + vlan.setSpeedUnits(speedUnits); + } + + vlanList.getVlan().add(vlan); + i++; + } + } + + // 5. metadata + if(subResources.contains("metadata") && !metadataKeys.isEmpty()) { + Object obj = null; + Metadata metadataList = null; + Method getMetadataMethod = resourceClass.getMethod("getMetadata"); + if(getMetadataMethod != null){ + try { + obj = getMetadataMethod.invoke(instance); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + if(obj != null && obj instanceof Metadata){ + metadataList = (Metadata)obj; + } else { + metadataList = new Metadata(); + Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class); + if(setMetadataMethod != null){ + try { + Object arglist[] = new Object[1]; + arglist[0] = metadataList; + + obj = setMetadataMethod.invoke(instance, arglist); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + } + + // process data + int i = 0; + while(true){ + String metaKey = "metadata.metadatum[" + i + "].meta-key"; + if(!params.containsKey(metaKey)) + break; + + String metaValue = params.get("metadata.metadatum[" + i + "].meta-value"); + + Metadatum vlan = new Metadatum(); + vlan.setMetaname(metaKey); + vlan.setMetaval(metaValue); + + metadataList.getMetadatum().add(vlan); + i++; + } + + } + + + // 6. Prepare AAI request + String[] args = request.getArgsList(); + for(String arg : args) { + String modifiedKey = arg.replaceAll("-", "_"); + if(nameValues.containsKey(modifiedKey)) { + String argValue = nameValues.get(modifiedKey); + if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", ""); + request.addRequestProperty(arg, argValue); + } + } + + request.processRequestPathValues(nameValues); + request.setRequestObject(instance); + Object response = getExecutor().post(request); + if(request.expectsDataFromPUTRequest()){ + if(response != null && response instanceof String) { + String rv = response.toString(); + QueryStatus retval = processResponseData(rv, resource, request, prefix, ctx, nameValues, null); + getLogger().debug("newModelSave - returning " + retval.toString()); + return retval; + } + } + + } catch(AAIServiceException exc){ + ctx.setAttribute(prefix + ".error.message", exc.getMessage()); + int returnCode = exc.getReturnCode(); + if(returnCode >= 300) { + ctx.setAttribute(prefix + ".error.http.response-code", + Integer.toString(exc.getReturnCode())); + } + + if(returnCode == 400 || returnCode == 412) + return QueryStatus.FAILURE; + else if(returnCode == 404) + return QueryStatus.NOT_FOUND; + else { + getLogger().warn("Failed newModelSave - returning FAILURE", exc); + return QueryStatus.FAILURE; + } + } catch(Exception exc){ + getLogger().warn("Failed newModelSave - returning FAILURE", exc); + ctx.setAttribute(prefix + ".error.message", exc.getMessage()); + return QueryStatus.FAILURE; + } + + getLogger().debug("newModelSave - returning SUCCESS"); + return QueryStatus.SUCCESS; + } + + private Method findSetterFor(Class<? extends AAIDatum> resourceClass, String value) { + try { + String setterName = "set"+StringUtils.capitalize(value); + for (Method method : resourceClass.getDeclaredMethods()) { + int modifiers = method.getModifiers(); + if (Modifier.isPublic(modifiers) && setterName.contentEquals(method.getName())) { + return method; + } + } + } catch(Exception exc) { + getLogger().warn("findSetterFor()", exc); + } + return null; + } + + private QueryStatus newModelProcessRelationshipList(Object instance, Map<String, String> params, String prefix, SvcLogicContext ctx) throws Exception { + + Class resourceClass = instance.getClass(); + + Set<String> relationshipKeys = new TreeSet<>(); + + Set<String> set = params.keySet(); + + for(String attribute : set) { + String value = params.get(attribute); + + if(attribute.startsWith("relationship-list")) { + relationshipKeys.add(attribute); + } + } + + // 3. Process Relationships + // add relationship list + if(!relationshipKeys.isEmpty()) { + RelationshipList relationshipList; + Object obj = null; + Method getRelationshipListMethod = null; + try { + getRelationshipListMethod = resourceClass.getMethod("getRelationshipList"); + } catch(Exception exc) { + getLogger().debug(RELATIONSHIP_DATA + exc.getMessage()); + } + if(getRelationshipListMethod != null){ + try { + obj = getRelationshipListMethod.invoke(instance); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + if(obj != null && obj instanceof RelationshipList){ + relationshipList = (RelationshipList)obj; + } else { + relationshipList = new RelationshipList(); + Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class); + if(setRelationshipListMethod != null){ + try { + Object arglist[] = new Object[1]; + arglist[0] = relationshipList; + + obj = setRelationshipListMethod.invoke(instance, arglist); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + } + + boolean createdNewRelationships = false; + List<Relationship> relationships = relationshipList.getRelationship(); + if(relationships == null) { + relationships = new ArrayList<>(); + createdNewRelationships = true; + } + + int i = 0; + while(true){ + String searchKey = "relationship-list.relationship[" + i + "].related-to"; + if(!params.containsKey(searchKey)) + break; + + String relatedTo = params.get(searchKey); + String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link"; + String relatedLink = null; + if(params.containsKey(relatedLinkKey)) { + relatedLink = params.get(relatedLinkKey); + } + + Relationship relationship = new Relationship(); + relationships.add(relationship); + relationship.setRelatedTo(relatedTo); + + String relationshipLabel = "relationship-list.relationship[" + i + "].relationship-label"; + if(params.containsKey(searchKey)) { + relationship.setRelationshipLabel(params.get(relationshipLabel)); + } + + if (relatedLink != null) { + if(relatedLink.contains("v$")) + relatedLink = relatedLink.replace(VERSION_PATTERN, AAIRequest.getSupportedAAIVersion()); + relationship.setRelatedLink(relatedLink); + } else { + Map<String, String> relParams = new HashMap<>(); + int j = 0; + + while (true) { + String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + + j + "].relationship-key"; + String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + + j + "].relationship-value"; + if (!params.containsKey(searchRelationshipKey)) + break; + + RelationshipData relDatum = new RelationshipData(); + relDatum.setRelationshipKey(params.get(searchRelationshipKey)); + relDatum.setRelationshipValue(params.get(searchRelationshipValue)); + relationship.getRelationshipData().add(relDatum); + + relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue)); + j++; + } + AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams); + for (Map.Entry<String, String> entry : relParams.entrySet()) { + rlRequest.addRequestProperty(entry.getKey(), entry.getValue()); + } + String path = rlRequest.updatePathDataValues(null); + relationship.setRelatedLink(path); + } + { + int k = 0; + // process related to properties + Map<String, String> relParams = new HashMap<String, String>(); + + while(true) { + String searchRelatedToKey = "relationship-list.relationship[" + i + "].related-to-property[" + k + "].property-key"; + String searchRelatedToValue = "relationship-list.relationship[" + i + "].related-to-property[" + k + "].property-value"; + if(!params.containsKey(searchRelatedToKey)) + break; + + RelatedToProperty relDatum = new RelatedToProperty(); + relDatum.setPropertyKey(params.get(searchRelatedToKey)); + relDatum.setPropertyValue(params.get(searchRelatedToValue)); + relationship.getRelatedToProperty().add(relDatum); + + relParams.put(params.get(searchRelatedToKey), params.get(searchRelatedToValue)); + k++; + } + } + + i++; + } + } + + return QueryStatus.SUCCESS; + } + + private QueryStatus newModelProcessMetadata(Object instance, Map<String, String> params, String prefix, SvcLogicContext ctx) throws Exception { + + if (!(instance instanceof ServiceInstance) && !(instance instanceof Image)) { + throw new IllegalArgumentException("request is not applicable for selected request"); + } + + Class resourceClass = instance.getClass(); + Set<String> metadataKeys = new TreeSet<>(); + Set<String> set = params.keySet(); + for(String attribute : set) { + if(attribute.startsWith("metadata")) { + metadataKeys.add(attribute); + } + } + + // 3. Process Metadata + // add metadata + if(!metadataKeys.isEmpty()) { + Metadata metadata = null; + Object obj = null; + Method getMetadataMethod = resourceClass.getMethod("getMetadata"); + if(getMetadataMethod != null){ + try { + obj = getMetadataMethod.invoke(instance); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + if(obj != null && obj instanceof Metadata){ + metadata = (Metadata)obj; + } else { + metadata = new Metadata(); + Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class); + if(setMetadataMethod != null){ + try { + setMetadataMethod.invoke(instance, metadata); + } catch (InvocationTargetException x) { + } + } + } + + List<Metadatum> metadatumList = metadata.getMetadatum(); + int i = 0; + while(true){ + String metaNameKey = "metadata.metadatum[" + i + "].metaname"; + String metaValueKey = "metadata.metadatum[" + i + "].metaval"; + if(!params.containsKey(metaNameKey) || !params.containsKey(metaValueKey)) + break; + + Metadatum metadatum = new Metadatum(); + metadatum.setMetaname(params.get(metaNameKey)); + metadatum.setMetaval(params.get(metaValueKey)); + metadatumList.add(metadatum); + + i++; + } + } + + return QueryStatus.SUCCESS; + } + + private Relationship findRelationship(List<Relationship> relationships, String relatedTo) { + if(relatedTo == null) + return null; + + for(Relationship relationship : relationships) { + if(relationship.getRelatedTo().equals(relatedTo)){ + return relationship; + } + } + return null; + } + + + public QueryStatus backup(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + String resource = params.get("resource").toLowerCase(); + String prefix = params.get("data-key"); + + HashMap<String, String> nameValues = new HashMap<>(); + if(AAIRequest.createRequest(resource, nameValues) != null) { + + try { + return newModelBackupRequest(resource, params, prefix, ctx); + } catch (Exception exc) { + getLogger().warn("Failed backup - returning FAILURE", exc); + return QueryStatus.FAILURE; + } + } + + return QueryStatus.NOT_FOUND; + } + + @Override + public QueryStatus restore(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + + QueryStatus retval = QueryStatus.SUCCESS; + String resource = params.get("resource").toLowerCase(); + String prefix = params.get("data-key"); + + HashMap<String, String> nameValues = new HashMap<>(); + if(AAIRequest.createRequest(resource, nameValues) != null) { + + try { + retval = newModelBackupRequest(resource, params, "tmpRestore", ctx); + if(retval == QueryStatus.SUCCESS) { + ctx.setAttribute("tmpRestore", null); + } + } catch (Exception exc) { + getLogger().warn("Failed restore - returning FAILURE", exc); + return QueryStatus.FAILURE; + } + } + + return QueryStatus.NOT_FOUND; + } + + protected Map<String, Object> objectToProperties(Object object) { + ObjectMapper mapper = AAIService.getObjectMapper(); + return mapper.convertValue(object, Map.class); + } + + static <T> T valueOf(Class<T> klazz, String arg) { + Exception cause = null; + T ret = null; + try { + ret = klazz.cast(klazz.getDeclaredMethod("valueOf", String.class).invoke(null, arg)); + } catch (NoSuchMethodException exc) { + LoggerFactory.getLogger(AAIService.class).warn("Wrong data type", exc); + ret = klazz.cast(arg); + } catch (IllegalAccessException e) { + cause = e; + } catch (InvocationTargetException e) { + cause = e; + } + if (cause == null) { + return ret; + } else { + throw new IllegalArgumentException(cause); + } + } + + private QueryStatus processDeleteRelationshipList(String resource, String key, SvcLogicContext ctx, HashMap<String, String> nameValues) { + try { + AAIRequest request = AAIRequest.createRequest(resource.split(":")[0], nameValues); + if(request == null) { + return QueryStatus.FAILURE; + } + + request.processRequestPathValues(nameValues); + URL url = request.getRequestUrl("GET", null); + + Class resourceClass = request.getModelClass(); + Object instance = getResource(url.toString(), resourceClass); + if(instance == null) + return QueryStatus.NOT_FOUND; + + // get resource version + String resourceVersion = null; + Method getResourceVersionMethod = resourceClass.getMethod("getResourceVersion"); + if(getResourceVersionMethod != null){ + try { + Object object = getResourceVersionMethod.invoke(instance); + if(object != null) + resourceVersion = object.toString(); + } catch (InvocationTargetException exc) { + getLogger().warn("Retrieving resource version", exc); + } + } + + RelationshipList relationshipList = null; + Object obj = null; + Method getRelationshipListMethod = null; + try { + getRelationshipListMethod = resourceClass.getMethod("getRelationshipList"); + } catch(Exception exc) { + getLogger().debug(RELATIONSHIP_DATA + exc.getMessage()); + } + if(getRelationshipListMethod != null){ + try { + obj = getRelationshipListMethod.invoke(instance); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + if(obj != null && obj instanceof RelationshipList){ + relationshipList = (RelationshipList)obj; + } else { + getLogger().debug("No relationships found to process."); + return QueryStatus.NOT_FOUND; + } + + if(relationshipList.getRelationship() == null || relationshipList.getRelationship().isEmpty()) { + return QueryStatus.NOT_FOUND; + } + String relatedTo = nameValues.get("related_to"); + if(relatedTo == null) { + return QueryStatus.FAILURE; + } + + relatedTo = relatedTo.replaceAll("_", "-"); + + String relatedLink = nameValues.get("relationship.related_link"); + if(relatedLink != null) { + relatedLink = URLDecoder.decode(relatedLink, "UTF-8"); + } + + List<Relationship> relationships = relationshipList.getRelationship(); + List<Relationship> relationshipsToDelete = new LinkedList<>(); + + for(Relationship relationship : relationships) { + if(relatedTo.equals(relationship.getRelatedTo())) { + if(relatedLink != null) { + if(relationship.getRelatedLink() != null ) { + String localRelatedLink = relationship.getRelatedLink(); + localRelatedLink = URLDecoder.decode(localRelatedLink, "UTF-8"); + if(localRelatedLink.endsWith(relatedLink)) { + getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(), relatedTo)); + relationshipsToDelete.add(relationship); + } + } + } else { + getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(), relatedTo)); + relationshipsToDelete.add(relationship); + } + } + } + if(relationshipsToDelete == null || relationshipsToDelete.isEmpty()) { + getLogger().info(String.format("Relationship has not been found for %s", key)); + return QueryStatus.NOT_FOUND; + } + + String path = url.toString(); + path = path + "/relationship-list/relationship"; + URL deleteUrl = new URL(path); + + ObjectMapper mapper = AAIService.getObjectMapper(); + + boolean cumulativeResponse = true; + + for(Relationship targetRelationship : relationshipsToDelete) { + String json_text = mapper.writeValueAsString(targetRelationship); + boolean response = deleteList(deleteUrl, json_text); + if(!response) + cumulativeResponse = response; + + } + + if(!cumulativeResponse) + return QueryStatus.FAILURE; + + return QueryStatus.SUCCESS; + + } catch(Exception exc) { + getLogger().warn("processDelete", exc); + return QueryStatus.FAILURE; + } + } + + private QueryStatus processDeleteMetadata(String resource, String key, SvcLogicContext ctx, HashMap<String, String> nameValues) { + try { + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + if(request == null) { + return QueryStatus.FAILURE; + } + + request.processRequestPathValues(nameValues); + URL url = request.getRequestUrl("GET", null); + + Class<?> resourceClass = request.getModelClass(); + Object instance = getResource(url.toString(), resourceClass); + + // get resource version + String resourceVersion = null; + Method getResourceVersionMethod = resourceClass.getMethod("getResourceVersion"); + if(getResourceVersionMethod != null){ + try { + resourceVersion = (String) getResourceVersionMethod.invoke(instance); + } catch (InvocationTargetException x) { + } + } + + Metadata metadata = null; + Object obj = null; + Method getMetadataMethod = resourceClass.getMethod("getMetadata"); + if(getMetadataMethod != null){ + try { + obj = getMetadataMethod.invoke(instance); + } catch (InvocationTargetException x) { + Throwable cause = x.getCause(); + } + } + if(obj != null && obj instanceof Metadata){ + metadata = (Metadata)obj; + } else { + getLogger().debug("No metadata found to process."); + return QueryStatus.NOT_FOUND; + } + + if(metadata.getMetadatum() == null || metadata.getMetadatum().isEmpty()) { + return QueryStatus.NOT_FOUND; + } + + List<Metadatum> metadatumList = metadata.getMetadatum(); + Metadatum metadatumToDelete = null; + + final String metaname = nameValues.get("metaname"); + + for(Metadatum metadatum : metadatumList) { + getLogger().debug(String.format("Comparing existing metadatum of '%s' to keyword '%s'", metadatum.getMetaname(), metaname)); + if(metaname.equals(metadatum.getMetaname())) { + metadatumToDelete = metadatum; + break; + } + } + if(metadatumToDelete == null) { + getLogger().info(String.format("Metadatum has not been found for %s", key)); + return QueryStatus.NOT_FOUND; + } + + String path = url.toString(); + path = path + "/metadata/metadatum/" + encodeQuery( metadatumToDelete.getMetaname() ) + + "?resource-version=" + metadatumToDelete.getResourceVersion(); + URL deleteUrl = new URL(path); + boolean response = deleteList(deleteUrl, null); + + if(!response) + return QueryStatus.FAILURE; + + return QueryStatus.SUCCESS; + + } catch(Exception exc) { + getLogger().warn("processDelete", exc); + return QueryStatus.FAILURE; + } + } + + protected String encodeQuery(String param) throws UnsupportedEncodingException { + return URLEncoder.encode(param, "UTF-8").replace("+", "%20"); + } + + static final Map<String, String> ctxGetBeginsWith( SvcLogicContext ctx, String prefix ) { + Map<String, String> tmpPrefixMap = new HashMap<>(); + + if(prefix == null || prefix.isEmpty()){ + return tmpPrefixMap; + } + + for( String key : ctx.getAttributeKeySet() ) { + if( key.startsWith(prefix) ) { + String tmpKey = key.substring(prefix.length() + 1); + tmpPrefixMap.put( tmpKey, ctx.getAttribute(key)); + } + } + + Map<String, String> prefixMap = new HashMap<>(); + Pattern p = Pattern.compile(".*\\[\\d\\]"); + + SortedSet<String> keys = new TreeSet<String>(tmpPrefixMap.keySet () ); + for(String key : keys) { + Matcher m = p.matcher(key); + if(m.matches()) { + continue; + } else if(key.endsWith("_length")) { + String listKey = key.substring(0, key.indexOf("_length")); + int max = Integer.parseInt(tmpPrefixMap.get(key)); + + ArrayList<String> data = new ArrayList<>(); + for(int x = 0; x < max; x++){ + String tmpKey = String.format("%s[%d]", listKey, x); + String tmpValue = tmpPrefixMap.get(tmpKey); + if(tmpValue != null && !tmpValue.isEmpty()) { + data.add(tmpValue); + } + } + if(!data.isEmpty()) { + prefixMap.put(listKey, data.toString()); + } else { + prefixMap.put(key, tmpPrefixMap.get(key)); + } + } else { + prefixMap.put(key, tmpPrefixMap.get(key)); + } + } + + return prefixMap; + } + + public abstract <T> T getResource(String key, Class<T> type) throws AAIServiceException ; + protected abstract boolean deleteList(URL url, String caller) throws AAIServiceException; +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIExecutorInterface.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIExecutorInterface.java new file mode 100755 index 000000000..d02f14a95 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIExecutorInterface.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +public interface AAIExecutorInterface { + public String get(AAIRequest request) throws AAIServiceException; + public String post(AAIRequest request) throws AAIServiceException; + public Boolean delete(AAIRequest request, String resourceVersion) throws AAIServiceException; + public Object query(AAIRequest request, Class clas) throws AAIServiceException; + public Boolean patch(AAIRequest request, String resourceVersion) throws AAIServiceException; +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIRequest.java new file mode 100755 index 000000000..9facab82c --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIRequest.java @@ -0,0 +1,493 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashSet; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.commons.lang.StringUtils; +import org.onap.aai.inventory.v21.GenericVnf; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public abstract class AAIRequest { + protected static final Logger LOG = LoggerFactory.getLogger(AAIRequest.class); + + protected static final String TARGET_URI = "org.onap.ccsdk.sli.adaptors.aai.uri"; + + protected static final String MASTER_REQUEST = "master-request"; + + public static final String RESOURCE_VERSION = "resource-version"; + + public static final String DEPTH = "depth"; + + protected static Properties configProperties; + protected final String targetUri; + protected static AAIService aaiService; + + protected AAIDatum requestDatum; + + protected final Properties requestProperties = new Properties(); + + + public static AAIRequest createRequest(String resoourceName, Map<String, String> nameValues){ + + String resoource = resoourceName; + String masterResource = null; + + if(resoource == null) + return null; + + if(resoource.contains(":")) { + String[] tokens = resoource.split(":"); + if(tokens != null && tokens.length == 2) { + resoource = tokens[1]; + masterResource = tokens[0]; + Class<? extends AAIDatum> clazz = getClassFromResource(resoource) ; + + if(clazz == null) { + return null; + } + } + } + + if(nameValues.containsKey("selflink")){ + Class<? extends AAIDatum> clazz = getClassFromResource(resoource) ; + + if(clazz != null) + return new SelfLinkRequest(clazz); + else + return null; + } + + switch(resoource){ + case "generic-query": + return new GenericQueryRequest(); + case "nodes-query": + return new NodesQueryRequest(); + case "custom-query": + case "formatted-query": + return new CustomQueryRequest(); + case "echo": + case "test": + return new EchoRequest(); + + case "linterface": + case "l2-bridge-sbg": + case "l2-bridge-bgf": + { + resoource = "l-interface"; + return getRequestFromResource("l-interface"); + } + case "relationship-list": + return new RelationshipListRequest(AAIRequest.createRequest(masterResource, nameValues)); + case "relationship": + return new RelationshipRequest(AAIRequest.createRequest(masterResource, nameValues)); + default: + return getRequestFromResource(resoource); + } + } + + + /** + * Map containing resource tag to its bit position in bitset mapping + */ + private static Map<String, String> tagValues = new LinkedHashMap<>(); + /** + * Map containing bitset value of the path to its path mapping + */ + private static Map<BitSet, String> bitsetPaths = new LinkedHashMap<>(); + + + public static Set<String> getResourceNames() { + return tagValues.keySet(); + } + + + public static void setProperties(Properties props, AAIService aaiService) { + AAIRequest.configProperties = props; + AAIRequest.aaiService = aaiService; + + InputStream in = null; + + try + { + LOG.info("Loading aai-path.properties via OSGi"); + URL url = null; + Bundle bundle = FrameworkUtil.getBundle(AAIService.class); + if(bundle != null) { + BundleContext ctx = bundle.getBundleContext(); + if(ctx == null) + return; + + url = ctx.getBundle().getResource(AAIService.PATH_PROPERTIES); + } else { + url = aaiService.getClass().getResource("/aai-path.properties"); + } + + in = url.openStream(); + } + catch (NoClassDefFoundError|Exception e) { + LOG.info("Loading aai-path.properties from jar"); + in = AAIRequest.class.getResourceAsStream("/aai-path.properties"); + + } + + if (in == null) { + return; + } + + try { + Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8); + + Properties properties = new Properties(); + properties.load(reader); + LOG.info("loaded " + properties.size()); + + Set<String> keys = properties.stringPropertyNames(); + + int index = 0; + Set<String> resourceNames = new TreeSet<>(); + + for(String key : keys) { + String[] tags = key.split("\\|"); + for(String tag : tags) { + if(!resourceNames.contains(tag)) { + resourceNames.add(tag); + tagValues.put(tag, Integer.toString(++index)); + } + } + BitSet bs = new BitSet(256); + for(String tag : tags) { + String value = tagValues.get(tag); + Integer bitIndex = Integer.parseInt(value) ; + bs.set(bitIndex); + } + String path = properties.getProperty(key); + LOG.trace(String.format("bitset %s\t\t%s", bs.toString(), path)); + bitsetPaths.put(bs, path); + } + LOG.info("loaded " + resourceNames.toString()); + } + catch (Exception e) + { + LOG.error("Caught exception", e); + } + } + + public AAIRequest() { + targetUri = configProperties.getProperty(TARGET_URI); + } + + public void addRequestProperty(String key, String value) { + requestProperties.put(key, value); + } + + public final void setRequestObject(AAIDatum value) { + requestDatum = value; + } + + public final AAIDatum getRequestObject() { + return requestDatum; + } + + public final void addMasterRequest(AAIRequest masterRequest) { + requestProperties.put(MASTER_REQUEST, masterRequest); + } + + protected static String encodeQuery(String param) throws UnsupportedEncodingException { + return URLEncoder.encode(param, "UTF-8").replace("+", "%20"); + } + + protected void handleException(AAIRequest lInterfaceRequest, JsonProcessingException exc) { + aaiService.getLogger().warn("Could not deserialize object of type " + lInterfaceRequest.getClass().getSimpleName(), exc) ; + } + + public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException, URISyntaxException { + + String request_url = null; + + request_url = targetUri + updatePathDataValues(resourceVersion); + + URL http_req_url = new URL(request_url); + + aaiService.LOGwriteFirstTrace(method, http_req_url.toString()); + + return http_req_url; + } + + public String updatePathDataValues(Object resourceVersion) throws UnsupportedEncodingException, MalformedURLException { + String request_url = getRequestPath(); + + Set<String> uniqueResources = extractUniqueResourceSetFromKeys(requestProperties.stringPropertyNames()); + + for(String resoourceName:uniqueResources) { + AAIRequest locRequest = AAIRequest.createRequest(resoourceName, new HashMap<String, String>()); + if(locRequest != null) { + Class<?> clazz = locRequest.getClass(); + Method function = null; + try { + function = clazz.getMethod("processPathData", request_url.getClass(), requestProperties.getClass()); + request_url = (String) function.invoke(null, request_url, requestProperties); + } catch (Exception e) { + LOG.error("Caught exception", e); + } + } + } + + if(resourceVersion != null) { + request_url = request_url +"?resource-version="+resourceVersion; + } + + return request_url; + } + + protected String getRequestPath() throws MalformedURLException { + return getRequestPath(null); + } + + protected String getRequestPath(String resource) throws MalformedURLException { + if(requestProperties.containsKey("resource-path")) { + return requestProperties.getProperty("resource-path"); + } + + Set<String> uniqueResources = extractUniqueResourceSetFromKeys(requestProperties.stringPropertyNames()); + if(resource != null) { + // for group search add itself, but remove singular version of itself + if(!uniqueResources.contains(resource)) { + boolean replaced = false; + Set<String> tmpUniqueResources = new HashSet<>(); + tmpUniqueResources.addAll(uniqueResources); + for(String item : tmpUniqueResources){ + String plural = item +"s"; + if(item.endsWith("y")){ + plural = item.substring(0, item.length()-1)+ "ies"; + } + if(plural.equals(resource)) { + uniqueResources.remove(item); + uniqueResources.add(resource); + replaced = true; + break; + } + } + if(!replaced){ + if(!uniqueResources.contains(resource)) { + uniqueResources.add(resource); + } + } + } + } + BitSet bitset = new BitSet(); + for(String key : uniqueResources) { + if(tagValues.containsKey(key)) { + Object tmpValue = tagValues.get(key); + if(tmpValue != null) { + String value = tmpValue.toString(); + int bitIndex = Integer.parseInt(value); + bitset.set(bitIndex); + } + } + } + + String path = bitsetPaths.get(bitset); + if(path == null) { + throw new MalformedURLException("PATH not found for key string containing valies :" +requestProperties.toString()); + } + return path; + } + + public abstract URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException, URISyntaxException; + + public abstract String toJSONString(); + + public abstract String[] getArgsList(); + + public abstract Class<? extends AAIDatum> getModelClass() ; + + public String getPrimaryResourceName(String resource) { + return resource; + } + + public String formatKey(String argument) { + return argument; + } + + public AAIDatum jsonStringToObject(String jsonData) throws JsonParseException, JsonMappingException, IOException { + if(jsonData == null) { + return null; + } + + AAIDatum response = null; + ObjectMapper mapper = getObjectMapper(); + response = mapper.readValue(jsonData, getModelClass()); + return response; + } + + protected static Set<String> extractUniqueResourceSetFromKeys(Set<String> keySet) { + Set<String> uniqueResources = new TreeSet<>(); + List<String> keys = new ArrayList<>(keySet); + for(String resource : keys) { + if(resource.contains(".")) { + String [] split = resource.split("\\."); + uniqueResources.add(split[0].replaceAll("_", "-")); + } + } + return uniqueResources; + } + + public void processRequestPathValues(Map<String, String> nameValues) { + Set<String> uniqueResources = extractUniqueResourceSetFromKeys(nameValues.keySet()); + + Set<String> tokens = new TreeSet<>(); + tokens.add(DEPTH); + tokens.addAll(Arrays.asList(this.getArgsList())); + + for(String resoourceName:uniqueResources) { + AAIRequest locRequest = AAIRequest.createRequest(resoourceName, nameValues); + if(locRequest != null) + tokens.addAll(Arrays.asList(locRequest.getArgsList())); + } + + String[] arguments = tokens.toArray(new String[0]); + for(String name : arguments) { + String tmpName = name.replaceAll("-", "_"); + String value = nameValues.get(tmpName); + if(value != null && !value.isEmpty()) { + value = value.trim().replace("'", "").replace("$", "").replace("'", ""); + this.addRequestProperty(name, value); + } + } + } + + public static String processPathData(String request_url, Properties requestProperties) throws UnsupportedEncodingException { + return request_url; + } + + public boolean isDeleteDataRequired() { + return false; + } + + ObjectMapper getObjectMapper() { + return AAIService.getObjectMapper(); + } + + public static Class<? extends AAIDatum> getClassFromResource(String resoourceName) { + String className = GenericVnf.class.getName(); + String[] split = resoourceName.split("-"); + for(int i = 0; i < split.length; i++) { + split[i] = StringUtils.capitalize(split[i]); + } + + String caps = StringUtils.join(split); + className = className.replace("GenericVnf", caps); + try { + return (Class<? extends AAIDatum>)Class.forName(className); + } catch (ClassNotFoundException e) { + LOG.warn("AAIRequest does not support class: " + e.getMessage()); + return null; + } + } + + protected static AAIRequest getRequestFromResource(String resoourceName) { + + Class<? extends AAIDatum> clazz = getClassFromResource(resoourceName); + + if(clazz == null) { + return null; + } + return new GenericRequest(clazz); + } + + public static Map<String, String> splitQuery(String query) throws UnsupportedEncodingException { + Map<String, String> query_pairs = new LinkedHashMap<>(); + + if(query != null && !query.isEmpty()) { + String[] pairs = query.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf('='); + query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8")); + } + } + return query_pairs; + } + + public static Map<String, String> splitPath(String path) throws UnsupportedEncodingException { + Map<String, String> query_pairs = new LinkedHashMap<>(); + + if(path != null && !path.isEmpty()) { + String[] pairs = path.split("/"); + for (String pair : pairs) { + int idx = pair.indexOf('='); + query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8")); + } + } + return query_pairs; + } + + protected boolean expectsDataFromPUTRequest() { + return false; + } + + + public String getTargetUri() { + return targetUri; + } + + public static final String getSupportedAAIVersion() { + return configProperties.getProperty(AAIDeclarations.AAI_VERSION, "/v21/"); + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIService.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIService.java new file mode 100755 index 000000000..4d51550a3 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIService.java @@ -0,0 +1,1547 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2019 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.Set; +import java.util.TimeZone; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +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.SSLSocketFactory; +import javax.ws.rs.HttpMethod; +import javax.xml.bind.annotation.XmlElement; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.ccsdk.sli.adaptors.aai.data.ErrorResponse; +import org.onap.ccsdk.sli.adaptors.aai.data.notify.NotifyEvent; +import org.onap.ccsdk.sli.core.sli.ConfigurationException; +import org.onap.ccsdk.sli.core.sli.MetricLogger; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.onap.aai.inventory.v21.GenericVnf; +import org.onap.aai.inventory.v21.PhysicalLink; +import org.onap.aai.inventory.v21.ResultData; +import org.onap.aai.inventory.v21.SearchResults; +import org.onap.aai.inventory.v21.Vserver; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.AnnotationIntrospector; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; + + +public class AAIService extends AAIDeclarations implements AAIClient, SvcLogicResource { + + public static final String AAICLIENT_PROPERTIES = "/aaiclient.properties"; + public static final String PATH_PROPERTIES = "/aai-path.properties"; + + private static final Logger LOG = LoggerFactory.getLogger(AAIService.class); + + private final String truststorePath; + private final String truststorePassword; + private final String keystorePath; + private final String keystorePassword; + private final Boolean ignoreCertificateHostError; + + private final String targetUri; + private final String networkVserverPath; + + private final String svc_inst_query_path; + + private final String ubb_notify_path; + private final String selflinkAvpn; + private final String selflinkFqdn; + + private final int connectionTimeout; + private final int readTimeout; + + // 1602 + private final String queryNodesPath; + private final String applicationId; + + // authentication credentials + private String userName; + private String userPassword; + + // runtime + private final boolean runtimeOSGI; + + private SSLContext CTX; + + private final MetricLogger ml = new MetricLogger(); + + private AAIExecutorInterface executor; + + public AAIService(final UtilsProvider configuration) { + this(configuration.getProperties()); + } + + public AAIService(final URL url) { + this(getProperties(url)); + } + + public AAIService(Properties props) { + LOG.info("Entered AAIService.ctor"); + + String runtime = System.getProperty("aaiclient.runtime"); + if("OSGI".equals(runtime)) { + runtimeOSGI = true; + } else { + runtimeOSGI = false; + } + + try { + AAIRequest.setProperties(props, this); + + } catch(Exception exc){ + LOG.error("AicAAIResource.static", exc); + } + + executor = new AAIClientRESTExecutor(props); + + userName = props.getProperty(CLIENT_NAME); + userPassword = props.getProperty(CLIENT_PWWD); + + if(userName == null || userName.isEmpty()){ + LOG.debug("Basic user name is not set"); + } + if(userPassword == null || userPassword.isEmpty()) { + LOG.debug("Basic password is not set"); + } + + truststorePath = props.getProperty(TRUSTSTORE_PATH); + truststorePassword = props.getProperty(TRUSTSTORE_PSSWD); + keystorePath = props.getProperty(KEYSTORE_PATH); + keystorePassword = props.getProperty(KEYSTORE_PSSWD); + + targetUri = props.getProperty(TARGET_URI); + props.getProperty(QUERY_PATH); + props.getProperty(UPDATE_PATH); + + String tmpApplicationId = props.getProperty(APPLICATION_ID); + if(tmpApplicationId == null || tmpApplicationId.isEmpty()) { + tmpApplicationId = "SDNC"; + } + this.applicationId = tmpApplicationId; + + // connection timeout + int tmpConnectionTimeout = 30000; + int tmpReadTimeout = 30000; + + try { + String tmpValue = null; + tmpValue = props.getProperty(CONNECTION_TIMEOUT, "30000"); + tmpConnectionTimeout = Integer.parseInt(tmpValue); + tmpValue = props.getProperty(READ_TIMEOUT, "30000"); + tmpReadTimeout = Integer.parseInt(tmpValue); + } catch(Exception exc) { + LOG.error("Failed setting connection timeout", exc); + tmpConnectionTimeout = 30000; + tmpReadTimeout = 30000; + } + connectionTimeout = tmpConnectionTimeout; + readTimeout = tmpReadTimeout; + + networkVserverPath =props.getProperty(NETWORK_VSERVER_PATH); + + props.getProperty(SVC_INSTANCE_PATH); + svc_inst_query_path = props.getProperty(SVC_INST_QRY_PATH); + props.getProperty(PARAM_SERVICE_TYPE, "service-type"); + + props.getProperty(VNF_IMAGE_QUERY_PATH); + + ubb_notify_path = props.getProperty(UBB_NOTIFY_PATH); + selflinkAvpn = props.getProperty(SELFLINK_AVPN); + selflinkFqdn = props.getProperty(SELFLINK_FQDN); + + props.getProperty(SERVICE_PATH); + + props.getProperty(SITE_PAIR_SET_PATH); + + queryNodesPath = props.getProperty(QUERY_NODES_PATH); + + String iche = props.getProperty(CERTIFICATE_HOST_ERROR); + boolean host_error = false; + if(iche != null && !iche.isEmpty()) { + host_error = Boolean.valueOf(iche); + } + + ignoreCertificateHostError = host_error; + + HttpsURLConnection.setDefaultHostnameVerifier( new HostnameVerifier(){ + public boolean verify(String string,SSLSession ssls) { + return ignoreCertificateHostError; + } + }); + + if(truststorePath != null && truststorePassword != null && (new File(truststorePath)).exists()) { + System.setProperty("javax.net.ssl.trustStore", truststorePath); + System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword); + } + + if(keystorePath != null && keystorePassword != null && (new File(keystorePath)).exists()) { + //DefaultClientConfig config = new DefaultClientConfig(); + //both jersey and HttpURLConnection can use this + SSLContext ctx = null; + try { + ctx = SSLContext.getInstance("TLS"); + + KeyManagerFactory kmf = null; + try (FileInputStream fin = new FileInputStream(keystorePath)){ + String def = "SunX509"; + String storeType = "PKCS12"; + def = KeyStore.getDefaultType(); + kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + + String extension = keystorePath.substring(keystorePath.lastIndexOf(".") + 1); + if("JKS".equalsIgnoreCase(extension)) { + storeType = "JKS"; + } + KeyStore ks = KeyStore.getInstance(storeType); + + char[] pwd = keystorePassword.toCharArray(); + ks.load(fin, pwd); + kmf.init(ks, pwd); + } catch (Exception ex) { + LOG.error("AAIResource", ex); + } + + if(null!=kmf) { + ctx.init(kmf.getKeyManagers(), null, null); + } + /* + * config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new + * HTTPSProperties( new HostnameVerifier() { + * + * @Override public boolean verify( String s, SSLSession sslSession ) { return + * ignoreCertificateHostError; } }, ctx)); + */ + + CTX = ctx; + LOG.debug("SSLContext created"); + + } catch (KeyManagementException | NoSuchAlgorithmException exc) { + LOG.error("AAIResource", exc); + } + } + + LOG.info("AAIResource.ctor initialized."); + + try { + Field methodsField = HttpURLConnection.class.getDeclaredField("methods"); + methodsField.setAccessible(true); + // get the methods field modifiers + Field modifiersField = Field.class.getDeclaredField("modifiers"); + // bypass the "private" modifier + modifiersField.setAccessible(true); + + // remove the "final" modifier + modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL); + + /* valid HTTP methods */ + String[] methods = { + "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH" + }; + // set the new methods - including patch + methodsField.set(null, methods); + + } catch (SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchFieldException e) { + LOG.error("Exception occured", e); + } + + } + + private static Properties getProperties(URL url) { + Properties properties = new Properties(); + try { + properties.load(url.openStream()); + } catch (IOException exc) { + LOG.error("getProperties", exc); + } + return properties; + } + + public void setExecutor(AAIExecutorInterface executor) { + this.executor = executor; + } + + public void cleanUp() { + + } + + /** + * + * @param http_req_url + * @param method + * @return + * @throws Exception + */ + protected HttpURLConnection getConfiguredConnection(URL http_req_url, String method) throws Exception { + HttpURLConnection con = (HttpURLConnection) http_req_url.openConnection(); + + // Set up the connection properties + con.setRequestProperty( "Connection", "close" ); + con.setDoInput(true); + con.setDoOutput(true); + con.setUseCaches(false); + con.setConnectTimeout( connectionTimeout ); + con.setReadTimeout( readTimeout ); + con.setRequestMethod( method ); + con.setRequestProperty( "Accept", "application/json" ); + con.setRequestProperty( "Content-Type", "PATCH".equalsIgnoreCase(method) ? "application/merge-patch+json" : "application/json" ); + con.setRequestProperty("X-FromAppId", applicationId); + con.setRequestProperty("X-TransactionId",TransactionIdTracker.getNextTransactionId()); + String mlId = ml.getRequestID(); + if(mlId != null && !mlId.isEmpty()) { + LOG.debug(String.format("MetricLogger requestId = %s", mlId)); + con.setRequestProperty(ONAPLogConstants.MDCs.REQUEST_ID, mlId); + } else { + LOG.debug("MetricLogger requestId is null"); + } + con.setRequestProperty("Transfer-Encoding","chunked"); + + if(userName != null && !userName.isEmpty() && userPassword != null && !userPassword.isEmpty()) { + String basicAuth = "Basic " + new String(Base64.encodeBase64((userName + ":" + userPassword).getBytes())); + con.setRequestProperty ("Authorization", basicAuth); + } + + if(con instanceof HttpsURLConnection && CTX != null) { + SSLSocketFactory sockFact = CTX.getSocketFactory(); + HttpsURLConnection.class.cast(con).setSSLSocketFactory( sockFact ); + } + return con; + } + + + @Override + public GenericVnf requestGenericVnfData(String vnf_id) throws AAIServiceException { + GenericVnf response = null; + + try { + AAIRequest request = AAIRequest.getRequestFromResource("generic-vnf"); + request.addRequestProperty("generic-vnf.vnf-id", vnf_id); + String rv = executor.get(request); + if(rv != null) { + ObjectMapper mapper = getObjectMapper(); + response = mapper.readValue(rv, GenericVnf.class); + } + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn(Object.class.getClass().getEnclosingMethod().getName(), exc); + throw new AAIServiceException(exc); + } + + return response; + + } + + @Override + public boolean postGenericVnfData(String vnf_id, GenericVnf data) throws AAIServiceException { + try { + AAIRequest request = AAIRequest.getRequestFromResource("generic-vnf"); + request.addRequestProperty("generic-vnf.vnf-id", vnf_id); + request.setRequestObject(data); + Object response = executor.post(request); + return true; + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("requestGenericVnfData", exc); + throw new AAIServiceException(exc); + } + } + + @Override + public SearchResults requestServiceInstanceURL(String svc_instance_id) throws AAIServiceException { + SearchResults response = null; + InputStream inputStream = null; + + try { + String path = svc_inst_query_path; + path = path.replace("{svc-instance-id}", encodeQuery(svc_instance_id)); + + String request_url = targetUri+path; + URL http_req_url = new URL(request_url); + + HttpURLConnection con = getConfiguredConnection(http_req_url, HttpMethod.GET); + + LOGwriteFirstTrace(HttpMethod.GET, http_req_url.toString()); + LOGwriteDateTrace("svc_instance_id", svc_instance_id); + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + + // Process the response + LOG.debug("HttpURLConnection result:" + responseCode); + if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); + BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ); + + ObjectMapper mapper = getObjectMapper(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + response = mapper.readValue(reader, SearchResults.class); + LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, "SUCCESS", mapper.writeValueAsString(response)); + } else if(responseCode == HttpURLConnection.HTTP_NOT_FOUND ) { + LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", "Entry does not exist."); + return response; + } else { + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse)); + throw new AAIServiceException(responseCode, errorresponse); + } + + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("requestServiceInstanceURL", exc); + throw new AAIServiceException(exc); + } finally { + if(inputStream != null){ + try { + inputStream.close(); + } catch(Exception exc) { + LOG.warn("Error closing Inputstream", exc); + } + } + } + return response; + } + + + private static Properties initialize(URL url ) throws ConfigurationException { + + if(url == null) { + throw new NullPointerException(); + } + + InputStream is = null; + Properties props = new Properties(); + + try { + if(LOG.isDebugEnabled()) + LOG.info("Property file is: " + url.toString()); + + is = url.openStream(); + + props.load(is); + if(LOG.isDebugEnabled()) { + LOG.info("Properties loaded: " + props.size()); + Enumeration<Object> en = props.keys(); + + while(en.hasMoreElements()) { + String key = (String)en.nextElement(); + String property = props.getProperty(key); + LOG.debug(key + " : " + property); + } + } + } catch (Exception e) { + throw new ConfigurationException("Could not load properties file.", e); + } + return props; + } + + static class TransactionIdTracker { +// protected static AtomicLong tracker = new AtomicLong(); + + public static String getNextTransactionId() { + // Check if RequestId exists as MDC. If not, create new. + String transactionId = MDC.get("RequestId"); + if ("".equals(transactionId) || transactionId == null) { + transactionId = UUID.randomUUID().toString(); + LOG.info("Missing requestID. Assigned " + transactionId); + MDC.put("RequestId", transactionId); + } + return transactionId; + } + + } + + protected void LOGwriteFirstTrace(String method, String url) { + String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(System.currentTimeMillis()); + LOG.info("A&AI transaction :"); + LOG.info("Request Time : " + time + ", Method : " + method); + LOG.info("Request URL : "+ url); + } + + protected void LOGwriteDateTrace(String name, String data) { + LOG.info("Input - " + name + " : " + data); + } + + protected void LOGwriteEndingTrace(int response_code, String comment, String data) { + LOG.info("Response code : " + response_code +", " + comment); + LOG.info(String.format("Response data : %s", data)); + } + + protected String encodeQuery(String param) throws UnsupportedEncodingException { + return URLEncoder.encode(param, "UTF-8").replace("+", "%20"); + } + + private String encodeCustomerURL(final String selection) + { + String encrypted_url = selection; + String apnpattern = + "/aai/v11/business/customers/customer/(.+)/service-subscriptions/service-subscription/(.+)/service-instances/service-instance/(.+)/"; + Pattern pattern = Pattern.compile(apnpattern); + + try { + URL url = new URL(selection); + String path = url.getPath(); + + LOG.info("Trying to match apn to <" + path + ">"); + + Matcher matcher = pattern.matcher(path); + + while(matcher.find()) { + String customer = matcher.group(1); + String subscription = matcher.group(2); + String service = matcher.group(3); + + encrypted_url = selection.replace(customer, encodeQuery(customer)); + encrypted_url = encrypted_url.replace(subscription, encodeQuery(subscription)); + encrypted_url = encrypted_url.replace(service, encodeQuery(service)); + } + } catch (Exception e) { + LOG.warn("", e); + } + + return encrypted_url; + } + + + + /* + * (non-Javadoc) + * @see org.onap.sdnct.sli.aai.AAIClient#requestVServersData(java.lang.String, java.lang.String) + */ + @Override + public Vserver requestVServerData(String tenantId, String vserverId, String cloudOwner, String cloudRegionId) throws AAIServiceException { + Vserver response = null; + + try { + AAIRequest request = AAIRequest.getRequestFromResource("vserver"); + request.addRequestProperty("cloud-region.cloud-owner", cloudOwner); + request.addRequestProperty("cloud-region.cloud-region-id", cloudRegionId); + request.addRequestProperty("tenant.tenant-id", tenantId); + request.addRequestProperty("vserver.vserver-id", vserverId); + + String rv = executor.get(request); + if(rv != null) { + ObjectMapper mapper = getObjectMapper(); + response = mapper.readValue(rv, Vserver.class); + } + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn(Object.class.getClass().getEnclosingMethod().getName(), exc); + throw new AAIServiceException(exc); + } + return response; + } + + + //================== End of DvsSwitch ================= + //==================== PhysicalLink ====================== + @Override + public PhysicalLink requestPhysicalLinkData(String linkName) throws AAIServiceException { + PhysicalLink response = null; + + try { + AAIRequest request = AAIRequest.getRequestFromResource("physical-link"); + request.addRequestProperty("physical-link.link-name", linkName); + + String rv = executor.get(request); + if(rv != null) { + ObjectMapper mapper = getObjectMapper(); + response = mapper.readValue(rv, PhysicalLink.class); + } + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("requestPhysicalLinkData", exc); + throw new AAIServiceException(exc); + } + return response; + } + + @Override + public boolean postPhysicalLinkData(String linkName, PhysicalLink data) throws AAIServiceException { + try { + AAIRequest request = AAIRequest.getRequestFromResource("physical-link"); + request.addRequestProperty("physical-link.link-name", linkName); + request.setRequestObject(data); + Object response = executor.post(request); + return true; + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn(Object.class.getClass().getEnclosingMethod().getName(), exc); + throw new AAIServiceException(exc); + } + } + + @Override + public boolean deletePhysicalLinkData(String linkName, String resourceVersion) throws AAIServiceException { + boolean response = false; + + try { + AAIRequest request = AAIRequest.getRequestFromResource("physical-link"); + request.addRequestProperty("physical-link.link-name", linkName); + response = executor.delete(request, resourceVersion); + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("deletePhysicalLinkData", exc); + throw new AAIServiceException(exc); + } + return response; + } + + public boolean deleteAAIEntity(URL url, String caller) throws AAIServiceException { + + if(url == null) { + throw new NullPointerException(); + } + + boolean response = false; + InputStream inputStream = null; + + try { + URL http_req_url = url; + + HttpURLConnection con = getConfiguredConnection(http_req_url, HttpMethod.DELETE); + + LOGwriteFirstTrace("DELETE", http_req_url.toString()); + + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + + // Process the response + LOG.debug("HttpURLConnection result:" + responseCode); + if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); + BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ); + String line = null; + + ObjectMapper mapper = getObjectMapper(); + + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + StringBuilder stringBuilder = new StringBuilder(); + + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append( line ); + } + LOGwriteEndingTrace(responseCode, "SUCCESS", stringBuilder.toString()); + response = true; + } else if(responseCode == HttpURLConnection.HTTP_NOT_FOUND ) { + LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", "Entry does not exist."); + response = false; + } else { + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse)); + throw new AAIServiceException(responseCode, errorresponse); + } + + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn(caller, exc); + throw new AAIServiceException(exc); + } finally { + if(inputStream != null){ + try { + inputStream.close(); + } catch(Exception exc) { + LOG.warn("Error closing InputStream", exc); + } + } + } + return response; + } + + /** + * Generic method to GET json data from an A&AI callback URL. + * Then convert that json to an Object. + * If successful the Object is attempted to be cast to the type parameter. + * + * @param key + * callback url for A&AI + * @param type + * the class of object that A&AI will return + * @return the object created from json or null if the response code is not 200 + * + * @throws AAIServiceException + * if empty or null key and or type or there's an error with processing + */ + public <T> T dataChangeRequestAaiData(String key, Class<T> type) throws AAIServiceException { + if (StringUtils.isEmpty(key) || type == null) { + throw new AAIServiceException("Key is empty or null and or type is null"); + } + + T response = null; + + SvcLogicContext ctx = new SvcLogicContext(); + if(!key.contains(" = ") && isValidURL(key)) { + key = String.format("selflink = '%s'", key); + } else + if(!key.contains(" = ") && isValidURI(key)) { + key = String.format("resource-path = '%s'", key); + } + + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + + SelfLinkRequest request = new SelfLinkRequest(type); + request.processRequestPathValues(nameValues); + Object obj = this.getExecutor().query(request, type); + response = type.cast(obj); + + return response != null ? type.cast(response) : response; + } + + + public boolean sendNotify(NotifyEvent event, String serviceInstanceId, String pathCode) throws AAIServiceException { + InputStream inputStream = null; + + try { + + String selfLink = selflinkFqdn; + if(SELFLINK_AVPN != null && SELFLINK_AVPN.equals(pathCode)) { + selfLink = selflinkAvpn; + } + selfLink = selfLink.replace("{service-instance-id}", encodeQuery(serviceInstanceId)); + event.setSelflink(selfLink); + + ObjectMapper mapper = getObjectMapper(); + String json_text = mapper.writeValueAsString(event); + + SSLSocketFactory sockFact = CTX.getSocketFactory(); + + String request_url = targetUri+ubb_notify_path; + URL http_req_url = new URL(request_url); + + HttpURLConnection con = getConfiguredConnection(http_req_url, HttpMethod.PUT); + + if (json_text != null) { + OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream()); + osw.write(json_text); + osw.flush(); + osw.close(); + } + + LOGwriteFirstTrace("PUT", request_url); + LOGwriteDateTrace("NotifyEvent", json_text); + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + + // Process the response + BufferedReader reader; + String line = null; + reader = new BufferedReader( new InputStreamReader( inputStream ) ); + + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + StringBuilder stringBuilder = new StringBuilder(); + + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append( line ); + } + LOGwriteEndingTrace(responseCode, "SUCCESS", (stringBuilder.length() > 0) ? stringBuilder.toString() : + "{no-data}"); + return true; + } else { + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse)); + + throw new AAIServiceException(responseCode, errorresponse); + } + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("sendNotify", exc); + throw new AAIServiceException(exc); + } finally { + try { + if(inputStream != null) + inputStream.close(); + } catch (Exception exc) { + LOG.warn("Error closing Input stream", exc); + } + } + } + + @Override + public SearchResults requestNodeQuery(String node_type, String entityIdentifier, String entityName) throws AAIServiceException { + SearchResults response = null; + InputStream inputStream = null; + + try { + String request_url = targetUri+queryNodesPath; + request_url = request_url.replace("{node-type}", encodeQuery(node_type)) ; + request_url = request_url.replace("{entity-identifier}", entityIdentifier) ; + request_url = request_url.replace("{entity-name}", encodeQuery(entityName)) ; + URL http_req_url = new URL(request_url); + + HttpURLConnection con = getConfiguredConnection(http_req_url, HttpMethod.GET); + + LOGwriteFirstTrace(HttpMethod.GET, http_req_url.toString()); + LOGwriteDateTrace("node_type", node_type); + LOGwriteDateTrace("vnf_name", entityName); + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + + // Process the response + LOG.debug("HttpURLConnection result:" + responseCode); + if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); + BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ); + + ObjectMapper mapper = getObjectMapper(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + response = mapper.readValue(reader, SearchResults.class); + LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, "SUCCESS", mapper.writeValueAsString(response)); + } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) { + LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", "Entry does not exist."); + return response; + } else { + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse)); + throw new AAIServiceException(responseCode, errorresponse); + } + + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("requestNodeQuery", exc); + throw new AAIServiceException(exc); + } finally { + if(inputStream != null){ + try { + inputStream.close(); + } catch(Exception exc) { + LOG.warn("Error closing Input stream", exc); + } + } + } + return response; + + } + + + @Override + public String requestDataByURL(URL url) throws AAIServiceException { + + if(url == null) { + throw new NullPointerException(); + } + + String response = null; + InputStream inputStream = null; + + try { + URL http_req_url = url; + + HttpURLConnection con = getConfiguredConnection(http_req_url, HttpMethod.GET); + + LOGwriteFirstTrace(HttpMethod.GET, http_req_url.toString()); + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + + // Process the response + LOG.debug("HttpURLConnection result:" + responseCode); + if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); + BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ); + + ObjectMapper mapper = getObjectMapper(); + + if (responseCode == HttpURLConnection.HTTP_OK) { + StringBuilder stringBuilder = new StringBuilder("\n"); + String line = null; + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append( line ); + } + LOG.info(stringBuilder.toString()); +// response = mapper.readValue(reader, String.class); + response = stringBuilder.toString(); + LOGwriteEndingTrace(HttpURLConnection.HTTP_OK, "SUCCESS", mapper.writeValueAsString(response)); + } else if(responseCode == HttpURLConnection.HTTP_NOT_FOUND ) { + LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", "Entry does not exist."); + response = null; + } else { + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse)); + throw new AAIServiceException(responseCode, errorresponse); + } + + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("requestNetworkVceData", exc); + throw new AAIServiceException(exc); + } finally { + if(inputStream != null){ + try { + inputStream.close(); + } catch(Exception exc) { + LOG.warn("Error closing Input stream", exc); + } + } + } + return response; + } + + + @Override + public GenericVnf requestGenericVnfeNodeQuery(String vnf_name) throws AAIServiceException { + + if(vnf_name == null) { + throw new NullPointerException(); + } + + GenericVnf entity = null; + SearchResults resp = this.requestNodeQuery("generic-vnf", "vnf-name", vnf_name); + + List<ResultData> resultDataList = resp.getResultData(); + + try { + for (ResultData datum : resultDataList) { + URI url = new URI(datum.getResourceLink()); + entity = this.getResource(url.toString(), GenericVnf.class); + } + } + catch (Exception e) + { + LOG.error("Caught exception", e); + } + return entity; + } + + @Override + public Vserver requestVServerDataByURL(URL url) throws AAIServiceException { + + if(url == null) { + throw new NullPointerException(); + } + + Vserver entity = null; + + try { + entity = this.getResource(url.toString(), Vserver.class); + } catch (AAIServiceException exc) { + throw exc; + } catch (Exception e) { + throw new AAIServiceException(e); + } + return entity; + } + + @Override + public URL requestVserverURLNodeQuery(String vserver_name) throws AAIServiceException { + + if(vserver_name == null) { + throw new NullPointerException(); + } + + URL entity = null; + SearchResults resp = this.requestNodeQuery("vserver", "vserver-name", vserver_name); + + List<ResultData> resultDataList = resp.getResultData(); + + try { + for (ResultData datum : resultDataList) { + String data_type = datum.getResourceType(); + String resourceLink = datum.getResourceLink(); + if(!resourceLink.isEmpty() && !resourceLink.toLowerCase().startsWith("http")) { + resourceLink = (new EchoRequest()).targetUri + resourceLink; + } + entity = new URL(resourceLink); + } + } catch (Exception e) { + throw new AAIServiceException(e); + } + return entity; + } + + @Override + public String getTenantIdFromVserverUrl(URL url) { + + String path = url.getPath(); + + String[] split = path.split("/tenants/tenant/"); + if(split.length > 1) { + split = split[1].split("/"); + return split[0]; + } else { + return null; + } + } + + @Override + public String getCloudOwnerFromVserverUrl(URL url) { + + String path = url.getPath(); + + String[] split = path.split("/cloud-regions/cloud-region/"); + if(split.length > 1) { + split = split[1].split("/"); + return split[0]; + } else { + return null; + } + } + + @Override + public String getCloudRegionFromVserverUrl(URL url) { + + String path = url.getPath(); + + String[] split = path.split("/cloud-regions/cloud-region/"); + if(split.length > 1) { + split = split[1].split("/"); + return split[1]; + } else { + return null; + } + } + + @Override + public String getVServerIdFromVserverUrl(URL url, String tenantId) { + String pattern = networkVserverPath; + pattern = pattern.replace("{tenant-id}", tenantId); + + int end = pattern.indexOf("{vserver-id}"); + String prefix = pattern.substring(0, end); + + String path = url.getPath(); + + if(path.startsWith(prefix)) { + path = path.substring(prefix.length()); + } + + return path; + } + + protected Logger getLogger(){ + return LOG; + } + + + @Override + public AAIExecutorInterface getExecutor() { + return executor; + } + + /** + * Creates a current time stamp in UTC i.e. 2016-03-08T22:15:13.343Z. + * If there are any parameters the values are appended to the time stamp. + * + * @param parameters + * values to be appended to current time stamp + * @param ctx + * used to set an attribute for a DG + * @throws SvcLogicException + */ + public void setStatusMethod(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException { + if (ctx == null) { + throw new SvcLogicException("SvcLogicContext is null."); + } + + StringBuilder sb = new StringBuilder(); + sb.append(String.format("%tFT%<tTZ", Calendar.getInstance(TimeZone.getTimeZone("Z")))).append(" - "); + + for (Entry<String, String> entry : parameters.entrySet()) { + sb.append(entry.getValue()).append(" "); + } + + if (sb.length() > 0) { + sb.setLength(sb.length() - 2); + } + + ctx.setAttribute("aai-summary-status-message", sb.toString()); + LOG.info("aai-summary-status-message: " + sb.toString()); + } + + /** + * Generic method to GET json data from an A&AI using key structure. + * Then convert that json to an Object. + * If successful the Object is attempted to be cast to the type parameter. + * + * @param key + * key identifying the resource to be retrieved from AAI + * @param type + * the class of object that A&AI will return + * @return the object created from json or null if the response code is not 200 + * + * @throws AAIServiceException + * if empty or null key and or type or there's an error with processing + */ + + public <T> T getResource(String key, Class<T> type) throws AAIServiceException { + if (StringUtils.isEmpty(key) || type == null) { + throw new AAIServiceException("Key is empty or null and or type is null"); + } + + T response = null; + + SvcLogicContext ctx = new SvcLogicContext(); + if(!key.contains(" = ")) { + if(isValidURL(key)) { + key = String.format("selflink = '%s'", key); + } else if(isValidURI(key)) { + key = String.format("resource-path = '%s'", key); + } else { + return response; + } + } + + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + + AAIRequest request = new SelfLinkRequest(type); + if(nameValues.containsKey(PathRequest.RESOURCE_PATH.replaceAll("-", "_"))) { + request = new PathRequest(type); + } + + request.processRequestPathValues(nameValues); + Object obj = this.getExecutor().query(request, type); + response = type.cast(obj); + + return response != null ? type.cast(response) : response; + } + + public boolean isValidURL(String url) { + + URL u = null; + + try { + u = new URL(url); + } catch (MalformedURLException e) { + LOG.warn("MalformedURLException", e); + return false; + } + + try { + u.toURI(); + } catch (URISyntaxException e) { + LOG.warn("URISyntaxException", e); + return false; + } + + return true; + } + + + public boolean isValidURI(String url) { + + URI u = null; + + try { + u = new URI(url); + } catch (URISyntaxException e) { + LOG.warn("URISyntaxException", e); + return false; + } + + return true; + } + + + protected boolean deleteList(URL httpReqUrl, String jsonText) throws AAIServiceException { + if(httpReqUrl == null) { + throw new NullPointerException(); + } + + boolean response = false; + InputStream inputStream = null; + + try { + HttpURLConnection con = getConfiguredConnection(httpReqUrl, HttpMethod.DELETE); + +// SSLSocketFactory sockFact = CTX.getSocketFactory(); +// con.setSSLSocketFactory( sockFact ); + if (jsonText != null) { + OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream()); + osw.write(jsonText); + osw.flush(); + osw.close(); + } + + LOGwriteFirstTrace("DELETE", httpReqUrl.toString()); + LOGwriteDateTrace("data", jsonText); + + // Check for errors + int responseCode = con.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + + // Process the response + LOG.debug("HttpURLConnection result:" + responseCode); + if(inputStream == null) inputStream = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); + BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream ) ); + String line = null; + + ObjectMapper mapper = getObjectMapper(); + + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_NO_CONTENT) { + StringBuilder stringBuilder = new StringBuilder(); + + while( ( line = reader.readLine() ) != null ) { + stringBuilder.append( line ); + } + LOGwriteEndingTrace(responseCode, "SUCCESS", stringBuilder.toString()); + response = true; + } else if(responseCode == HttpURLConnection.HTTP_NOT_FOUND ) { + LOGwriteEndingTrace(responseCode, "HTTP_NOT_FOUND", "Entry does not exist."); + response = false; + } else { + ErrorResponse errorresponse = mapper.readValue(reader, ErrorResponse.class); + LOGwriteEndingTrace(responseCode, "FAILURE", mapper.writeValueAsString(errorresponse)); + throw new AAIServiceException(responseCode, errorresponse); + } + + } catch(AAIServiceException aaiexc) { + throw aaiexc; + } catch (Exception exc) { + LOG.warn("deleteList", exc); + throw new AAIServiceException(exc); + } finally { + if(inputStream != null){ + try { + inputStream.close(); + } catch(Exception exc) { + + } + } + } + return response; + } + + public static ObjectMapper getObjectMapper() { + ObjectMapper mapper = new ObjectMapper(); + AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()); + AnnotationIntrospector secondary = new JacksonAnnotationIntrospector(); + mapper.setAnnotationIntrospector(AnnotationIntrospector.pair(introspector, secondary)); + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + mapper.setSerializationInclusion(Include.NON_NULL); + mapper.setSerializationInclusion(Include.NON_EMPTY); + return mapper; + } + + public void logMetricRequest(String requestId, String targetServiceName, String msg, String path){ + String svcInstanceId = ""; + String svcName = null; + String partnerName = null; + String targetEntity = "A&AI"; + String targetVirtualEntity = null; + + ml.logRequest(svcInstanceId, svcName, partnerName, targetEntity, targetServiceName, targetVirtualEntity, msg); + } + + public void logMetricResponse(String requestId, int responseCode, String responseDescription){ + ml.logResponse(responseCode < 400 ? "COMPLETE" : "ERROR", Integer.toString(responseCode), responseDescription); + } + + public void logKeyError(String keys){ + LOG.error("Atleast one of the keys [" + keys + "] should have been populated. This will cause a NPE."); + } + + + /** + * Retrofit code + */ + @Override + public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + String normResource = resource.split(":")[0]; + + switch(normResource){ + case "custom-query": + case "formatted-query": + case "generic-query": + case "nodes-query": + case "linterface": + case "l2-bridge-sbg": + case "l2-bridge-bgf": + case "echo": + case "test": + break; + + default: + if(key.contains("selflink =")) { + break; + } + if(!key.contains(String.format("%s.", normResource))) { + key = rewriteKey(resource, key, ctx); + } + } + return super.save(resource, force, localOnly, key, params, prefix, ctx); + } + + @Override + public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) + throws SvcLogicException { + String normResource = resource.split(":")[0]; + + switch(normResource){ + case "custom-query": + case "formatted-query": + case "generic-query": + case "nodes-query": + case "linterface": + case "l2-bridge-sbg": + case "l2-bridge-bgf": + case "echo": + case "test": + break; + + default: + if(key.contains("selflink =")) { + break; + } + if(!key.contains(String.format("%s.", normResource))) { + key = rewriteKey(resource, key, ctx); + } + } + + return super.query(resource, localOnly, select, key, prefix, orderBy, ctx); + } + + @Override + public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException { + String normResource = resource.split(":")[0]; + + switch(normResource){ + case "custom-query": + case "formatted-query": + case "generic-query": + case "nodes-query": + case "linterface": + case "l2-bridge-sbg": + case "l2-bridge-bgf": + case "echo": + case "test": + break; + + default: + if(key.contains("selflink =")) { + break; + } + if(!key.contains(String.format("%s.", normResource))) { + key = rewriteKey(resource, key, ctx); + } + } + + return super.delete(resource, key, ctx); + } + + @Override + public QueryStatus update(String resource, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) throws SvcLogicException { + String normResource = resource.split(":")[0]; + + switch(normResource){ + case "custom-query": + case "formatted-query": + case "generic-query": + case "nodes-query": + case "linterface": + case "l2-bridge-sbg": + case "l2-bridge-bgf": + case "echo": + case "test": + break; + + default: + if(key.contains("selflink =")) { + break; + } + if(!key.contains(String.format("%s.", normResource))) { + key = rewriteKey(resource, key, ctx); + } + } + + return super.update(resource, key, params, prefix, ctx); + } + + private String rewriteKey(String resource, String key, SvcLogicContext ctx) { + LOG.info("AAI Deprecation - the format of request key is no longer supported. Please rewrite this key : " + key); + + String normResource = resource.split(":")[0]; + Class<? extends AAIDatum> clazz = AAIRequest.getClassFromResource(normResource) ; + + if(clazz == null) + return key; + + List<String> fieldAnnotatedNames = new LinkedList<>(); + + Field[] fields = clazz.getDeclaredFields(); + for(Field field : fields) { + String fieldName = field.getName(); + XmlElement annotation = field.getAnnotation(XmlElement.class); + if(annotation == null) + continue; + String primaryId = annotation.name(); + if("##default".equals(primaryId)) { + primaryId = fieldName; + } + fieldAnnotatedNames.add(primaryId); + } + + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + Set<String> keyset = nameValues.keySet(); + for(String keyName : keyset) { + if(keyName.contains(".")) + continue; + else { + String tmpKeyName = keyName.replaceAll("_", "-"); + String valueToSubstitute = String.format("%s =", tmpKeyName); + if(fieldAnnotatedNames.contains(tmpKeyName) && key.contains(valueToSubstitute)) { + key = key.replace(valueToSubstitute, String.format("%s.%s =", normResource, tmpKeyName)); + } + } + } + + + return key; + } + + @Override + public String getPathTemplateForResource(String resoourceName, String keys, SvcLogicContext ctx) throws MalformedURLException { + return AAIServiceUtils.getPathForResource(resoourceName, StringUtils.join(keys, " AND "), ctx); + } + + @Override + public boolean isDeprecatedFormat(String resource, Map<String, String> nameValues) { + return !AAIServiceUtils.isValidFormat(resource, nameValues); + } + + public AAIRequest getRequestFromResource(String resoourceName) { + return AAIRequest.getRequestFromResource(resoourceName); + } + + /* (non-Javadoc) + * @see org.onap.ccsdk.sli.core.sli.aai.haha#query(org.onap.ccsdk.sli.core.sli.aai.AAIRequest) + */ + @Override + public String query(AAIRequest request) throws AAIServiceException { + return executor.get(request); + } + + /* (non-Javadoc) + * @see org.onap.ccsdk.sli.core.sli.aai.haha#save(org.onap.ccsdk.sli.core.sli.aai.AAIRequest) + */ + @Override + public String save(AAIRequest request) throws AAIServiceException { + return executor.post(request); + } + + public boolean update(AAIRequest request, String resourceVersion) throws AAIServiceException { + return executor.patch(request, resourceVersion); + } + + /* (non-Javadoc) + * @see org.onap.ccsdk.sli.core.sli.aai.haha#delete(org.onap.ccsdk.sli.core.sli.aai.AAIRequest, java.lang.String) + */ + @Override + public boolean delete(AAIRequest request, String resourceVersion) throws AAIServiceException { + return executor.delete(request, resourceVersion); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceException.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceException.java new file mode 100755 index 000000000..2f774e407 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceException.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import org.onap.ccsdk.sli.adaptors.aai.data.ErrorResponse; + +public class AAIServiceException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -9039257722542999522L; + + protected final ErrorResponse errorResponse; + protected final int returnCode; + + public AAIServiceException() { + returnCode = -1; + errorResponse = null; + } + + public AAIServiceException(String message) { + super(message); + returnCode = -1; + errorResponse = null; + } + + public AAIServiceException(Throwable cause) { + super(cause); + returnCode = -1; + errorResponse = null; + } + + public AAIServiceException(String message, Throwable cause) { + super(message, cause); + returnCode = -1; + errorResponse = null; + } + + public AAIServiceException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + returnCode = -1; + errorResponse = null; + } + + public AAIServiceException(int returnCode, ErrorResponse errorresponse) { + this.errorResponse = errorresponse; + this.returnCode = returnCode; + } + + public ErrorResponse getErrorResponse() { + return errorResponse; + } + + public int getReturnCode() { + return returnCode; + } + + public String getMessage() { + if(errorResponse != null) { + return errorResponse.getRequestError().getServiceException().getText(); + } else { + return super.getMessage(); + } + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceProvider.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceProvider.java new file mode 100755 index 000000000..743f975b6 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceProvider.java @@ -0,0 +1,226 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 - 2018 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Optional; +import java.util.Properties; +import java.util.Vector; + +import org.onap.ccsdk.sli.core.utils.JREFileResolver; +import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver; +import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver; +import org.onap.ccsdk.sli.core.utils.common.BundleContextFileResolver; +import org.onap.ccsdk.sli.core.utils.common.CoreDefaultFileResolver; +import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Responsible for determining the properties file to use and instantiating the <code>DBResourceManager</code> + * Service. The priority for properties file resolution is as follows: + * + * <ol> + * <li>A directory identified by the system environment variable <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument <code>dblib.properties</code></li> + * <li>A <code>dblib.properties</code> file located in the karaf root directory</li> + * </ol> + * + * Encryption Support + * <ol> + * <li>Uses ecryption provided by <code>AAAEncryptionService</code></li> + * <li>AAA Configuration file is <code>aaa-cert-config.xml</code></li> + * </ol> + * + */ +public class AAIServiceProvider implements UtilsProvider { + + private static final Logger LOG = LoggerFactory.getLogger(AAIServiceProvider.class); + + /** + * The name of the properties file for database configuration + */ + private static final String AAISEERVICE_PROP_FILE_NAME = "aaiclient.properties"; + + /** + * The name of the pwd key + */ + private static final String AAICLIENT_PROPERTY_NAME = "org.onap.ccsdk.sli.adaptors.aai.client.psswd"; + + /** + * A prioritized list of strategies for resolving dblib properties files. + */ + private Vector<PropertiesFileResolver> dblibPropertiesFileResolvers = new Vector<>(); + + /** + * The configuration properties for the db connection. + */ + private Properties properties; + + /** + * Set up the prioritized list of strategies for resolving dblib properties files. + */ + public AAIServiceProvider() { + dblibPropertiesFileResolvers.add(new SdncConfigEnvVarFileResolver( + "Using property file (1) from environment variable" + )); + dblibPropertiesFileResolvers.add(new JREFileResolver( + "Using property file (2) from JRE argument", AAIServiceProvider.class + )); + dblibPropertiesFileResolvers.add(new BundleContextFileResolver( + "Using property file (3) from JRE argument", AAIServiceProvider.class + )); + dblibPropertiesFileResolvers.add(new KarafRootFileResolver( + "Using property file (4) from karaf root", this + )); + dblibPropertiesFileResolvers.add(new CoreDefaultFileResolver( + "Using property file (5) from default directory" + )); + + // determines properties file as according to the priority described in the class header comment + final File propertiesFile = determinePropertiesFile(); + if (propertiesFile != null) { + try(FileInputStream fileInputStream = new FileInputStream(propertiesFile)) { + properties = new Properties(); + properties.load(fileInputStream); + + if(properties.containsKey(AAICLIENT_PROPERTY_NAME)) { + String sensitive = properties.getProperty(AAICLIENT_PROPERTY_NAME); + if(sensitive != null && sensitive.startsWith("ENC:")) { + try { + sensitive = sensitive.substring(4); + String postsense = decrypt(sensitive); + properties.setProperty(AAICLIENT_PROPERTY_NAME, postsense); + } catch(Exception exc) { + LOG.error("Failed to translate property", exc); + } + } + } + } catch (final IOException e) { + LOG.error("Failed to load properties for file: {}", propertiesFile.toString(), + new AAIServiceException("Failed to load properties for file: " + + propertiesFile.toString(), e)); + } + } + } + + /** + * + * @param value + * @return decrypted string if successful or the original value if unsuccessful + */ + private String decrypt(String value) { + try { + BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + + ServiceReference sref = bctx.getServiceReference("org.opendaylight.aaa.encrypt.AAAEncryptionService"); + if(sref == null) { + LOG.warn("Could not acquire service reference for 'org.opendaylight.aaa.encrypt.AAAEncryptionService'"); + return value; + } + Object encrSvc = bctx.getService(sref); + if(encrSvc == null) { + LOG.warn("Could not access service for 'org.opendaylight.aaa.encrypt.AAAEncryptionService'"); + return value; + } + + Method gs2Method = encrSvc.getClass().getMethod("decrypt", new Class[] { "".getClass() }); + Object unmasked = gs2Method.invoke(encrSvc, new Object[] { value }); + return unmasked.toString(); + + } catch (Exception|NoClassDefFoundError exc) { + LOG.error("Failure", exc); + return value; + } + } + + /** + * Extract db config properties. + * + * @return the db config properties + */ + public Properties getProperties() { + return properties; + } + + /** + * Reports the method chosen for properties resolution to the <code>Logger</code>. + * + * @param message Some user friendly message + * @param fileOptional The file location of the chosen properties file + * @return the file location of the chosen properties file + */ + private static File reportSuccess(final String message, final Optional<File> fileOptional) { + if(fileOptional.isPresent()) { + final File file = fileOptional.get(); + LOG.info("{} {}", message, file.getPath()); + return file; + } + return null; + } + + /** + * Reports fatal errors. This is the case in which no properties file could be found. + * + * @param message An appropriate fatal error message + * @param dblibConfigurationException An exception describing what went wrong during resolution + */ + private static void reportFailure(final String message, + final AAIServiceException dblibConfigurationException) { + + LOG.error("{}", message, dblibConfigurationException); + } + + /** + * Determines the dblib properties file to use based on the following priority: + * <ol> + * <li>A directory identified by the system environment variable <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument <code>dblib.properties</code></li> + * <li>A <code>dblib.properties</code> file located in the karaf root directory</li> + * </ol> + */ + File determinePropertiesFile() { + + for (final PropertiesFileResolver dblibPropertiesFileResolver : dblibPropertiesFileResolvers) { + final Optional<File> fileOptional = dblibPropertiesFileResolver.resolveFile(AAISEERVICE_PROP_FILE_NAME); + if (fileOptional.isPresent()) { + return reportSuccess(dblibPropertiesFileResolver.getSuccessfulResolutionMessage(), fileOptional); + } + } + + reportFailure("Missing configuration properties resource(3)", + new AAIServiceException("Missing configuration properties resource(3): " + + AAISEERVICE_PROP_FILE_NAME)); + return null; + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceUtils.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceUtils.java new file mode 100755 index 000000000..b3ee7474d --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceUtils.java @@ -0,0 +1,394 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.xml.bind.annotation.XmlType; + +import org.apache.commons.lang.StringUtils; +import org.onap.aai.inventory.v21.Relationship; +import org.onap.aai.inventory.v21.RelationshipData; +import org.onap.aai.inventory.v21.RelationshipList; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AAIServiceUtils { + + private static final String VERSION_PATTERN = "/v$/"; + + private static final Logger LOG = LoggerFactory.getLogger(AAIService.class); + + private AAIServiceUtils() { + } + + public static String getPrimaryIdFromClass(Class<? extends AAIDatum> resourceClass){ + // 1. find class + getLogger().debug(resourceClass.getName()); + + try { + Annotation[] annotations = resourceClass.getAnnotations(); + for(Annotation annotation : annotations) { + Class<? extends Annotation> anotationType = annotation.annotationType(); + String annotationName = anotationType.getName(); + + // 2. find string property setters and getters for the lists + if("javax.xml.bind.annotation.XmlType".equals(annotationName)){ + XmlType order = (XmlType)annotation; + String[] values = order.propOrder(); + for(String value : values) { + String id = camelCaseToDashedString(value); + return id; + } + } + } + } catch(Exception exc) { + getLogger().warn("getPrimaryIdFromClass failed", exc); + } + return null; + } + + public static String getSecondaryIdFromClass(Class<? extends AAIDatum> resourceClass){ + getLogger().debug(resourceClass.getName()); + + try { + Annotation[] annotations = resourceClass.getAnnotations(); + for(Annotation annotation : annotations) { + Class<? extends Annotation> anotationType = annotation.annotationType(); + String annotationName = anotationType.getName(); + + // 2. find string property setters and getters for the lists + if("javax.xml.bind.annotation.XmlType".equals(annotationName)){ + boolean primaryIdFound = false; + XmlType order = (XmlType)annotation; + String[] values = order.propOrder(); + for(String value : values) { + String id = camelCaseToDashedString(value); + if(primaryIdFound) { + return id; + } else { + primaryIdFound = true; + } + } + } + } + } catch(Exception exc) { + + } + return null; + } + + public static Method getRelationshipListGetterMethodFromClassDefinition(Class resourceClass) { + Method getRelationshipListMethod = null; + + try { + getRelationshipListMethod = resourceClass.getMethod("getRelationshipList"); + } catch(Exception exc) { + getLogger().debug("Retrofiting relationship data: " + exc.getMessage()); + } + return getRelationshipListMethod; + } + + private static Logger getLogger() { + return LOG; + } + + + private static final String regex = "([A-Z][a-z,0-9]+)"; + private static final String replacement = "-$1"; + + public static String camelCaseToDashedString(String propOrder) { + return propOrder.replaceAll(regex, replacement).toLowerCase(); + } + + public static HashMap<String,String> keyToHashMap(String key, SvcLogicContext ctx) { + if (key == null) { + return (null); + } + + getLogger().debug("Converting key [" + key + "] to where clause"); + + if (key.startsWith("'") && key.endsWith("'")) { + key = key.substring(1, key.length() - 1); + + getLogger().debug("Stripped outer single quotes - key is now [" + key + "]"); + } + + String[] keyTerms = key.split("\\s+"); + + StringBuffer whereBuff = new StringBuffer(); + String term1 = null; + String op = null; + String term2 = null; + HashMap<String, String> results = new HashMap<>(); + + for (int i = 0; i < keyTerms.length; i++) { + if (term1 == null) { + if ("and".equalsIgnoreCase(keyTerms[i]) + || "or".equalsIgnoreCase(keyTerms[i])) { + // Skip over ADD/OR + } else { + term1 = resolveTerm(keyTerms[i], ctx); + } + } else if (op == null) { + if ("==".equals(keyTerms[i])) { + op = "="; + } else { + op = keyTerms[i]; + } + } else { + term2 = resolveTerm(keyTerms[i], ctx); + term2 = term2.trim().replace("'", "").replace("$", "").replace("'", ""); + results.put(term1, term2); + + term1 = null; + op = null; + term2 = null; + } + } + + return (results); + } + + private static String resolveTerm(String term, SvcLogicContext ctx) { + if (term == null) { + return (null); + } + + getLogger().debug("resolveTerm: term is " + term); + + if (term.startsWith("$") && (ctx != null)) { + // Resolve any index variables. + + term = ("'" + resolveCtxVariable(term.substring(1), ctx) + "'"); + if (term.contains(VERSION_PATTERN) && (ctx != null)) { + return term.replace(VERSION_PATTERN, AAIRequest.getSupportedAAIVersion()); + } + return term; + } else if (term.contains(VERSION_PATTERN) && (ctx != null)) { + return term.replace(VERSION_PATTERN, AAIRequest.getSupportedAAIVersion()); + } else if (term.startsWith("'") || term.startsWith("\"")) { + return (term); + } else { + return (term.replaceAll("-", "_")); + + } + } + + private static String resolveCtxVariable(String ctxVarName, SvcLogicContext ctx) { + + if (ctxVarName.indexOf('[') == -1) { + // Ctx variable contains no arrays + return (ctx.getAttribute(ctxVarName)); + } + + // Resolve any array references + StringBuffer sbuff = new StringBuffer(); + String[] ctxVarParts = ctxVarName.split("\\["); + sbuff.append(ctxVarParts[0]); + for (int i = 1; i < ctxVarParts.length; i++) { + if (ctxVarParts[i].startsWith("$")) { + int endBracketLoc = ctxVarParts[i].indexOf("]"); + if (endBracketLoc == -1) { + // Missing end bracket ... give up parsing + getLogger().warn("Variable reference " + ctxVarName + + " seems to be missing a ']'"); + return (ctx.getAttribute(ctxVarName)); + } + + String idxVarName = ctxVarParts[i].substring(1, endBracketLoc); + String remainder = ctxVarParts[i].substring(endBracketLoc); + + sbuff.append("["); + sbuff.append(ctx.getAttribute(idxVarName)); + sbuff.append(remainder); + + } else { + // Index is not a variable reference + sbuff.append("["); + sbuff.append(ctxVarParts[i]); + } + } + + return (ctx.getAttribute(sbuff.toString())); + } + + public static void populateRelationshipDataFromPath(RelationshipList rl) throws URISyntaxException { + List<Relationship> list = rl.getRelationship(); + if(list != null && !list.isEmpty()) { + for(Relationship relationship : list) { + if(relationship.getRelationshipData().isEmpty()){ + String link = relationship.getRelatedLink(); + URI uri = new URI(link); + link = uri.getPath(); + HashMap<String,String> contributors = pathToHashMap(link); + for(String key : contributors.keySet()) { + RelationshipData rd = new RelationshipData(); + rd.setRelationshipKey(key); + rd.setRelationshipValue(contributors.get(key)); + relationship.getRelationshipData().add(rd); + } + } + } + } + } + + protected static HashMap<String,String> pathToHashMap(String path) { + HashMap<String, String> nameValues = new HashMap<>(); + + String[] split = path.split("/"); + + LinkedList<String> list = new LinkedList<String>( Arrays.asList(split)); + Iterator<String> it = list.iterator(); + + while(it.hasNext()) { + String tag = it.next(); + if(!tag.isEmpty()) { + if(AAIRequest.getResourceNames().contains(tag)){ + LOG.info(tag); + // get the class from tag + Class<? extends AAIDatum> clazz = AAIRequest.getClassFromResource(tag); + String fieldName = AAIServiceUtils.getPrimaryIdFromClass(clazz); + + String value = it.next(); + if(!StringUtils.isEmpty(value)){ + nameValues.put(String.format("%s.%s", tag, fieldName), value); + switch(tag) { + case "cloud-region": + case "entitlement": + case "license": + case "route-target": + case "service-capability": + case "ctag-pool": + String secondaryFieldName = AAIServiceUtils.getSecondaryIdFromClass(clazz); + if(secondaryFieldName != null) { + value = it.next(); + nameValues.put(String.format("%s.%s", tag, secondaryFieldName), value); + } + break; + default: + break; + } + } + } + } + } + return nameValues; + } + + public static String getPathForResource(String resource, String key, SvcLogicContext ctx ) throws MalformedURLException{ + HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx); + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + + for(String name : nameValues.keySet()) { + request.addRequestProperty(name, nameValues.get(name)); + } + return request.getRequestPath(); + } + + public static boolean isValidFormat(String resource, Map<String, String> nameValues) { + + switch(resource){ + case "custom-query": + case "formatted-query": + case "generic-query": + case "nodes-query": + case "linterface": + case "l2-bridge-sbg": + case "l2-bridge-bgf": + case "echo": + case "test": + return true; + } + if(resource.contains(":")) { + resource = resource.substring(0, resource.indexOf(":")); + } + + Set<String> keys = nameValues.keySet(); + for(String key : keys) { + if(!key.contains(".")) { + if("depth".equals(key) || "related-to".equals(key) || "related_to".equals(key) || "related-link".equals(key) || "related_link".equals(key) || "selflink".equals(key) || "resource_path".equals(key)) + continue; + else { + getLogger().warn(String.format("key '%s' is incompatible with resource type '%s'", key, resource)); + } + } + } + return true; + } + + public static boolean containsResource(String resource, HashMap<String, String> nameValues) { + if(resource.contains(":")) { + return true; + } + + switch(resource){ + case "custom-query": + case "formatted-query": + case "generic-query": + case "nodes-query": + case "linterface": + case "l2-bridge-sbg": + case "l2-bridge-bgf": + case "echo": + case "test": + return true; + + default: + if(nameValues.containsKey("selflink")) { + return true; + } + } + + Set<String> tags = new HashSet<>(); + + for(String key : nameValues.keySet()) { + key = key.replace("_", "-"); + if(key.contains(".")) { + String[] split = key.split("\\."); + tags.add(split[0]); + } else { + tags.add(key); + } + } + return tags.contains(resource); + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAITrinityService.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAITrinityService.java new file mode 100755 index 000000000..d1abda13d --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/AAITrinityService.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AAITrinityService extends AAIService { + + private static final Logger LOG = LoggerFactory.getLogger(AAITrinityService.class); + + public AAITrinityService(UtilsProvider configuration) { + super(configuration); + LOG.info("Entered AAITrinityService.ctor"); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/CustomQueryRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/CustomQueryRequest.java new file mode 100755 index 000000000..a99e6d5ef --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/CustomQueryRequest.java @@ -0,0 +1,138 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * Modifications Copyright (C) 2018 IBM. + * Modifications Copyright (C) 2019 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Properties; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.ccsdk.sli.adaptors.aai.query.FormattedQueryRequestData; +import org.onap.ccsdk.sli.adaptors.aai.query.FormattedQueryResultList; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + + +public class CustomQueryRequest extends AAIRequest { + + public static final String GENERIC_SEARCH_PATH_CONST = "org.onap.ccsdk.sli.adaptors.aai.query.generic"; + + private final String generic_search_path; + + public static final String FORMAT = "format"; + + + public CustomQueryRequest() { + String tmpGenericSearchPath = configProperties.getProperty(GENERIC_SEARCH_PATH_CONST); + tmpGenericSearchPath = tmpGenericSearchPath.split("search")[0]; + generic_search_path = tmpGenericSearchPath +"query"; + } + + + @Override + public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException { + + String requestUrl = targetUri+generic_search_path; + + requestUrl = processPathData(requestUrl, requestProperties); + + String formatQuery = requestProperties.getProperty(FORMAT); + + if(formatQuery != null) { + requestUrl = requestUrl +"?format="+formatQuery; + } + URL httpReqUrl = new URL(requestUrl); + + aaiService.LOGwriteFirstTrace(method, httpReqUrl.toString()); + + return httpReqUrl; + } + + @Override + public URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException { + return getRequestUrl(method, null); + } + + + @Override + public String toJSONString() { + ObjectMapper mapper = getObjectMapper(); + FormattedQueryRequestData tenant = (FormattedQueryRequestData)requestDatum; + String jsonText = null; + try { + jsonText = mapper.writeValueAsString(tenant); + } catch (JsonProcessingException exc) { + handleException(this, exc); + return null; + } + return jsonText; + } + + + @Override + public String[] getArgsList() { + String[] args = {FORMAT}; + return args; + } + + + @Override + public Class<? extends AAIDatum> getModelClass() { + return FormattedQueryRequestData.class; + } + + + public static String processPathData(String requestUrl, Properties requestProperties) throws UnsupportedEncodingException { + + String key = FORMAT; + + String encodedVnf = encodeQuery(requestProperties.getProperty(key)); + requestUrl = requestUrl.replace("{identifier}", encodedVnf) ; + aaiService.LOGwriteDateTrace("identifier", requestProperties.getProperty(key)); + + return requestUrl; + } + + @Override + public AAIDatum jsonStringToObject(String jsonData) throws IOException { + if(jsonData == null) { + return null; + } + + AAIDatum response = null; + ObjectMapper mapper = getObjectMapper(); + response = mapper.readValue(jsonData, FormattedQueryResultList.class); + return response; + } + + protected boolean expectsDataFromPUTRequest() { + return true; + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/EchoRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/EchoRequest.java new file mode 100755 index 000000000..8e6af0100 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/EchoRequest.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.ccsdk.sli.adaptors.aai.data.EchoResponse; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class EchoRequest extends AAIRequest { + + + + private final String echoPath; + + public EchoRequest() { + echoPath = "/aai/util/echo"; + } + + + @Override + public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException { + + String requestUrl = targetUri+echoPath; + + if(resourceVersion != null) { + requestUrl = requestUrl +"?resource-version="+resourceVersion; + } + URL httpReqUrl = new URL(requestUrl); + + aaiService.LOGwriteFirstTrace(method, httpReqUrl.toString()); + + return httpReqUrl; + } + + @Override + public URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException { + return getRequestUrl(method, null); + } + + + @Override + public String toJSONString() { + ObjectMapper mapper = getObjectMapper(); + EchoResponse tenant = (EchoResponse)requestDatum; + String jsonText = null; + try { + jsonText = mapper.writeValueAsString(tenant); + } catch (JsonProcessingException exc) { + handleException(this, exc); + return null; + } + return jsonText; + } + + + @Override + public String[] getArgsList() { + String[] args = {}; + return args; + } + + + @Override + public Class<? extends AAIDatum> getModelClass() { + return EchoResponse.class; + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/GenericQueryRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/GenericQueryRequest.java new file mode 100755 index 000000000..29fe24ef2 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/GenericQueryRequest.java @@ -0,0 +1,128 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Properties; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.aai.inventory.v21.ResultData; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class GenericQueryRequest extends AAIRequest { + + public static final String GENERIC_SEARCH_PATH = "org.onap.ccsdk.sli.adaptors.aai.query.generic"; + + private final String generic_search_path; + + public static final String START_NODE_TYPE = "start-node-type"; + public static final String IDENTIFIER = "identifier"; + public static final String VALUE = "value"; + + + public GenericQueryRequest() { + generic_search_path = configProperties.getProperty(GENERIC_SEARCH_PATH); + } + + @Override + public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException { + + String request_url = targetUri+generic_search_path; + + request_url = processPathData(request_url, requestProperties); + + if(resourceVersion != null) { + request_url = request_url +"?resource-version="+resourceVersion; + } + URL http_req_url = new URL(request_url); + + aaiService.LOGwriteFirstTrace(method, http_req_url.toString()); + + return http_req_url; + } + + @Override + public URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException { + return getRequestUrl(method, null); + } + + + @Override + public String toJSONString() { + ObjectMapper mapper = getObjectMapper(); + ResultData tenant = (ResultData)requestDatum; + String json_text = null; + try { + json_text = mapper.writeValueAsString(tenant); + } catch (JsonProcessingException exc) { + handleException(this, exc); + return null; + } + return json_text; + } + + + @Override + public String[] getArgsList() { + String[] args = {START_NODE_TYPE, IDENTIFIER, VALUE}; + return args; + } + + + @Override + public Class<? extends AAIDatum> getModelClass() { + return ResultData.class; + } + + + public static String processPathData(String request_url, Properties requestProperties) throws UnsupportedEncodingException { + + String key = IDENTIFIER; + + String encoded_vnf = encodeQuery(requestProperties.getProperty(key)); + request_url = request_url.replace("{identifier}", encoded_vnf) ; + aaiService.LOGwriteDateTrace(IDENTIFIER, requestProperties.getProperty(key)); + + key = VALUE; + + encoded_vnf = encodeQuery(requestProperties.getProperty(key)); + request_url = request_url.replace("{value}", encoded_vnf) ; + aaiService.LOGwriteDateTrace(VALUE, requestProperties.getProperty(key)); + + key = START_NODE_TYPE; + + encoded_vnf = encodeQuery(requestProperties.getProperty(key)); + request_url = request_url.replace("{start-node-type}", encoded_vnf) ; + aaiService.LOGwriteDateTrace(START_NODE_TYPE, requestProperties.getProperty(key)); + + return request_url; + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/GenericRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/GenericRequest.java new file mode 100755 index 000000000..604dd0e5c --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/GenericRequest.java @@ -0,0 +1,265 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * 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========================================================= + */ + /** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.UnsupportedEncodingException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.aai.inventory.v21.L3Network; +import org.onap.aai.inventory.v21.L3Networks; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Joiner; + +public class GenericRequest extends AAIRequest { + + + protected Class<? extends AAIDatum> model; + + public GenericRequest(Class<? extends AAIDatum> clazz) { + model = clazz; + } + + @Override + public String updatePathDataValues(Object resourceVersion) throws UnsupportedEncodingException, MalformedURLException { + + String originalPath = null; + String pathSubstitute = null; + String resourceName = null; + + Annotation[] annotations = model.getAnnotations(); + for(Annotation annotation : annotations) { + Class<? extends Annotation> anotationType = annotation.annotationType(); + String annotationName = anotationType.getName(); + if("javax.xml.bind.annotation.XmlRootElement".equals(annotationName)){ + XmlRootElement order = (XmlRootElement)annotation; + resourceName = order.name(); + } + } + + String request_url = getRequestPath(resourceName); + + Map<String, String> queryParams = new HashMap<> (); + if(resourceVersion != null) { + queryParams.put("resource-version", resourceVersion.toString()); + } + + Set<String> uniqueResources = extractUniqueResourceSetFromKeys(requestProperties.stringPropertyNames()); + + String[] keys = requestProperties.keySet().toArray(new String[0]); + for(String key : keys) { + switch(key) { + case "cloud-region.cloud-region-id": + case "entitlement.resource-uuid": + case "license.resource-uuid": + case "route-target.route-target-role": + case "service-capability.vnf-type": + case "ctag-pool.availability-zone-name": + continue; + } + + String value = requestProperties.getProperty(key); + if(key.contains(".")) { + String[] splitKey = key.split("\\."); + if("cloud-region".equals(splitKey[0])){ + String cloudRegionId = requestProperties.getProperty("cloud-region.cloud-region-id"); + aaiService.LOGwriteDateTrace("cloud-region-id", cloudRegionId); + String token = String.format("%s/{%s}/{cloud-region-id}", splitKey[0], splitKey[1] ); + String encoded_owner = encodeQuery(value); + String encoded_region = encodeQuery(cloudRegionId); + request_url = request_url.replace(token, String.format("%s/%s/%s", splitKey[0], encoded_owner, encoded_region)); + } else if("entitlement".equals(splitKey[0])){ + String cloudRegionId = requestProperties.getProperty("entitlement.resource-uuid"); + aaiService.LOGwriteDateTrace("resource-uuid", cloudRegionId); + String token = String.format("%s/{%s}/{resource-uuid}", splitKey[0], splitKey[1] ); + String encoded_owner = encodeQuery(value); + String encoded_region = encodeQuery(cloudRegionId); + request_url = request_url.replace(token, String.format("%s/%s/%s", splitKey[0], encoded_owner, encoded_region)); + } else if("license".equals(splitKey[0])){ + String cloudRegionId = requestProperties.getProperty("license.resource-uuid"); + aaiService.LOGwriteDateTrace("resource-uuid", cloudRegionId); + String token = String.format("%s/{%s}/{resource-uuid}", splitKey[0], splitKey[1] ); + String encoded_owner = encodeQuery(value); + String encoded_region = encodeQuery(cloudRegionId); + request_url = request_url.replace(token, String.format("%s/%s/%s", splitKey[0], encoded_owner, encoded_region)); + } else if("route-target".equals(splitKey[0])){ + String cloudRegionId = requestProperties.getProperty("route-target.route-target-role"); + aaiService.LOGwriteDateTrace("route-target-role", cloudRegionId); + String token = String.format("%s/{%s}/{route-target-role}", splitKey[0], splitKey[1] ); + String encoded_owner = encodeQuery(value); + String encoded_region = encodeQuery(cloudRegionId); + request_url = request_url.replace(token, String.format("%s/%s/%s", splitKey[0], encoded_owner, encoded_region)); + } else if("service-capability".equals(splitKey[0])){ + String vnfType = requestProperties.getProperty("service-capability.vnf-type"); + aaiService.LOGwriteDateTrace("vnf-type", vnfType); + String token = String.format("%s/{%s}/{vnf-type}", splitKey[0], splitKey[1] ); + String encoded_service_type = encodeQuery(value); + String encoded_vnf_type = encodeQuery(vnfType); + if("service-capability".equals(resourceName)) { + request_url = request_url.replace(token, String.format("%s/%s/%s", splitKey[0], encoded_service_type, encoded_vnf_type)); + } else if("service-capabilities".equals(resourceName)) { + queryParams.put("service-type", encoded_service_type); + queryParams.put("vnf-type", encoded_vnf_type); + } + } else if("ctag-pool".equals(splitKey[0])){ + String cloudRegionId = requestProperties.getProperty("ctag-pool.availability-zone-name"); + aaiService.LOGwriteDateTrace("availability-zone-name", cloudRegionId); + String token = String.format("%s/{%s}/{availability-zone-name}", splitKey[0], splitKey[1] ); + String encoded_owner = encodeQuery(value); + String encoded_region = encodeQuery(cloudRegionId); + request_url = request_url.replace(token, String.format("%s/%s/%s", splitKey[0], encoded_owner, encoded_region)); + } else { + Class<? extends AAIDatum> clazz = getClassFromResource(splitKey[0]); + + if(clazz != null) { + if(clazz == this.model) { + Field[] fields = this.model.getDeclaredFields(); + Field field = fields[0]; + String fieldName = field.getName(); + XmlElement annotation = field.getAnnotation(XmlElement.class); + String primaryId = null; + if(annotation != null) { + primaryId = annotation.name(); + if("##default".equals(primaryId)) { + primaryId = fieldName; + } + } else { + primaryId = fieldName; + } + + String token = String.format("%s/{%s}", splitKey[0], primaryId); + + if(splitKey[1].equals(primaryId)) { + String encoded_vnf = encodeQuery(value); + request_url = request_url.replace(token, String.format("%s/%s", splitKey[0], encoded_vnf)); + } else { + queryParams.put(splitKey[1], encodeQuery(value)); + originalPath = token; + pathSubstitute = String.format("%s", splitKey[0]); + } + } else if(L3Networks.class == this.model) { + Field[] fields = L3Network.class.getDeclaredFields(); + Field field = fields[0]; + String fieldName = field.getName(); + XmlElement annotation = field.getAnnotation(XmlElement.class); + String primaryId = annotation.name(); + if("##default".equals(primaryId)) { + primaryId = fieldName; + } + + String token = String.format("%s/{%s}", splitKey[0], primaryId); + originalPath = token; + pathSubstitute = String.format(""); + + queryParams.put(splitKey[1], encodeQuery(value)); + } else { + String encoded_vnf = encodeQuery(value); + if(!resourceName.equals(splitKey[0]) && resourceName.contains(splitKey[0])) { + queryParams.put(splitKey[1], encoded_vnf); + } else { + String token = String.format("%s/{%s}", splitKey[0], splitKey[1]); + request_url = request_url.replace(token, String.format("%s/%s", splitKey[0], encoded_vnf)); + } + } + } + + } + aaiService.LOGwriteDateTrace(splitKey[1], value); + } + } + + if(originalPath != null && pathSubstitute != null) + request_url = request_url.replace(originalPath, pathSubstitute); + + if(!queryParams.isEmpty()) { + Joiner.MapJoiner mapJoiner = Joiner.on("&").withKeyValueSeparator("="); + String queryString = mapJoiner.join(queryParams); + request_url = String.format("%s?%s", request_url, queryString); + } + + return request_url; + } + + @Override + public URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException, URISyntaxException { + return this.getRequestUrl(method, null); + } + + + @Override + public String toJSONString() { + ObjectMapper mapper = getObjectMapper(); + + String json_text = null; + try { + json_text = mapper.writeValueAsString(requestDatum); + } catch (JsonProcessingException exc) { + handleException(this, exc); + return null; + } + return json_text; + } + + @Override + public String[] getArgsList() { + String[] args = {}; + return args; + } + + @Override + public Class<? extends AAIDatum> getModelClass() { + return model; + } + + public void processRequestPathValues(Map<String, String> nameValues) { + // identify unique resources + Set<String> uniqueResources = AAIRequest.extractUniqueResourceSetFromKeys(nameValues.keySet()); + + String[] arguments = nameValues.keySet().toArray(new String[0]); + for(String name : arguments) { + String tmpName = name.replaceAll("-", "_"); + String value = nameValues.get(tmpName); + if(value != null && !value.isEmpty()) { + value = value.trim().replace("'", "").replace("$", "").replace("'", ""); + tmpName = name.replaceAll("_", "-"); + this.addRequestProperty(tmpName, value); + } + } + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/HttpMethod.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/HttpMethod.java new file mode 100755 index 000000000..8f7abe601 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/HttpMethod.java @@ -0,0 +1,13 @@ +package org.onap.ccsdk.sli.adaptors.aai; +/** + * @author Rich Tabedzki + * + */ +public interface HttpMethod { + public static final String GET = "GET"; + public static final String HEAD = "HEAD"; + public static final String PATCH = "PATCH"; + public static final String POST = "POST"; + public static final String PUT = "PUT"; + public static final String DELETE = "DELETE"; +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/NodesQueryRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/NodesQueryRequest.java new file mode 100755 index 000000000..c40d96cad --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/NodesQueryRequest.java @@ -0,0 +1,129 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Properties; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.aai.inventory.v21.SearchResults; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class NodesQueryRequest extends AAIRequest { + + public static final String NODES_SEARCH_PATH = "org.onap.ccsdk.sli.adaptors.aai.query.nodes"; + + private final String nodes_search_path; + + public static final String NODE_TYPE = "node-type"; + public static final String ENTITY_IDENTIFIER = "entity-identifier"; + public static final String ENTITY_VALUE = "entity-value"; + + + public NodesQueryRequest() { + nodes_search_path = configProperties.getProperty(NODES_SEARCH_PATH); + } + + + @Override + public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException { + + String request_url = targetUri+nodes_search_path; + + request_url = processPathData(request_url, requestProperties); + + if(resourceVersion != null) { + request_url = request_url +"?resource-version="+resourceVersion; + } + URL http_req_url = new URL(request_url); + + aaiService.LOGwriteFirstTrace(method, http_req_url.toString()); + + return http_req_url; + } + + @Override + public URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException { + return getRequestUrl(method, null); + } + + + @Override + public String toJSONString() { + ObjectMapper mapper = getObjectMapper(); + SearchResults tenant = (SearchResults)requestDatum; + String json_text = null; + try { + json_text = mapper.writeValueAsString(tenant); + } catch (JsonProcessingException exc) { + handleException(this, exc); + return null; + } + return json_text; + } + + + @Override + public String[] getArgsList() { + String[] args = {NODE_TYPE, ENTITY_IDENTIFIER, ENTITY_VALUE}; + return args; + } + + + @Override + public Class<? extends AAIDatum> getModelClass() { + return SearchResults.class; + } + + + public static String processPathData(String request_url, Properties requestProperties) throws UnsupportedEncodingException { + + String key = ENTITY_IDENTIFIER; + + String encoded_vnf = encodeQuery(requestProperties.getProperty(key)); + request_url = request_url.replace("{entity-identifier}", encoded_vnf) ; + aaiService.LOGwriteDateTrace(ENTITY_IDENTIFIER, requestProperties.getProperty(key)); + + key = ENTITY_VALUE; + + encoded_vnf = encodeQuery(requestProperties.getProperty(key)); + request_url = request_url.replace("{entity-name}", encoded_vnf) ; + aaiService.LOGwriteDateTrace("entity-name", requestProperties.getProperty(key)); + + key = NODE_TYPE; + + encoded_vnf = encodeQuery(requestProperties.getProperty(key)); + request_url = request_url.replace("{node-type}", encoded_vnf) ; + aaiService.LOGwriteDateTrace(NODE_TYPE, requestProperties.getProperty(key)); + + return request_url; + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/PathRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/PathRequest.java new file mode 100755 index 000000000..68aff1f95 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/PathRequest.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class PathRequest extends AAIRequest { + + private final Class<? extends AAIDatum> classType; + + public static final String RESOURCE_PATH = "resource-path"; + + public PathRequest(Class<?> type) { + classType = (Class<? extends AAIDatum>)type; + } + + + @Override + public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException { + + String request_url = targetUri + "{resource-path}"; + + String encoded_vnf = requestProperties.getProperty(RESOURCE_PATH); + request_url = request_url.replace("{resource-path}", encoded_vnf) ; + + URL http_req_url = new URL(request_url); + + aaiService.LOGwriteFirstTrace(method, http_req_url.toString()); + + return http_req_url; + } + + @Override + public URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException { + return this.getRequestUrl(method, null); + } + + + @Override + public String toJSONString() { + ObjectMapper mapper = getObjectMapper(); + String json_text = null; + try { + json_text = mapper.writeValueAsString(classType); + } catch (JsonProcessingException exc) { + handleException(this, exc); + return null; + } + return json_text; + } + + @Override + public String[] getArgsList() { + String[] args = {RESOURCE_PATH}; + return args; + } + + @Override + public Class<? extends AAIDatum> getModelClass() { + return classType; + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/RelationshipListRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/RelationshipListRequest.java new file mode 100755 index 000000000..751fe5d59 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/RelationshipListRequest.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.List; + +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.onap.aai.inventory.v21.RelationshipList; + +public class RelationshipListRequest extends GenericRequest { + + public static final String SELFLINK = "selflink"; + + public RelationshipListRequest(AAIRequest masterRequest) { + super(RelationshipList.class); + this.addMasterRequest(masterRequest); + } + + + @Override + public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException, URISyntaxException { + + URL url = super.getRequestUrl(method, null); + URIBuilder builder = new URIBuilder(url.toURI()); + String newPath = builder.getPath() + "/relationship-list"; + builder.setPath(newPath); + if(resourceVersion != null) { + List<NameValuePair> queryList = builder.getQueryParams(); + NameValuePair nvp = new BasicNameValuePair("resourceVersion", resourceVersion); + queryList.add(nvp); + } + + aaiService.LOGwriteFirstTrace(method, builder.toString()); + + return builder.build().toURL(); + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/RelationshipRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/RelationshipRequest.java new file mode 100755 index 000000000..fa71d6f22 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/RelationshipRequest.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.List; + +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.message.BasicNameValuePair; + +import org.onap.aai.inventory.v21.Relationship; + + +public class RelationshipRequest extends GenericRequest { + + public RelationshipRequest(AAIRequest masterRequest) { + super(Relationship.class); + this.addMasterRequest(masterRequest); + } + + + @Override + public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException, URISyntaxException { + + + URL url = super.getRequestUrl(method, null); + URIBuilder builder = new URIBuilder(url.toURI()); + String newPath = builder.getPath() + "/relationship-list/relationship"; + builder.setPath(newPath); + if(resourceVersion != null) { + List<NameValuePair> queryList = builder.getQueryParams(); + NameValuePair nvp = new BasicNameValuePair("resourceVersion", resourceVersion); + queryList.add(nvp); + } + + aaiService.LOGwriteFirstTrace(method, builder.toString()); + + return builder.build().toURL(); + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/SelfLinkRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/SelfLinkRequest.java new file mode 100755 index 000000000..0094b45fd --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/SelfLinkRequest.java @@ -0,0 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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========================================================= + */ +/** + * @author Rich Tabedzki + * + */ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Joiner; + +public class SelfLinkRequest extends AAIRequest { + + private final Class<? extends AAIDatum> classType; + + public static final String SELFLINK = "selflink"; + + public SelfLinkRequest(Class<?> type) { + classType = (Class<? extends AAIDatum>)type; + } + + + @Override + public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException { + + String request_url = null; + + request_url = requestProperties.getProperty(SELFLINK); + try { + URI uri = new URI(request_url); + if(uri.getHost() == null) { + request_url = targetUri + request_url; + } + } catch(Exception exc) { + LOG.error("SelfLinkRequest.getRequestUrl", exc); + } + String query = null; + + if(request_url.contains("?")) { + query = request_url.substring(request_url.indexOf("?")); + Joiner.MapJoiner mapJoiner = Joiner.on(",").withKeyValueSeparator("="); +// String queryString = mapJoiner.join(query); + } else { + request_url = request_url + "?depth=1"; + } + + URL http_req_url = new URL(request_url); + + aaiService.LOGwriteFirstTrace(method, http_req_url.toString()); + + return http_req_url; + } + + @Override + public URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException { + return this.getRequestUrl(method, null); + } + + + @Override + public String toJSONString() { + ObjectMapper mapper = getObjectMapper(); + String json_text = null; + try { + json_text = mapper.writeValueAsString(classType); + } catch (JsonProcessingException exc) { + handleException(this, exc); + return null; + } + return json_text; + } + + @Override + public String[] getArgsList() { + String[] args = {SELFLINK}; + return args; + } + + @Override + public Class<? extends AAIDatum> getModelClass() { + return classType; + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/UpdateRequest.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/UpdateRequest.java new file mode 100755 index 000000000..8046ca5e3 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/UpdateRequest.java @@ -0,0 +1,152 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * 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========================================================= + */ +/** + * The UpdateRequest class provides processing related to update transaction. + * @author richtabedzki + */ + +package org.onap.ccsdk.sli.adaptors.aai; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.stream.Collectors; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class UpdateRequest extends AAIRequest { + + private AAIRequest request; + private Map<String, String> params; + + public UpdateRequest(AAIRequest request, Map<String, String> parms) { + this.request = request; + this.params = parms; + } + + @Override + public URL getRequestUrl(String method, String resourceVersion) + throws UnsupportedEncodingException, MalformedURLException, URISyntaxException { + return request.getRequestUrl(method, resourceVersion); + } + + @Override + public URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException, URISyntaxException { + return request.getRequestQueryUrl(method); + } + + @Override + public String toJSONString() { + updateArrayEntries(params); + ObjectMapper mapper = AAIService.getObjectMapper(); + String json = null; + + try { + json = mapper.writeValueAsString(params); + } catch (JsonProcessingException e) { + LOG.error("Could not convert parameters of " + request.getRequestObject().getClass().getName(), e); + } + + return json; + } + + /** + * + * Update array entries. + * The method converts indexed data entries to an array of values + * + * @param data Map containing String:String values representing input data + */ + private void updateArrayEntries( Map<String, String> data) { + Set<String> set = data.keySet() + .stream() + .filter(s -> s.endsWith("_length")) + .collect(Collectors.toSet()); + + for(String lenghtKey : set) { + String key = lenghtKey.replace("_length", ""); +// String index = data.get(lenghtKey); + List<String> array = new ArrayList<>(); + + Set<String> subset = data.keySet() + .stream() + .filter(s -> s.startsWith(String.format("%s[",key))) + .collect(Collectors.toSet()); + for(String subKey : subset) { + String subValue = data.get(subKey); + array.add(subValue); + LOG.trace("{} : {} ", subKey, subValue); + } + data.put(key, array.toString()); + data.remove(lenghtKey); + for(String subKey : subset) { + data.remove(subKey); + } + } + } + + @Override + public String[] getArgsList() { + return request.getArgsList(); + } + + @Override + public Class<? extends AAIDatum> getModelClass() { + return request.getModelClass(); + } + + @Override + public void addRequestProperty(String key, String value) { + request.requestProperties.put(key, value); + } + + public static String processPathData(String requestUrl, Properties requestProperties) { + +// if(request != null) { +// Class<?> clazz = request.getClass(); +// Method function = null; +// try { +// function = clazz.getMethod("processPathData", request_url.getClass(), requestProperties.getClass()); +// request_url = (String) function.invoke(null, request_url, requestProperties); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } + +// request.processPathData(request_url, requestProperties); + return requestUrl; + } + + public void processRequestPathValues(Map<String, String> nameValues) { + request.processRequestPathValues(nameValues); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/UtilsProvider.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/UtilsProvider.java new file mode 100755 index 000000000..c89e35b2c --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/UtilsProvider.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2016 - 2017 ONAP + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.aai; + +import java.util.Properties; + +/** + * @author Rich Tabedzki + * + */ +public interface UtilsProvider { + /** + * Extract configuration properties. + * + * @return the configuration properties + */ + Properties getProperties(); +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/AAIDatum.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/AAIDatum.java new file mode 100644 index 000000000..2a44a38e4 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/AAIDatum.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +public interface AAIDatum { + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/EchoResponse.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/EchoResponse.java new file mode 100644 index 000000000..40f5f4e4c --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/EchoResponse.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "responseMessages" +}) +public class EchoResponse implements AAIDatum { + + @JsonProperty("responseMessages") + private ResponseMessages responseMessages; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The responseMessages + */ + @JsonProperty("responseMessages") + public ResponseMessages getResponseMessages() { + return responseMessages; + } + + /** + * + * @param responseMessages + * The responseMessages + */ + @JsonProperty("responseMessages") + public void setResponseMessages(ResponseMessages responseMessages) { + this.responseMessages = responseMessages; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ErrorResponse.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ErrorResponse.java new file mode 100644 index 000000000..e650003cb --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ErrorResponse.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Generated; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "requestError" +}) +public class ErrorResponse { + + @JsonProperty("requestError") + private RequestError requestError; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The requestError + */ + @JsonProperty("requestError") + public RequestError getRequestError() { + return requestError; + } + + /** + * + * @param requestError + * The requestError + */ + @JsonProperty("requestError") + public void setRequestError(RequestError requestError) { + this.requestError = requestError; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/RequestError.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/RequestError.java new file mode 100644 index 000000000..88325d828 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/RequestError.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Generated; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "serviceException" +}) +public class RequestError { + + @JsonProperty("serviceException") + private ServiceException serviceException; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The serviceException + */ + @JsonProperty("serviceException") + public ServiceException getServiceException() { + return serviceException; + } + + /** + * + * @param serviceException + * The serviceException + */ + @JsonProperty("serviceException") + public void setServiceException(ServiceException serviceException) { + this.serviceException = serviceException; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ResourceVersion.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ResourceVersion.java new file mode 100644 index 000000000..237d95a5a --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ResourceVersion.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +public interface ResourceVersion { + + public String getResourceVersion(); + public void setResourceVersion(String resourceVersion); +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessage.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessage.java new file mode 100644 index 000000000..4742cef7a --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessage.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "messageId", + "text", + "variables" +}) +public class ResponseMessage { + + @JsonProperty("messageId") + private String messageId; + @JsonProperty("text") + private String text; + @JsonProperty("variables") + private Variables variables; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The messageId + */ + @JsonProperty("messageId") + public String getMessageId() { + return messageId; + } + + /** + * + * @param messageId + * The messageId + */ + @JsonProperty("messageId") + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + /** + * + * @return + * The text + */ + @JsonProperty("text") + public String getText() { + return text; + } + + /** + * + * @param text + * The text + */ + @JsonProperty("text") + public void setText(String text) { + this.text = text; + } + + /** + * + * @return + * The variables + */ + @JsonProperty("variables") + public Variables getVariables() { + return variables; + } + + /** + * + * @param variables + * The variables + */ + @JsonProperty("variables") + public void setVariables(Variables variables) { + this.variables = variables; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessages.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessages.java new file mode 100644 index 000000000..8ba5d145b --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessages.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "responseMessage" +}) +public class ResponseMessages { + + @JsonProperty("responseMessage") + private List<ResponseMessage> responseMessage = new ArrayList<ResponseMessage>(); + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The responseMessage + */ + @JsonProperty("responseMessage") + public List<ResponseMessage> getResponseMessage() { + return responseMessage; + } + + /** + * + * @param responseMessage + * The responseMessage + */ + @JsonProperty("responseMessage") + public void setResponseMessage(List<ResponseMessage> responseMessage) { + this.responseMessage = responseMessage; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ServiceException.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ServiceException.java new file mode 100644 index 000000000..bdb09855a --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/ServiceException.java @@ -0,0 +1,126 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Generated; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "messageId", + "text", + "variables" +}) +public class ServiceException { + + @JsonProperty("messageId") + private String messageId; + @JsonProperty("text") + private String text; + @JsonProperty("variables") + private List<String> variables = new ArrayList<String>(); + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The messageId + */ + @JsonProperty("messageId") + public String getMessageId() { + return messageId; + } + + /** + * + * @param messageId + * The messageId + */ + @JsonProperty("messageId") + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + /** + * + * @return + * The text + */ + @JsonProperty("text") + public String getText() { + return text; + } + + /** + * + * @param text + * The text + */ + @JsonProperty("text") + public void setText(String text) { + this.text = text; + } + + /** + * + * @return + * The variables + */ + @JsonProperty("variables") + public List<String> getVariables() { + return variables; + } + + /** + * + * @param variables + * The variables + */ + @JsonProperty("variables") + public void setVariables(List<String> variables) { + this.variables = variables; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/SubInterface.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/SubInterface.java new file mode 100644 index 000000000..7c66daa62 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/SubInterface.java @@ -0,0 +1,171 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import org.onap.aai.inventory.v21.RelationshipList; +import org.onap.aai.inventory.v21.Vlans; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "interface-name", + "interface-role", + "resource-version", + "vlans", + "relationshipList" +}) +public class SubInterface implements AAIDatum { + + @JsonProperty("interface-name") + private String interfaceName; + @JsonProperty("interface-role") + private String interfaceRole; + @JsonProperty("resource-version") + private String resourceVersion; + @JsonProperty("vlans") + private Vlans vlans; + @JsonProperty("relationshipList") + private RelationshipList relationshipList; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The interfaceName + */ + @JsonProperty("interface-name") + public String getInterfaceName() { + return interfaceName; + } + + /** + * + * @param interfaceName + * The interface-name + */ + @JsonProperty("interface-name") + public void setInterfaceName(String interfaceName) { + this.interfaceName = interfaceName; + } + + /** + * + * @return + * The interfaceRole + */ + @JsonProperty("interface-role") + public String getInterfaceRole() { + return interfaceRole; + } + + /** + * + * @param interfaceRole + * The interface-role + */ + @JsonProperty("interface-role") + public void setInterfaceRole(String interfaceRole) { + this.interfaceRole = interfaceRole; + } + + /** + * + * @return + * The resourceVersion + */ + @JsonProperty("resource-version") + public String getResourceVersion() { + return resourceVersion; + } + + /** + * + * @param resourceVersion + * The resource-version + */ + @JsonProperty("resource-version") + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + /** + * + * @return + * The vlans + */ + @JsonProperty("vlans") + public Vlans getVlans() { + return vlans; + } + + /** + * + * @param vlans + * The vlans + */ + @JsonProperty("vlans") + public void setVlans(Vlans vlans) { + this.vlans = vlans; + } + + /** + * + * @return + * The relationshipList + */ + @JsonProperty("relationshipList") + public RelationshipList getRelationshipList() { + return relationshipList; + } + + /** + * + * @param relationshipList + * The relationshipList + */ + @JsonProperty("relationshipList") + public void setRelationshipList(RelationshipList relationshipList) { + this.relationshipList = relationshipList; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/Variables.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/Variables.java new file mode 100644 index 000000000..3bdf70d7a --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/Variables.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "variable" +}) +public class Variables { + + @JsonProperty("variable") + private List<String> variable = new ArrayList<String>(); + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The variable + */ + @JsonProperty("variable") + public List<String> getVariable() { + return variable; + } + + /** + * + * @param variable + * The variable + */ + @JsonProperty("variable") + public void setVariable(List<String> variable) { + this.variable = variable; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/KeyDatum.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/KeyDatum.java new file mode 100644 index 000000000..1cad9fdd6 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/KeyDatum.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data.notify; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "key-name", + "key-value" +}) +public class KeyDatum { + + @JsonProperty("key-name") + private String keyName; + @JsonProperty("key-value") + private String keyValue; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The keyName + */ + @JsonProperty("key-name") + public String getKeyName() { + return keyName; + } + + /** + * + * @param keyName + * The key-name + */ + @JsonProperty("key-name") + public void setKeyName(String keyName) { + this.keyName = keyName; + } + + /** + * + * @return + * The keyValue + */ + @JsonProperty("key-value") + public String getKeyValue() { + return keyValue; + } + + /** + * + * @param keyValue + * The key-value + */ + @JsonProperty("key-value") + public void setKeyValue(String keyValue) { + this.keyValue = keyValue; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/NotifyEvent.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/NotifyEvent.java new file mode 100644 index 000000000..007096188 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/NotifyEvent.java @@ -0,0 +1,170 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.data.notify; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "event-id", + "event-trigger", + "key-data", + "node-type", + "selflink" +}) +public class NotifyEvent { + + @JsonProperty("event-id") + private String eventId; + @JsonProperty("event-trigger") + private String eventTrigger; + @JsonProperty("key-data") + private List<KeyDatum> keyData = new ArrayList<KeyDatum>(); + @JsonProperty("node-type") + private String nodeType; + @JsonProperty("selflink") + private String selflink; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The eventId + */ + @JsonProperty("event-id") + public String getEventId() { + return eventId; + } + + /** + * + * @param eventId + * The event-id + */ + @JsonProperty("event-id") + public void setEventId(String eventId) { + this.eventId = eventId; + } + + /** + * + * @return + * The eventTrigger + */ + @JsonProperty("event-trigger") + public String getEventTrigger() { + return eventTrigger; + } + + /** + * + * @param eventTrigger + * The event-trigger + */ + @JsonProperty("event-trigger") + public void setEventTrigger(String eventTrigger) { + this.eventTrigger = eventTrigger; + } + + /** + * + * @return + * The keyData + */ + @JsonProperty("key-data") + public List<KeyDatum> getKeyData() { + return keyData; + } + + /** + * + * @param keyData + * The key-data + */ + @JsonProperty("key-data") + public void setKeyData(List<KeyDatum> keyData) { + this.keyData = keyData; + } + + /** + * + * @return + * The nodeType + */ + @JsonProperty("node-type") + public String getNodeType() { + return nodeType; + } + + /** + * + * @param nodeType + * The node-type + */ + @JsonProperty("node-type") + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + /** + * + * @return + * The selflink + */ + @JsonProperty("selflink") + public String getSelflink() { + return selflink; + } + + /** + * + * @param selflink + * The selflink + */ + @JsonProperty("selflink") + public void setSelflink(String selflink) { + this.selflink = selflink; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryRequestData.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryRequestData.java new file mode 100644 index 000000000..e2074e97b --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryRequestData.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.query; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; + +import com.fasterxml.jackson.annotation.JsonProperty; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "start", + "query" +}) +@XmlRootElement(name = "query-request") +public class FormattedQueryRequestData implements AAIDatum { + + @JsonProperty("start") + protected List<String> start; + + @JsonProperty("query") + private String query; + + @JsonProperty("start") + public List<String> getStart () + { + return start; + } + + @JsonProperty("start") + public void setStart (List<String> start) + { + this.start = start; + } + + @JsonProperty("query") + public String getQuery () + { + return query; + } + + @JsonProperty("query") + public void setQuery (String query) + { + this.query = query; + } + + @Override + public String toString() + { + return " [start = "+start+", query = "+query+"]"; + } + + public String getResourceVersion() { + return null; + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryResultList.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryResultList.java new file mode 100755 index 000000000..a50bf78b2 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryResultList.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.query; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "results" +}) +@XmlRootElement(name = "result-list") +public class FormattedQueryResultList implements AAIDatum { + + @XmlElement(name = "results") + private List<Result> results; + + @XmlElement(name = "results") + public List<Result> getResults () + { + return results; + } + @XmlElement(name = "results") + public void setResults (List<Result> results) + { + this.results = results; + } + + @Override + public String toString() + { + return "ClassPojo [results = "+results+"]"; + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFilter.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFilter.java new file mode 100755 index 000000000..48ada1fa9 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFilter.java @@ -0,0 +1,205 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.query; + +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Generated; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import org.onap.aai.inventory.v21.CloudRegion; +import org.onap.aai.inventory.v21.GenericVnf; +import org.onap.aai.inventory.v21.L3Network; +import org.onap.aai.inventory.v21.Pnf; +import org.onap.aai.inventory.v21.LogicalLink; +import org.onap.aai.inventory.v21.PInterface; +import org.onap.aai.inventory.v21.ServiceInstance; +import org.onap.aai.inventory.v21.Tenant; +import org.onap.aai.inventory.v21.Vnf; +import org.onap.aai.inventory.v21.Vserver; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "logical-link", + "pnf", + "l3-network", + "p-interface", + "generic-vnf", + "vserver", + "tenant", + "cloud-region", + "service-instance", + "vnfc" +}) +public class InstanceFilter { + + @JsonProperty("logical-link") + private LogicalLink logicalLink; + @JsonProperty("pnf") + private Pnf pnf; + @JsonProperty("l3-network") + private L3Network l3Network; + @JsonProperty("p-interface") + private PInterface pInterface; + @JsonProperty("generic-vnf") + private GenericVnf genericVnf; + @JsonProperty("vserver") + private Vserver vserver; + @JsonProperty("tenant") + private Tenant tenant; + @JsonProperty("cloud-region") + private CloudRegion cloudRegion; + @JsonProperty("service-instance") + private ServiceInstance serviceInstance; + @JsonProperty("vnfc") + private Vnf vnfc; + + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The logicalLink + */ + @JsonProperty("logical-link") + public LogicalLink getLogicalLink() { + return logicalLink; + } + + /** + * + * @param logicalLink + * The logical-link + */ + @JsonProperty("logical-link") + public void setLogicalLink(LogicalLink logicalLink) { + this.logicalLink = logicalLink; + } + + /** + * + * @return + * The pnf + */ + @JsonProperty("pnf") + public Pnf getPnf() { + return pnf; + } + + /** + * + * @param pnf + * The pnf + */ + @JsonProperty("pnf") + public void setPnf(Pnf pnf) { + this.pnf = pnf; + } + + @JsonProperty("l3-network") + public L3Network getL3Network() { + return l3Network; + } + + @JsonProperty("l3-network") + public void setL3Network(L3Network l3Network) { + this.l3Network = l3Network; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @JsonProperty("service-instance") + public ServiceInstance getServiceInstance() { + return serviceInstance; + } + + @JsonProperty("service-instance") + public void setServiceInstance(ServiceInstance serviceInstance) { + this.serviceInstance = serviceInstance; + } + @JsonProperty("p-interface") + public PInterface getpInterface() { + return pInterface; + } + @JsonProperty("p-interface") + public void setpInterface(PInterface pInterface) { + this.pInterface = pInterface; + } + @JsonProperty("generic-vnf") + public GenericVnf getGenericVnf() { + return genericVnf; + } + @JsonProperty("generic-vnf") + public void setGenericVnf(GenericVnf genericVnf) { + this.genericVnf = genericVnf; + } + @JsonProperty("vserver") + public Vserver getVserver() { + return vserver; + } + @JsonProperty("vserver") + public void setVserver(Vserver vserver) { + this.vserver = vserver; + } + @JsonProperty("tenant") + public Tenant getTenant() { + return tenant; + } + @JsonProperty("tenant") + public void setTenant(Tenant tenant) { + this.tenant = tenant; + } + @JsonProperty("cloud-region") + public CloudRegion getCloudRegion() { + return cloudRegion; + } + @JsonProperty("cloud-region") + public void setCloudRegion(CloudRegion cloudRegion) { + this.cloudRegion = cloudRegion; + } + @JsonProperty("vnfc") + public Vnf getVnfc() { + return vnfc; + } + @JsonProperty("vnfc") + public void setVnfc(Vnf vnfc) { + this.vnfc = vnfc; + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFilters.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFilters.java new file mode 100644 index 000000000..c0a3ba255 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFilters.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.query; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "instance-filter" +}) +public class InstanceFilters { + + @JsonProperty("instance-filter") + private List<InstanceFilter> instanceFilter = new ArrayList<InstanceFilter>(); + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The instanceFilter + */ + @JsonProperty("instance-filter") + public List<InstanceFilter> getInstanceFilter() { + return instanceFilter; + } + + /** + * + * @param instanceFilter + * The instance-filter + */ + @JsonProperty("instance-filter") + public void setInstanceFilter(List<InstanceFilter> instanceFilter) { + this.instanceFilter = instanceFilter; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/Result.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/Result.java new file mode 100755 index 000000000..1f8a17551 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/query/Result.java @@ -0,0 +1,278 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.query; + +import java.util.HashMap; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.onap.aai.inventory.v21.CloudRegion; +import org.onap.aai.inventory.v21.Complex; +import org.onap.aai.inventory.v21.Configuration; +import org.onap.aai.inventory.v21.GenericVnf; +import org.onap.aai.inventory.v21.L3InterfaceIpv4AddressList; +import org.onap.aai.inventory.v21.L3InterfaceIpv6AddressList; +import org.onap.aai.inventory.v21.L3Network; +import org.onap.aai.inventory.v21.LInterface; +//import org.onap.aai.inventory.v21.OwningEntity; +import org.onap.aai.inventory.v21.Pserver; +import org.onap.aai.inventory.v21.ServiceInstance; +import org.onap.aai.inventory.v21.Vnfc; +import org.onap.aai.inventory.v21.Vserver; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "resource-type", + "resource-link", + "url", + "cloud-region", + "complex", + "configuration", + "generic-vnf", + "l3-interface-ipv4-address-list", + "l3-interface-ipv6-address-list", + "l3-network", + "l-interface", + "owning-entity", + "pserver", + "service-instance", + "vnfc", + "vserver" +}) +@XmlRootElement(name = "result") +public class Result { + + @XmlElement(name = "resource-type") + private String resourceType; + @XmlElement(name = "resource-link") + private String resourceLink; + @XmlElement(name = "url") + private String url; + @XmlElement(name = "cloud-region") + private CloudRegion cloudRegion; + @XmlElement(name = "complex") + private Complex complex; + @XmlElement(name = "configuration") + private Configuration configuration; + @XmlElement(name = "generic-vnf") + private GenericVnf genericVnf; + @XmlElement(name = "l3-interface-ipv4-address-list") + private L3InterfaceIpv4AddressList l3InterfaceIpv4AddressList; + @XmlElement(name = "l3-interface-ipv6-address-list") + private L3InterfaceIpv6AddressList l3InterfaceIpv6AddressList; + @XmlElement(name = "l3-network") + private L3Network l3Network; + @XmlElement(name = "l-interface") + private LInterface lInterface; +// @XmlElement(name = "owning-entity") +// private OwningEntity owningEntity; + @XmlElement(name = "pserver") + private Pserver pserver; + @XmlElement(name = "service-instance") + private ServiceInstance serviceInstance; + @XmlElement(name = "vnfc") + private Vnfc vnfc; + @XmlElement(name = "vserver") + private Vserver vserver; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + @XmlElement(name = "cloud-region") + public CloudRegion getCloudRegion() { + return cloudRegion; + } + + @XmlElement(name = "cloud-region") + public void setCloudRegion(CloudRegion cloudRegion) { + this.cloudRegion = cloudRegion; + } + + @XmlElement(name = "complex") + public Complex getComplex() { + return complex; + } + + @XmlElement(name = "complex") + public void setComplex(Complex complex) { + this.complex = complex; + } + + @XmlElement(name = "configuration") + public Configuration getConfiguration() { + return configuration; + } + + @XmlElement(name = "configuration") + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + @XmlElement(name = "generic-vnf") + public GenericVnf getGenericVnf () + { + return genericVnf; + } + + @XmlElement(name = "generic-vnf") + public void setGenericVnf (GenericVnf genericVnf) + { + this.genericVnf = genericVnf; + } + + @JsonProperty("l3-interface-ipv4-address-list") + public L3InterfaceIpv4AddressList getL3InterfaceIpv4AddressList() { + return l3InterfaceIpv4AddressList; + } + + @JsonProperty("l3-interface-ipv4-address-list") + public void setL3InterfaceIpv4AddressList(L3InterfaceIpv4AddressList l3InterfaceIpv4AddressList) { + this.l3InterfaceIpv4AddressList = l3InterfaceIpv4AddressList; + } + + @JsonProperty("l3-interface-ipv6-address-list") + public L3InterfaceIpv6AddressList getL3InterfaceIpv6AddressList() { + return l3InterfaceIpv6AddressList; + } + + @JsonProperty("l3-interface-ipv6-address-list") + public void setL3InterfaceIpv6AddressList(L3InterfaceIpv6AddressList l3InterfaceIpv6AddressList) { + this.l3InterfaceIpv6AddressList = l3InterfaceIpv6AddressList; + } + + @XmlElement(name = "l3-network") + public L3Network getL3Network() { + return l3Network; + } + + @XmlElement(name = "l3-network") + public void setL3Network(L3Network l3Network) { + this.l3Network = l3Network; + } + + @XmlElement(name = "l-interface") + public LInterface getLInterface() { + return lInterface; + } + @XmlElement(name = "l-interface") + public void setLInterface(LInterface linterface) { + this.lInterface = linterface; + } + +// @XmlElement(name = "owning-entity") +// public OwningEntity getOwningEntity() { +// return owningEntity; +// } + +// @XmlElement(name = "owning-entity") +// public void setOwningEntity(OwningEntity owningEntity) { +// this.owningEntity = owningEntity; +// } + + @XmlElement(name = "pserver") + public Pserver getPserver() { + return pserver; + } + @XmlElement(name = "pserver") + public void setPserver(Pserver pserver) { + this.pserver = pserver; + } + + @XmlElement(name = "service-instance") + public ServiceInstance getServiceInstance() { + return serviceInstance; + } + + @XmlElement(name = "service-instance") + public void setServiceInstance(ServiceInstance serviceInstance) { + this.serviceInstance = serviceInstance; + } + + @XmlElement(name = "vnfc") + public Vnfc getVnfc() { + return vnfc; + } + + @XmlElement(name = "vnfc") + public void setVnfc(Vnfc vnfc) { + this.vnfc = vnfc; + } + + @XmlElement(name = "vserver") + public Vserver getVserver() { + return vserver; + } + + @XmlElement(name = "vserver") + public void setVserver(Vserver vserver) { + this.vserver = vserver; + } + + @Override + public String toString() + { + return " [generic-vnf = "+genericVnf+"]"; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + @XmlElement(name = "resource-type") + public String getResourceType() { + return resourceType; + } + @XmlElement(name = "resource-type") + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + @XmlElement(name = "resource-link") + public String getResourceLink() { + return resourceLink; + } + @XmlElement(name = "resource-link") + public void setResourceLink(String resourceLink) { + this.resourceLink = resourceLink; + } + @XmlElement(name = "url") + public String getUrl() { + return url; + } + @XmlElement(name = "url") + public void setUrl(String url) { + this.url = url; + } +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/Action.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/Action.java new file mode 100644 index 000000000..376da0d01 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/Action.java @@ -0,0 +1,101 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.update; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "action-data", + "action-type" +}) +public class Action { + + @JsonProperty("action-data") + private List<ActionDatum> actionData = new ArrayList<ActionDatum>(); + @JsonProperty("action-type") + private String actionType; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The actionData + */ + @JsonProperty("action-data") + public List<ActionDatum> getActionData() { + return actionData; + } + + /** + * + * @param actionData + * The action-data + */ + @JsonProperty("action-data") + public void setActionData(List<ActionDatum> actionData) { + this.actionData = actionData; + } + + /** + * + * @return + * The actionType + */ + @JsonProperty("action-type") + public String getActionType() { + return actionType; + } + + /** + * + * @param actionType + * The action-type + */ + @JsonProperty("action-type") + public void setActionType(String actionType) { + this.actionType = actionType; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/ActionDatum.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/ActionDatum.java new file mode 100644 index 000000000..67c6246c7 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/ActionDatum.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.update; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "property-name", + "property-value" +}) +public class ActionDatum { + + @JsonProperty("property-name") + private String propertyName; + @JsonProperty("property-value") + private String propertyValue; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The propertyName + */ + @JsonProperty("property-name") + public String getPropertyName() { + return propertyName; + } + + /** + * + * @param propertyName + * The property-name + */ + @JsonProperty("property-name") + public void setPropertyName(String propertyName) { + this.propertyName = propertyName; + } + + /** + * + * @return + * The propertyValue + */ + @JsonProperty("property-value") + public String getPropertyValue() { + return propertyValue; + } + + /** + * + * @param propertyValue + * The property-value + */ + @JsonProperty("property-value") + public void setPropertyValue(String propertyValue) { + this.propertyValue = propertyValue; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/Update.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/Update.java new file mode 100644 index 000000000..80bb75694 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/Update.java @@ -0,0 +1,124 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.update; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "update-node-type", + "update-node-key", + "action" +}) +public class Update { + + @JsonProperty("update-node-type") + private String updateNodeType; + @JsonProperty("action") + private List<Action> action = new ArrayList<Action>(); + @JsonProperty("update-node-key") + private List<UpdateNodeKey> updateNodeKey = new ArrayList<UpdateNodeKey>(); + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The updateNodeType + */ + @JsonProperty("update-node-type") + public String getUpdateNodeType() { + return updateNodeType; + } + + /** + * + * @param updateNodeType + * The update-node-type + */ + @JsonProperty("update-node-type") + public void setUpdateNodeType(String updateNodeType) { + this.updateNodeType = updateNodeType; + } + + /** + * + * @return + * The action + */ + @JsonProperty("action") + public List<Action> getAction() { + return action; + } + + /** + * + * @param action + * The action + */ + @JsonProperty("action") + public void setAction(List<Action> action) { + this.action = action; + } + + /** + * + * @return + * The updateNodeKey + */ + @JsonProperty("update-node-key") + public List<UpdateNodeKey> getUpdateNodeKey() { + return updateNodeKey; + } + + /** + * + * @param updateNodeKey + * The update-node-key + */ + @JsonProperty("update-node-key") + public void setUpdateNodeKey(List<UpdateNodeKey> updateNodeKey) { + this.updateNodeKey = updateNodeKey; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/UpdateNodeKey.java b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/UpdateNodeKey.java new file mode 100644 index 000000000..6803ea2c2 --- /dev/null +++ b/aai-service/provider/src/main/java/org/onap/ccsdk/sli/adaptors/aai/update/UpdateNodeKey.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai.update; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "key-name", + "key-value" +}) +public class UpdateNodeKey { + + @JsonProperty("key-name") + private String keyName; + @JsonProperty("key-value") + private String keyValue; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The keyName + */ + @JsonProperty("key-name") + public String getKeyName() { + return keyName; + } + + /** + * + * @param keyName + * The key-name + */ + @JsonProperty("key-name") + public void setKeyName(String keyName) { + this.keyName = keyName; + } + + /** + * + * @return + * The keyValue + */ + @JsonProperty("key-value") + public String getKeyValue() { + return keyValue; + } + + /** + * + * @param keyValue + * The key-value + */ + @JsonProperty("key-value") + public void setKeyValue(String keyValue) { + this.keyValue = keyValue; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + +} diff --git a/aai-service/provider/src/main/resources/OSGI-INF/blueprint/aaiservice-blueprint.xml b/aai-service/provider/src/main/resources/OSGI-INF/blueprint/aaiservice-blueprint.xml new file mode 100755 index 000000000..970936610 --- /dev/null +++ b/aai-service/provider/src/main/resources/OSGI-INF/blueprint/aaiservice-blueprint.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 - 2018 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="provider" class="org.onap.ccsdk.sli.adaptors.aai.AAIServiceProvider" /> + + <bean id="aaiService" class="org.onap.ccsdk.sli.adaptors.aai.AAIService"> + <argument ref="provider" /> + </bean> + <service ref="aaiService"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.aai.AAIService</value> + <value>org.onap.ccsdk.sli.adaptors.aai.AAIClient</value> + </interfaces> + </service> + +</blueprint> diff --git a/aai-service/provider/src/main/resources/aai-path.properties b/aai-service/provider/src/main/resources/aai-path.properties new file mode 100755 index 000000000..e597d7e0a --- /dev/null +++ b/aai-service/provider/src/main/resources/aai-path.properties @@ -0,0 +1,353 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +cloud-regions = /aai/v21/cloud-infrastructure/cloud-regions +cloud-region = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id} +cloud-region|availability-zones = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/availability-zones +cloud-region|availability-zone = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/availability-zones/availability-zone/{availability-zone-name} +cloud-region|dvs-switches = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/dvs-switches +cloud-region|dvs-switch = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/dvs-switches/dvs-switch/{switch-name} +cloud-region|flavors = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/flavors +cloud-region|flavor = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/flavors/flavor/{flavor-id} +cloud-region|flavor|hpa-capabilities = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/flavors/flavor/{flavor-id}/hpa-capabilities +cloud-region|flavor|hpa-capability = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/flavors/flavor/{flavor-id}/hpa-capabilities/hpa-capability/{hpa-capability-id} +cloud-region|flavor|hpa-capability|hpa-feature-attributes = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/flavors/flavor/{flavor-id}/hpa-capabilities/hpa-capability/{hpa-capability-id}/hpa-feature-attributes/{hpa-attribute-key} +cloud-region|group-assignments = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/group-assignments +cloud-region|group-assignment = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/group-assignments/group-assignment/{group-id} +cloud-region|hpa-capabilities = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/hpa-capabilities +cloud-region|hpa-capability = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/hpa-capabilities/hpa-capability/{hpa-capability-id} +cloud-region|hpa-capability|hpa-feature-attributes = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/hpa-capabilities/hpa-capability/{hpa-capability-id}/hpa-feature-attributes/{hpa-attribute-key} +cloud-region|images = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/images +cloud-region|image = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/images/image/{image-id} +cloud-region|image|metadata = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/images/image/{image-id}/metadata +cloud-region|image|metadatum = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/images/image/{image-id}/metadata/metadatum/{metaname} +cloud-region|oam-networks = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/oam-networks +cloud-region|oam-network = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/oam-networks/oam-network/{network-uuid} +cloud-region|snapshots = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/snapshots +cloud-region|snapshot = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/snapshots/snapshot/{snapshot-id} +cloud-region|tenants = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants +cloud-region|tenant = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id} +cloud-region|tenant|vservers = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers +cloud-region|tenant|vserver = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id} +cloud-region|tenant|vserver|l-interfaces = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces +cloud-region|tenant|vserver|l-interface = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces/l-interface/{interface-name} +cloud-region|tenant|vserver|l-interface|l3-interface-ipv4-address-list = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +cloud-region|tenant|vserver|l-interface|l3-interface-ipv6-address-list = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +cloud-region|tenant|vserver|l-interface|sriov-vfs = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces/l-interface/{interface-name}/sriov-vfs +cloud-region|tenant|vserver|l-interface|sriov-vf = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +cloud-region|tenant|vserver|l-interface|vlans = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces/l-interface/{interface-name}/vlans +cloud-region|tenant|vserver|l-interface|vlan = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +cloud-region|tenant|vserver|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +cloud-region|tenant|vserver|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +cloud-region|tenant|vserver|volumes = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/volumes +cloud-region|tenant|vserver|volume = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}/volumes/volume/{volume-id} +cloud-region|vip-ipv4-address-list = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/vip-ipv4-address-list/{vip-ipv4-address} +cloud-region|vip-ipv6-address-list = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/vip-ipv6-address-list/{vip-ipv6-address} +cloud-region|volume-groups = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/volume-groups +cloud-region|volume-group = /aai/v21/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}/volume-groups/volume-group/{volume-group-id} +complexes = /aai/v21/cloud-infrastructure/complexes +complex = /aai/v21/cloud-infrastructure/complexes/complex/{physical-location-id} +complex|ctag-pools = /aai/v21/cloud-infrastructure/complexes/complex/{physical-location-id}/ctag-pools +complex|ctag-pool = /aai/v21/cloud-infrastructure/complexes/complex/{physical-location-id}/ctag-pools/ctag-pool/{target-pe}/{availability-zone-name} +network-profiles = /aai/v21/cloud-infrastructure/network-profiles +network-profile = /aai/v21/cloud-infrastructure/network-profiles/network-profile/{nm-profile-name} +operational-environments = /aai/v21/cloud-infrastructure/operational-environments +operational-environment = /aai/v21/cloud-infrastructure/operational-environments/operational-environment/{operational-environment-id} +pservers = /aai/v21/cloud-infrastructure/pservers +pserver = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname} +pserver|lag-interfaces = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces +pserver|lag-interface = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name} +pserver|lag-interface|l-interfaces = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces +pserver|lag-interface|l-interface = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name} +pserver|lag-interface|l-interface|l3-interface-ipv4-address-list = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +pserver|lag-interface|l-interface|l3-interface-ipv6-address-list = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +pserver|lag-interface|l-interface|sriov-vfs = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs +pserver|lag-interface|l-interface|sriov-vf = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +pserver|lag-interface|l-interface|vlans = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans +pserver|lag-interface|l-interface|vlan = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +pserver|lag-interface|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +pserver|lag-interface|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +pserver|p-interfaces = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces +pserver|p-interface = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name} +pserver|p-interface|l-interfaces = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces +pserver|p-interface|l-interface = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name} +pserver|p-interface|l-interface|l3-interface-ipv4-address-list = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +pserver|p-interface|l-interface|l3-interface-ipv6-address-list = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +pserver|p-interface|l-interface|sriov-vfs = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs +pserver|p-interface|l-interface|sriov-vf = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +pserver|p-interface|l-interface|vlans = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans +pserver|p-interface|l-interface|vlan = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +pserver|p-interface|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +pserver|p-interface|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +pserver|p-interface|sriov-pfs = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/sriov-pfs +pserver|p-interface|sriov-pf = /aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name}/sriov-pfs/sriov-pf/{pf-pci-id} +virtual-data-centers = /aai/v21/cloud-infrastructure/virtual-data-centers +virtual-data-center = /aai/v21/cloud-infrastructure/virtual-data-centers/virtual-data-center/{vdc-id} +connectors = /aai/v21/business/connectors +connector = /aai/v21/business/connectors/connector/{resource-instance-id} +connector|metadata = /aai/v21/business/connectors/connector/{resource-instance-id}/metadata +connector|metadatum = /aai/v21/business/connectors/connector/{resource-instance-id}/metadata/metadatum/{metaname} +customers = /aai/v21/business/customers +customer = /aai/v21/business/customers/customer/{global-customer-id} +customer|service-subscriptions = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions +customer|service-subscription = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type} +customer|service-subscription|service-instances = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances +customer|service-subscription|service-instance = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances/service-instance/{service-instance-id} +customer|service-subscription|service-instance|allotted-resources = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances/service-instance/{service-instance-id}/allotted-resources +customer|service-subscription|service-instance|allotted-resource = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances/service-instance/{service-instance-id}/allotted-resources/allotted-resource/{id} +customer|service-subscription|service-instance|allotted-resource|tunnel-xconnects = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances/service-instance/{service-instance-id}/allotted-resources/allotted-resource/{id}/tunnel-xconnects +customer|service-subscription|service-instance|allotted-resource|tunnel-xconnect = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances/service-instance/{service-instance-id}/allotted-resources/allotted-resource/{id}/tunnel-xconnects/tunnel-xconnect/{id} +customer|service-subscription|service-instance|metadata = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances/service-instance/{service-instance-id}/metadata +customer|service-subscription|service-instance|metadatum = /aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances/service-instance/{service-instance-id}/metadata/metadatum/{metaname} +configurations = /aai/v21/network/configurations +configuration = /aai/v21/network/configurations/configuration/{configuration-id} +configuration|evcs = /aai/v21/network/configurations/configuration/{configuration-id}/evcs +configuration|evc = /aai/v21/network/configurations/configuration/{configuration-id}/evcs/evc/{evc-id} +configuration|forwarder-evcs = /aai/v21/network/configurations/configuration/{configuration-id}/forwarder-evcs +configuration|forwarder-evc = /aai/v21/network/configurations/configuration/{configuration-id}/forwarder-evcs/forwarder-evc/{forwarder-evc-id} +configuration|metadata = /aai/v21/network/configurations/configuration/{configuration-id}/metadata +configuration|metadatum = /aai/v21/network/configurations/configuration/{configuration-id}/metadata/metadatum/{metaname} +connectivities = /aai/v21/network/connectivities +connectivity = /aai/v21/network/connectivities/connectivity/{connectivity-id} +devices = /aai/v21/network/devices +device = /aai/v21/network/devices/device/{device-id} +esr-thirdparty-sdnc = /aai/v21/external-system/esr-thirdparty-sdnc-list/esr-thirdparty-sdnc/{thirdparty-sdnc-id} +esr-thirdparty-sdnc-list = /aai/v21/external-system/esr-thirdparty-sdnc-list +forwarding-paths = /aai/v21/network/forwarding-paths +forwarding-path = /aai/v21/network/forwarding-paths/forwarding-path/{forwarding-path-id} +forwarding-path|forwarders = /aai/v21/network/forwarding-paths/forwarding-path/{forwarding-path-id}/forwarders +forwarding-path|forwarder = /aai/v21/network/forwarding-paths/forwarding-path/{forwarding-path-id}/forwarders/forwarder/{sequence} +generic-vnfs = /aai/v21/network/generic-vnfs +generic-vnf = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id} +generic-vnf|entitlements = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/entitlements +generic-vnf|entitlement = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/entitlements/entitlement/{group-uuid}/{resource-uuid} +generic-vnf|l-interfaces = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces +generic-vnf|l-interface = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces/l-interface/{interface-name} +generic-vnf|l-interface|l3-interface-ipv4-address-list = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +generic-vnf|l-interface|l3-interface-ipv6-address-list = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +generic-vnf|l-interface|sriov-vfs = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces/l-interface/{interface-name}/sriov-vfs +generic-vnf|l-interface|sriov-vf = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +generic-vnf|l-interface|vlans = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces/l-interface/{interface-name}/vlans +generic-vnf|l-interface|vlan = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +generic-vnf|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +generic-vnf|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +generic-vnf|lag-interfaces = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces +generic-vnf|lag-interface = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name} +generic-vnf|lag-interface|l-interfaces = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces +generic-vnf|lag-interface|l-interface = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name} +generic-vnf|lag-interface|l-interface|l3-interface-ipv4-address-list = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +generic-vnf|lag-interface|l-interface|l3-interface-ipv6-address-list = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +generic-vnf|lag-interface|l-interface|sriov-vfs = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs +generic-vnf|lag-interface|l-interface|sriov-vf = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +generic-vnf|lag-interface|l-interface|vlans = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans +generic-vnf|lag-interface|l-interface|vlan = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +generic-vnf|lag-interface|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +generic-vnf|lag-interface|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +generic-vnf|licenses = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/licenses +generic-vnf|license = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/licenses/license/{group-uuid}/{resource-uuid} +generic-vnf|vf-modules = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/vf-modules +generic-vnf|vf-module = /aai/v21/network/generic-vnfs/generic-vnf/{vnf-id}/vf-modules/vf-module/{vf-module-id} +instance-groups = /aai/v21/network/instance-groups +instance-group = /aai/v21/network/instance-groups/instance-group/{id} +interlayer-attachments = /aai/v21/network/interlayer-attachments +interlayer-attachment = /aai/v21/network/interlayer-attachments/interlayer-attachment/{id} +ipsec-configurations = /aai/v21/network/ipsec-configurations +ipsec-configuration = /aai/v21/network/ipsec-configurations/ipsec-configuration/{ipsec-configuration-id} +ipsec-configuration|vig-servers = /aai/v21/network/ipsec-configurations/ipsec-configuration/{ipsec-configuration-id}/vig-servers +ipsec-configuration|vig-server = /aai/v21/network/ipsec-configurations/ipsec-configuration/{ipsec-configuration-id}/vig-servers/vig-server/{vig-address-type} +l3-networks = /aai/v21/network/l3-networks +l3-network = /aai/v21/network/l3-networks/l3-network/{network-id} +l3-network|ctag-assignments = /aai/v21/network/l3-networks/l3-network/{network-id}/ctag-assignments +l3-network|ctag-assignment = /aai/v21/network/l3-networks/l3-network/{network-id}/ctag-assignments/ctag-assignment/{vlan-id-inner} +l3-network|segmentation-assignments = /aai/v21/network/l3-networks/l3-network/{network-id}/segmentation-assignments +l3-network|segmentation-assignment = /aai/v21/network/l3-networks/l3-network/{network-id}/segmentation-assignments/segmentation-assignment/{segmentation-id} +l3-network|subnets = /aai/v21/network/l3-networks/l3-network/{network-id}/subnets +l3-network|subnet = /aai/v21/network/l3-networks/l3-network/{network-id}/subnets/subnet/{subnet-id} +l3-network|subnet|host-routes = /aai/v21/network/l3-networks/l3-network/{network-id}/subnets/subnet/{subnet-id}/host-routes +l3-network|subnet|host-route = /aai/v21/network/l3-networks/l3-network/{network-id}/subnets/subnet/{subnet-id}/host-routes/host-route/{host-route-id} +label-restrictions = /aai/v21/network/label-restrictions +label-restriction = /aai/v21/network/label-restrictions/label-restriction/{id} +lag-links = /aai/v21/network/lag-links +lag-link = /aai/v21/network/lag-links/lag-link/{link-name} +lines-of-business = /aai/v21/business/lines-of-business +line-of-business = /aai/v21/business/lines-of-business/line-of-business/{line-of-business-name} +logical-links = /aai/v21/network/logical-links +logical-link = /aai/v21/network/logical-links/logical-link/{link-name} +models = /aai/v21/service-design-and-creation/models +model = /aai/v21/service-design-and-creation/models/model/{model-invariant-id} +model|model-vers = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers +model|model-ver = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id} +model|model-ver|metadata = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/metadata +model|model-ver|metadatum = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/metadata/metadatum/{metaname} +model|model-ver|model-elements = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/model-elements +model|model-ver|model-element = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/model-elements/model-element/{model-element-uuid} +model|model-ver|model-element|model-constraints = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/model-elements/model-element/{model-element-uuid}/model-constraints +model|model-ver|model-element|model-constraint = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/model-elements/model-element/{model-element-uuid}/model-constraints/model-constraint/{model-constraint-uuid} +model|model-ver|model-element|model-constraint|constrained-element-sets = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/model-elements/model-element/{model-element-uuid}/model-constraints/model-constraint/{model-constraint-uuid}/constrained-element-sets +model|model-ver|model-element|model-constraint|constrained-element-set = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/model-elements/model-element/{model-element-uuid}/model-constraints/model-constraint/{model-constraint-uuid}/constrained-element-sets/constrained-element-set/{constrained-element-set-uuid} +model|model-ver|model-element|model-constraint|constrained-element-set|element-choice-sets = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/model-elements/model-element/{model-element-uuid}/model-constraints/model-constraint/{model-constraint-uuid}/constrained-element-sets/constrained-element-set/{constrained-element-set-uuid}/element-choice-sets +model|model-ver|model-element|model-constraint|constrained-element-set|element-choice-set = /aai/v21/service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}/model-elements/model-element/{model-element-uuid}/model-constraints/model-constraint/{model-constraint-uuid}/constrained-element-sets/constrained-element-set/{constrained-element-set-uuid}/element-choice-sets/element-choice-set/{element-choice-set-uuid} +multicast-configurations = /aai/v21/network/multicast-configurations +multicast-configuration = /aai/v21/network/multicast-configurations/multicast-configuration/{multicast-configuration-id} +named-queries = /aai/v21/service-design-and-creation/named-queries +named-query = /aai/v21/service-design-and-creation/named-queries/named-query/{named-query-uuid} +named-query|named-query-elements = /aai/v21/service-design-and-creation/named-queries/named-query/{named-query-uuid}/named-query-elements +named-query|named-query-element = /aai/v21/service-design-and-creation/named-queries/named-query/{named-query-uuid}/named-query-elements/named-query-element/{named-query-element-uuid} +named-query|named-query-element|property-constraints = /aai/v21/service-design-and-creation/named-queries/named-query/{named-query-uuid}/named-query-elements/named-query-element/{named-query-element-uuid}/property-constraints +named-query|named-query-element|property-constraint = /aai/v21/service-design-and-creation/named-queries/named-query/{named-query-uuid}/named-query-elements/named-query-element/{named-query-element-uuid}/property-constraints/property-constraint/{property-constraint-uuid} +named-query|named-query-element|related-lookups = /aai/v21/service-design-and-creation/named-queries/named-query/{named-query-uuid}/named-query-elements/named-query-element/{named-query-element-uuid}/related-lookups +named-query|named-query-element|related-lookup = /aai/v21/service-design-and-creation/named-queries/named-query/{named-query-uuid}/named-query-elements/named-query-element/{named-query-element-uuid}/related-lookups/related-lookup/{related-lookup-uuid} +network-policies = /aai/v21/network/network-policies +network-policy = /aai/v21/network/network-policies/network-policy/{network-policy-id} +network-resources = /aai/v21/network/network-resources +network-resource = /aai/v21/network/network-resources/network-resource/{network-id} +newvces = /aai/v21/network/newvces +newvce = /aai/v21/network/newvces/newvce/{vnf-id2} +newvce|l-interfaces = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces +newvce|l-interface = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces/l-interface/{interface-name} +newvce|l-interface|l3-interface-ipv4-address-list = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +newvce|l-interface|l3-interface-ipv6-address-list = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +newvce|l-interface|sriov-vfs = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces/l-interface/{interface-name}/sriov-vfs +newvce|l-interface|sriov-vf = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +newvce|l-interface|vlans = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces/l-interface/{interface-name}/vlans +newvce|l-interface|vlan = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +newvce|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +newvce|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/network/newvces/newvce/{vnf-id2}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +owning-entities = /aai/v21/business/owning-entities +owning-entity = /aai/v21/business/owning-entities/owning-entity/{owning-entity-id} +physical-links = /aai/v21/network/physical-links +physical-link = /aai/v21/network/physical-links/physical-link/{link-name} +platforms = /aai/v21/business/platforms +platform = /aai/v21/business/platforms/platform/{platform-name} +pnfs = /aai/v21/network/pnfs +pnf = /aai/v21/network/pnfs/pnf/{pnf-name} +pnf|lag-interfaces = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces +pnf|lag-interface = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name} +pnf|lag-interface|l-interfaces = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces +pnf|lag-interface|l-interface = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name} +pnf|lag-interface|l-interface|l3-interface-ipv4-address-list = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +pnf|lag-interface|l-interface|l3-interface-ipv6-address-list = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +pnf|lag-interface|l-interface|sriov-vfs = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs +pnf|lag-interface|l-interface|sriov-vf = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +pnf|lag-interface|l-interface|vlans = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans +pnf|lag-interface|l-interface|vlan = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +pnf|lag-interface|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +pnf|lag-interface|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/network/pnfs/pnf/{pnf-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +pnf|p-interfaces = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces +pnf|p-interface = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name} +pnf|p-interface|l-interfaces = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces +pnf|p-interface|l-interface = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name} +pnf|p-interface|l-interface|l3-interface-ipv4-address-list = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +pnf|p-interface|l-interface|l3-interface-ipv6-address-list = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +pnf|p-interface|l-interface|sriov-vfs = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs +pnf|p-interface|l-interface|sriov-vf = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +pnf|p-interface|l-interface|vlans = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans +pnf|p-interface|l-interface|vlan = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +pnf|p-interface|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +pnf|p-interface|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +pnf|p-interface|sriov-pfs = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/sriov-pfs +pnf|p-interface|sriov-pf = /aai/v21/network/pnfs/pnf/{pnf-name}/p-interfaces/p-interface/{interface-name}/sriov-pfs/sriov-pf/{pf-pci-id} +projects = /aai/v21/business/projects +project = /aai/v21/business/projects/project/{project-name} +route-table-references = /aai/v21/network/route-table-references +route-table-reference = /aai/v21/network/route-table-references/route-table-reference/{route-table-reference-id} +sdwan-vpns = /aai/v21/network/sdwan-vpns +sdwan-vpn = /aai/v21/network/sdwan-vpns/sdwan-vpn/{sdwan-vpn-id} +service-capabilities = /aai/v21/service-design-and-creation/service-capabilities +service-capability = /aai/v21/service-design-and-creation/service-capabilities/service-capability/{service-type}/{vnf-type} +services = /aai/v21/service-design-and-creation/services +service = /aai/v21/service-design-and-creation/services/service/{service-id} +site-pair-sets = /aai/v21/network/site-pair-sets +site-pair-set = /aai/v21/network/site-pair-sets/site-pair-set/{site-pair-set-id} +site-pair-set|routing-instances = /aai/v21/network/site-pair-sets/site-pair-set/{site-pair-set-id}/routing-instances +site-pair-set|routing-instance = /aai/v21/network/site-pair-sets/site-pair-set/{site-pair-set-id}/routing-instances/routing-instance/{routing-instance-id} +site-pair-set|routing-instance|site-pairs = /aai/v21/network/site-pair-sets/site-pair-set/{site-pair-set-id}/routing-instances/routing-instance/{routing-instance-id}/site-pairs +site-pair-set|routing-instance|site-pair = /aai/v21/network/site-pair-sets/site-pair-set/{site-pair-set-id}/routing-instances/routing-instance/{routing-instance-id}/site-pairs/site-pair/{site-pair-id} +site-pair-set|routing-instance|site-pair|classes-of-service = /aai/v21/network/site-pair-sets/site-pair-set/{site-pair-set-id}/routing-instances/routing-instance/{routing-instance-id}/site-pairs/site-pair/{site-pair-id}/classes-of-service +site-pair-set|routing-instance|site-pair|class-of-service = /aai/v21/network/site-pair-sets/site-pair-set/{site-pair-set-id}/routing-instances/routing-instance/{routing-instance-id}/site-pairs/site-pair/{site-pair-id}/classes-of-service/class-of-service/{cos} +site-resources = /aai/v21/network/site-resources +site-resource = /aai/v21/network/site-resources/site-resource/{site-resource-id} +te-link-attributes = /aai/v21/network/te-link-attributes +te-link-attribute = /aai/v21/network/te-link-attributes/te-link-attribute/{id} +tunnel-termination-points = /aai/v21/network/tunnel-termination-points +tunnel-termination-point = /aai/v21/network/tunnel-termination-points/tunnel-termination-point/{ttp-id} +unis = /aai/v21/network/unis +uni = /aai/v21/network/unis/uni/{id} +vces = /aai/v21/network/vces +vce = /aai/v21/network/vces/vce/{vnf-id} +vce|entitlements = /aai/v21/network/vces/vce/{vnf-id}/entitlements +vce|entitlement = /aai/v21/network/vces/vce/{vnf-id}/entitlements/entitlement/{group-uuid}/{resource-uuid} +vce|licenses = /aai/v21/network/vces/vce/{vnf-id}/licenses +vce|license = /aai/v21/network/vces/vce/{vnf-id}/licenses/license/{group-uuid}/{resource-uuid} +vce|port-groups = /aai/v21/network/vces/vce/{vnf-id}/port-groups +vce|port-group = /aai/v21/network/vces/vce/{vnf-id}/port-groups/port-group/{interface-id} +vce|port-group|cvlan-tags = /aai/v21/network/vces/vce/{vnf-id}/port-groups/port-group/{interface-id}/cvlan-tags +vce|port-group|cvlan-tag-entry = /aai/v21/network/vces/vce/{vnf-id}/port-groups/port-group/{interface-id}/cvlan-tags/cvlan-tag-entry/{cvlan-tag} +vnf-images = /aai/v21/service-design-and-creation/vnf-images +vnf-image = /aai/v21/service-design-and-creation/vnf-images/vnf-image/{vnf-image-uuid} +vnfcs = /aai/v21/network/vnfcs +vnfc = /aai/v21/network/vnfcs/vnfc/{vnfc-name} +vnfc|cps = /aai/v21/network/vnfcs/vnfc/{vnfc-name}/cps +vnfc|cp = /aai/v21/network/vnfcs/vnfc/{vnfc-name}/cps/cp/{cp-instance-id} +vnfc|cp|l3-interface-ipv4-address-list = /aai/v21/network/vnfcs/vnfc/{vnfc-name}/cps/cp/{cp-instance-id}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +vnfc|cp|l3-interface-ipv6-address-list = /aai/v21/network/vnfcs/vnfc/{vnfc-name}/cps/cp/{cp-instance-id}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +vnfc|l3-interface-ipv4-address-list = /aai/v21/network/vnfcs/vnfc/{vnfc-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +vnfc|l3-interface-ipv6-address-list = /aai/v21/network/vnfcs/vnfc/{vnfc-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +vpls-pes = /aai/v21/network/vpls-pes +vpls-pe = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name} +vpls-pe|lag-interfaces = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces +vpls-pe|lag-interface = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name} +vpls-pe|lag-interface|l-interfaces = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces +vpls-pe|lag-interface|l-interface = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name} +vpls-pe|lag-interface|l-interface|l3-interface-ipv4-address-list = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +vpls-pe|lag-interface|l-interface|l3-interface-ipv6-address-list = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +vpls-pe|lag-interface|l-interface|sriov-vfs = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs +vpls-pe|lag-interface|l-interface|sriov-vf = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +vpls-pe|lag-interface|l-interface|vlans = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans +vpls-pe|lag-interface|l-interface|vlan = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +vpls-pe|lag-interface|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +vpls-pe|lag-interface|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/lag-interfaces/lag-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +vpls-pe|p-interfaces = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces +vpls-pe|p-interface = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name} +vpls-pe|p-interface|l-interfaces = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces +vpls-pe|p-interface|l-interface = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name} +vpls-pe|p-interface|l-interface|l3-interface-ipv4-address-list = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +vpls-pe|p-interface|l-interface|l3-interface-ipv6-address-list = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +vpls-pe|p-interface|l-interface|sriov-vfs = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs +vpls-pe|p-interface|l-interface|sriov-vf = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/sriov-vfs/sriov-vf/{pci-id} +vpls-pe|p-interface|l-interface|vlans = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans +vpls-pe|p-interface|l-interface|vlan = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface} +vpls-pe|p-interface|l-interface|vlan|l3-interface-ipv4-address-list = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv4-address-list/{l3-interface-ipv4-address} +vpls-pe|p-interface|l-interface|vlan|l3-interface-ipv6-address-list = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/l-interfaces/l-interface/{interface-name}/vlans/vlan/{vlan-interface}/l3-interface-ipv6-address-list/{l3-interface-ipv6-address} +vpls-pe|p-interface|sriov-pfs = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/sriov-pfs +vpls-pe|p-interface|sriov-pf = /aai/v21/network/vpls-pes/vpls-pe/{equipment-name}/p-interfaces/p-interface/{interface-name}/sriov-pfs/sriov-pf/{pf-pci-id} +vpn-bindings = /aai/v21/network/vpn-bindings +vpn-binding = /aai/v21/network/vpn-bindings/vpn-binding/{vpn-id} +vpn-binding|route-targets = /aai/v21/network/vpn-bindings/vpn-binding/{vpn-id}/route-targets +vpn-binding|route-target = /aai/v21/network/vpn-bindings/vpn-binding/{vpn-id}/route-targets/route-target/{global-route-target}/{route-target-role} +wan-port-configs = /aai/v21/network/wan-port-configs +wan-port-config = /aai/v21/network/wan-port-configs/wan-port-config/{wan-port-config-id} +lan-port-configs = /aai/v21/network/lan-port-configs +lan-port-config = /aai/v21/network/lan-port-configs/lan-port-config/{lan-port-config-id} +zones = /aai/v21/network/zones +zone = /aai/v21/network/zones/zone/{zone-id} +network-routes = /aai/v21/network/network-routes +network-route = /aai/v21/network/network-routes/network-route/{route-id} diff --git a/aai-service/provider/src/main/resources/aai-schema-bindings.xjb b/aai-service/provider/src/main/resources/aai-schema-bindings.xjb new file mode 100755 index 000000000..996a74afd --- /dev/null +++ b/aai-service/provider/src/main/resources/aai-schema-bindings.xjb @@ -0,0 +1,11 @@ +<jxb:bindings version="1.0" + xmlns:jxb="http://java.sun.com/xml/ns/jaxb" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" + jxb:extensionBindingPrefixes="xjc"> + <jxb:bindings schemaLocation="aai_schema_v21.xsd" node="/xs:schema"> + <jxb:globalBindings> + <xjc:superInterface name="org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum"/> + </jxb:globalBindings> + </jxb:bindings> +</jxb:bindings> diff --git a/aai-service/provider/src/main/resources/aai_schema_v21.xsd b/aai-service/provider/src/main/resources/aai_schema_v21.xsd new file mode 100644 index 000000000..afdda3dc5 --- /dev/null +++ b/aai-service/provider/src/main/resources/aai_schema_v21.xsd @@ -0,0 +1,14837 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://org.onap.aai.inventory/v21" xmlns:tns="http://org.onap.aai.inventory/v21" xmlns:xs="http://www.w3.org/2001/XMLSchema" +xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" + jaxb:version="2.1" + xmlns:annox="http://annox.dev.java.net" + jaxb:extensionBindingPrefixes="annox"> + + <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="5000"/> + <xs:element ref="tns:tagged-inventory-item-list" minOccurs="0" maxOccurs="5000"/> + </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="5000"/> + </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="5000"/> + </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="5000"/> + <xs:element ref="tns:include-node-filter" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:secondary-filter" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="result-data"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="The URL to the specific resource")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="resource-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The specific type of node in the A&AI graph")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-link" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The URL to the specific resource")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="search-results"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:result-data" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="relationship-data"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Value of the attribute.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="relationship-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="A keyword provided by A&AI to indicate an attribute.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="relationship-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Value of the attribute.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="related-to-property"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Value part of a key/value pair")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="property-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Key part of a key/value pair")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="property-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Value part of a key/value pair")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="relationship"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="URL to the object in A&AI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="related-to" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="A keyword provided by A&AI to indicate type of node.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="relationship-label" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The edge label for this relationship.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="related-link" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to the object in A&AI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-data" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:related-to-property" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="relationship-list"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:relationship" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="oam-network"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="OAM network, to be deprecated shortly. Do not use for new purposes. ",nameProps="network-name",indexedProps="cvlan-tag,network-uuid,network-name",dependentOn="cloud-region",container="oam-networks",uriTemplate="/oam-networks/oam-network/{network-uuid}",requiredProps="network-uuid,network-name,cvlan-tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="network-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID of the network. Unique across a cloud-region")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cvlan-tag" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="cvlan-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-oam-gateway-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for VNF firewall rule so customer cannot send customer traffic over this oam network")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-oam-gateway-address-prefix-length" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for VNF firewall rule so customer cannot send customer traffic over this oam network")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="oam-networks"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of OAM networks, to be deprecated shortly. Do not use for new purposes. ")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:oam-network" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="dvs-switch"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Digital virtual switch metadata, used by SDN-C to configure VCEs. A&AI needs to receive this data from the PO deployment team and administer it using the provisioningTool.sh into A&AI. ",indexedProps="vcenter-url,switch-name",dependentOn="cloud-region",container="dvs-switches",uriTemplate="/dvs-switches/dvs-switch/{switch-name}",requiredProps="switch-name,vcenter-url")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="switch-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="DVS switch name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vcenter-url" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL used to reach the vcenter")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="dvs-switches"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of digital virtual switch metadata used for vmWare VCEs and GenericVnfs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:dvs-switch" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="availability-zone"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Availability zone, a collection of compute hosts/pservers",indexedProps="availability-zone-name",dependentOn="cloud-region",container="availability-zones",uriTemplate="/availability-zones/availability-zone/{availability-zone-name}",requiredProps="availability-zone-name,hypervisor-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="availability-zone-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name of the availability zone. Unique across a cloud region")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="hypervisor-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of hypervisor. Source of truth should define valid values.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="State that indicates whether the availability zone should be used, etc. Source of truth should define valid values.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="5000"/> + </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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="update"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Serves a PATCH like function. Does not enforce concurrency control. Clear each usage with AAI team.",requiredProps="update-node-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="update-node-type" type="xs:string" minOccurs="0"/> + <xs:element ref="tns:update-node-key" minOccurs="0" maxOccurs="5000"/> + <xs:element name="update-node-uri" type="xs:string" minOccurs="0"/> + <xs:element ref="tns:action" minOccurs="0" maxOccurs="5000"/> + </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" minOccurs="0"/> + <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="5000"/> + <xs:element name="selflink" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="actions"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="APIs that are more action related than REST (e.g., notify, update).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <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="rack-unit"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of rack-unit",indexedProps="rack-unit-name",dependentOn="rack",container="rack-units",uriTemplate="/rack-units/rack-unit/{rack-unit-name}",requiredProps="rack-unit-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="rack-unit-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="A unique name for the rack-unit (within the rack).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="rack-units"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:rack-unit" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pdu"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of pdu",uniqueProps="pdu-name",indexedProps="pdu-name",dependentOn="rack",container="pdus",uriTemplate="/pdus/pdu/{pdu-name}",requiredProps="pdu-name,pdu-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="pdu-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="A unique name for the power distribution unit.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pdu-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of pdu.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pdus"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:pdu" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="rack"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of rack",uniqueProps="rack-name",indexedProps="rack-name",dependentOn="complex",container="racks",uriTemplate="/racks/rack/{rack-name}",requiredProps="rack-name,rack-type,rack-location,rack-power-diversity")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="rack-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="A unique name for the rack (within the location).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="rack-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of rack.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="rack-location" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The location of the rack within the building.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="rack-position" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The position of the rack (ex-floor-mounted).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="rack-power-diversity" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:rack-units" minOccurs="0"/> + <xs:element ref="tns:pdus" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="racks"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:rack" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="cable"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of cable",indexedProps="cable-name",dependentOn="complex",container="cables",uriTemplate="/cables/cable/{cable-name}",requiredProps="cable-name,cable-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="cable-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="A unique name for the channel-link relative to the physical-link.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cable-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of cable.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="cables"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:cable" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="ctag-pool"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="A collection of C tags (vlan tags) grouped for a specific purpose.",indexedProps="availability-zone-name",dependentOn="complex",container="ctag-pools",uriTemplate="/ctag-pools/ctag-pool/{target-pe}/{availability-zone-name}",requiredProps="target-pe,availability-zone-name,ctag-pool-purpose")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="target-pe" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="The Target provider edge router")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="availability-zone-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name of the availability zone")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ctag-pool-purpose" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Describes what the intended purpose of this pool is.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ctag-values" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Comma separated list of ctags")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="complex"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of physical locations that can house cloud-regions.",indexedProps="identity-url,data-center-code,complex-name,physical-location-id",searchable="physical-location-id,data-center-code,complex-name,street1,street2,postal-code",uniqueProps="physical-location-id",container="complexes",namespace="cloud-infrastructure",uriTemplate="/cloud-infrastructure/complexes/complex/{physical-location-id}",requiredProps="physical-location-id,physical-location-type,street1,city,postal-code,country,region")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="physical-location-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier for physical location, e.g., CLLI")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="data-center-code" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Data center code which can be an alternate way to identify a complex")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="complex-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Gamma complex name for LCP instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="identity-url" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL of the keystone identity service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="physical-location-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type, e.g., central office, data center.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="time-zone" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The time zone where the complex is located.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="street1" type="xs:string" minOccurs="0"/> + <xs:element name="street2" type="xs:string" minOccurs="0"/> + <xs:element name="city" type="xs:string" minOccurs="0"/> + <xs:element name="state" type="xs:string" minOccurs="0"/> + <xs:element name="postal-code" type="xs:string" minOccurs="0"/> + <xs:element name="country" type="xs:string" minOccurs="0"/> + <xs:element name="region" type="xs:string" minOccurs="0"/> + <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:racks" minOccurs="0"/> + <xs:element ref="tns:cables" 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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of physical locations that can house cloud-regions.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:complex" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="volume-group"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Persistent block-level storage.",indexedProps="volume-group-name,vnf-type,heat-stack-id,volume-group-id,orchestration-status",searchable="volume-group-id,volume-group-name",dependentOn="cloud-region",container="volume-groups",uriTemplate="/volume-groups/volume-group/{volume-group-id}",requiredProps="volume-group-id,vnf-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="volume-group-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of volume-group.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="volume-group-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the volume group.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="heat-stack-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Heat stack id corresponding to this volume-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="String capturing type of vnf, that was intended to identify the SDC resource. This field has been overloaded in service-specific ways and clients should expect changes to occur in the future to this field as ONAP matures.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this volume-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="captures the id of all the configuration used to customize the resource for the service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-module-model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="helps relate the volume group to the vf-module whose components will require the volume group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="volume-groups"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of persistent block-level storage.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:volume-group" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="volume"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Ephemeral Block storage volume.",indexedProps="volume-id",dependentOn="vserver",container="volumes",uriTemplate="/volumes/volume/{volume-id}",requiredProps="volume-id,volume-selflink")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="volume-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of block storage volume relative to the vserver.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="volume-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="volumes"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of ephemeral Block storage volumes.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:volume" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="l3-interface-ipv4-address-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="IPv4 Address Range",indexedProps="l3-interface-ipv4-address,vlan-id-inner,neutron-network-id,neutron-subnet-id",dependentOn="vlan,l-interface,vnfc,cp,lag-interface,p-interface",uriTemplate="/l3-interface-ipv4-address-list/{l3-interface-ipv4-address}",requiredProps="l3-interface-ipv4-address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="l3-interface-ipv4-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="IP address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="l3-interface-ipv4-prefix-length" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prefix length, 32 for single address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-inner" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Inner VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-outer" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Outer VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-floating" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator of fixed or floating address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron network id of the interface that address belongs to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-subnet-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron id of subnet that address belongs to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="IPv6 Address Range",indexedProps="l3-interface-ipv6-address,vlan-id-inner,neutron-network-id,neutron-subnet-id",dependentOn="vlan,l-interface,vnfc,cp,lag-interface,p-interface",uriTemplate="/l3-interface-ipv6-address-list/{l3-interface-ipv6-address}",requiredProps="l3-interface-ipv6-address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="l3-interface-ipv6-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="IP address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="l3-interface-ipv6-prefix-length" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prefix length, 128 for single address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-inner" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Inner VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-outer" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Outer VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-floating" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator of fixed or floating address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron network id of the interface that address belongs to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-subnet-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron id of subnet that address belongs to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlan"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of vlan",indexedProps="vlan-interface,vlan-id-inner,vpn-key,orchestration-status,prov-status",dependentOn="l-interface",container="vlans",uriTemplate="/vlans/vlan/{vlan-interface}",requiredProps="vlan-interface,in-maint,is-ip-unnumbered,is-private")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vlan-interface" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="String that identifies the interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-inner" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Inner VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-outer" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Outer VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the numeric part of the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the units corresponding to the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of vlan (eg. vxlan)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to describe (the service associated with) the vlan")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="backdoor-connection" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Whether customer is going to use this VLAN for backdoor connection to another customer premise device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpn-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This indicates the customers VPN ID associated with this vlan")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Status of a vnf's vlan interface, on which the customer circuit resides, mastered by SDN-C.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this object is in maintenance mode (maintenance mode = true)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prov Status of the VLAN configuration related to a logical interface. Valid values [PREPROV/NVTPROV/PROV].")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-ip-unnumbered" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Flag indicating the interface uses the IP Unnumbered configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-private" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Private VLAN indicator.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:l3-interface-ipv4-address-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:l3-interface-ipv6-address-list" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlans"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:vlan" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sriov-vf"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="SR-IOV Virtual Function (not to be confused with virtual network function)",indexedProps="pci-id,vf-vlan-filter,vf-mac-filter,vf-vlan-strip,neutron-network-id",dependentOn="l-interface",container="sriov-vfs",uriTemplate="/sriov-vfs/sriov-vf/{pci-id}",requiredProps="pci-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="pci-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="PCI ID used to identify the sriov-vf")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-vlan-filter" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This metadata provides option to specify list of VLAN filters applied on VF to pass the traffic to VM.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-mac-filter" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="When MAC filters are specified, VF-agent service configures VFs to do MAC level filtering before the traffic is passed to VM.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-vlan-strip" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="When this field is set to true, VF will configured to strip the outer TAG before the traffic is passed to VM.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-vlan-anti-spoof-check" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This option ensures anti VLAN spoof checks are done at the VF level to comply with security. The disable check will also be honored per the VNF needs for trusted VMs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-mac-anti-spoof-check" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This option ensures anti MAC spoof checks are done at the VF level to comply with security. The disable check will also be honored per the VNF needs for trusted VMs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-mirrors" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This option defines the set of Mirror objects which essentially mirrors the traffic from source to set of collector VNF Ports.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-broadcast-allow" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This option, if set to true, sets the VF in promiscuous mode and allows all broadcast traffic to reach the VM")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-unknown-multicast-allow" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This option, if set to true, sets the VF in promiscuous mode and allows unknown multicast traffic to reach the VM")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-unknown-unicast-allow" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This option, if set to true, sets the VF in promiscuous mode and allows unknown unicast traffic to reach the VM")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-insert-stag" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This option, if set to true, instructs to insert outer tag after traffic comes out of VM.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-link-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This option is used to set the link status. Valid values as of 1607 are on, off, and auto.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron network id of the interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sriov-vfs"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of SR-IOV Virtual Functions.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:sriov-vf" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="l-interface"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Logical interfaces, e.g., a vnic.",indexedProps="macaddr,interface-id,interface-name,network-name,interface-type,interface-function,interface-role,prov-status",dependentOn="generic-vnf,newvce,p-interface,vserver,lag-interface,l-interface,pnf,pserver",nameProps="interface-type",container="l-interfaces",uriTemplate="/l-interfaces/l-interface/{interface-name}",searchable="interface-name",requiredProps="interface-name,is-port-mirrored,in-maint,is-ip-unnumbered")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="interface-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name given to the interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="E.g., CUSTOMER, UPLINK, etc.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="v6-wan-link-ip" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Questionably placed - v6 ip addr of this interface (is in vr-lan-interface from Mary B.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ID of interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="macaddr" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="MAC address for the interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the network")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="management-option" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Whether A&AI should be managing this interface of not. Could have value like CUSTOMER")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Human friendly text regarding this interface.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="type to sub-classify the l-interface (ex, loopback)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-port-mirrored" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="boolean indicatating whether or not port is a mirrored.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this object is in maintenance mode (maintenance mode = true)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prov Status of the logical interface. Valid values [PREPROV/NVTPROV/PROV].")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-ip-unnumbered" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Flag indicating the interface uses the IP Unnumbered configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="allowed-address-pairs" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Freeform field for storing an ip address, list of ip addresses or a subnet block.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="priority" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Priority used for fail-over. Valid values 1-1024, with 1 being the highest priority.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by this Linterface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="l2-multicasting" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Identifies l2-multicasting support on an l-interface. true indicates that l2-multicasting is supported; defaulted to false .")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:vlans" minOccurs="0"/> + <xs:element ref="tns:sriov-vfs" minOccurs="0"/> + <xs:element ref="tns:l-interfaces" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:l3-interface-ipv4-address-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:l3-interface-ipv6-address-list" minOccurs="0" maxOccurs="5000"/> + <xs:element name="admin-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Administrative status of the interface. Valid values are 'up', 'down', or 'testing'.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="l-interfaces"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of logical interfaces.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:l-interface" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vserver"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Virtual Servers, aka virtual machine or VM.",nameProps="vserver-name",indexedProps="is-closed-loop-disabled,prov-status,vserver-name,vserver-id,vserver-name2",searchable="vserver-id,vserver-name,vserver-name2,operational-status",dependentOn="tenant",container="vservers",uriTemplate="/vservers/vserver/{vserver-id}",requiredProps="vserver-id,vserver-name,vserver-selflink,in-maint,is-closed-loop-disabled")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vserver-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier for this vserver relative to its tenant")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vserver-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of vserver")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vserver-name2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Alternative name of vserver")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Trigger for operational monitoring of this resource by Service Assurance systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vserver-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Used to indicate whether or not this object is in maintenance mode (maintenance mode = true). This field (in conjunction with prov-status) is used to suppress alarms and vSCL on VNFs/VMs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-closed-loop-disabled" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Used to indicate whether closed loop function is enabled on this node")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="numa" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Non-uniform memory access optimization, helps prevent memory-bandwidth bottlenecks. Expected values - 1 or 2 identifying memory access")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:volumes" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:l-interfaces" minOccurs="0"/> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational. Valid values are in-service-path and out-of-service-path.",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vservers"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of virtual Servers, aka virtual machines or VMs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:vserver" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="nos-server"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="nos-server is the execution environment that will have images, certain versions of VNOS, running on it.",indexedProps="nos-server-id,prov-status",dependentOn="tenant",nameProps="nos-server-name",container="nos-servers",uriTemplate="/nos-servers/nos-server/{nos-server-id}",requiredProps="nos-server-id,nos-server-name,vendor,nos-server-selflink,in-maint")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="nos-server-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier for this nos relative to its tenant")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nos-server-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of nos")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vendor" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="uCPE vendor")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Trigger for operational monitoring of this resource by Service Assurance systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nos-server-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Used to indicate whether or not this object is in maintenance mode (maintenance mode = true). This field (in conjunction with prov-status) is used to suppress alarms and vSCL on VNFs/VMs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="nos-servers"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="nos-server is the execution environment that will have images, certain versions of VNOS, running on it.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:nos-server" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="tenant"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Openstack tenant",nameProps="tenant-name",indexedProps="tenant-name,tenant-id,tenant-context",searchable="tenant-id,tenant-name",dependentOn="cloud-region",container="tenants",uriTemplate="/tenants/tenant/{tenant-id}",requiredProps="tenant-id,tenant-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="tenant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id relative to the cloud-region.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="tenant-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Readable name of tenant")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="tenant-context" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This field will store the tenant context.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="parent-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="tenant parent-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:vservers" minOccurs="0"/> + <xs:element ref="tns:nos-servers" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="tenants"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of openstack tenants.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:tenant" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="hpa-feature-attributes"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="HPA Capability Feature attributes",indexedProps="hpa-attribute-key",dependentOn="hpa-capability",requiredProps="hpa-attribute-key")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="hpa-attribute-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="name of the specific HPA attribute")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="hpa-attribute-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="JSON string specifying the value, unit and type of the specific HPA attribute")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="hpa-capability"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Represents a HPA capability",indexedProps="hpa-feature,architecture,hpa-capability-id",dependentOn="flavor,cloud-region",container="hpa-capabilities",requiredProps="hpa-capability-id,hpa-feature",uriTemplate="/hpa-capabilities/hpa-capability/{hpa-capability-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="hpa-capability-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID to uniquely identify a HPA capability")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="hpa-feature" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the HPACapability")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="hpa-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="HPA schema version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="architecture" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Hardware architecture")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:hpa-feature-attributes" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="hpa-capabilities"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of HPA Capabilities")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:hpa-capability" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="flavor"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Openstack flavor.",nameProps="flavor-name",indexedProps="flavor-name,flavor-id",dependentOn="cloud-region",container="flavors",uriTemplate="/flavors/flavor/{flavor-id}",requiredProps="flavor-id,flavor-name,flavor-selflink")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="flavor-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Flavor id, expected to be unique across cloud-region.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="flavor-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Flavor name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="flavor-vcpus" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Number of CPUs")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="flavor-ram" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Amount of memory")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="flavor-disk" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Disk space")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="flavor-ephemeral" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Amount of ephemeral disk space")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="flavor-swap" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="amount of swap space allocation")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="flavor-is-public" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="whether flavor is available to all users or private to the tenant it was created in.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="flavor-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="flavor-disabled" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Boolean as to whether this flavor is no longer enabled")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:hpa-capabilities" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="List of flavor specific HPA Capabilities")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="flavors"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of openstack flavors.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:flavor" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="group-assignment"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Openstack group-assignment used to store exclusivity groups (EG).",nameProps="group-name",indexedProps="group-id,group-type,group-name",searchable="group-id,group-name",dependentOn="cloud-region",container="group-assignments",uriTemplate="/group-assignments/group-assignment/{group-id}",requiredProps="group-id,group-type,group-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="group-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Group id, expected to be unique across cloud-region.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="group-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Group type - the type of group this instance refers to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="group-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Group name - name assigned to the group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="group-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Group description - description of the group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="group-assignments"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of openstack group assignments")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:group-assignment" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="snapshot"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Openstack snapshot",nameProps="snapshot-name",uniqueProps="snapshot-id",indexedProps="application,snapshot-name,application-vendor,snapshot-id,application-version,prev-snapshot-id",dependentOn="cloud-region",container="snapshots",uriTemplate="/snapshots/snapshot/{snapshot-id}",requiredProps="snapshot-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="snapshot-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Snapshot id, this is the key UUID assoc associated in glance with the snapshots.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="snapshot-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Snapshot name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="snapshot-architecture" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Operating system architecture")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="snapshot-os-distro" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The common name of the operating system distribution in lowercase")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="snapshot-os-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The operating system version as specified by the distributor.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The application that the image instantiates.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application-vendor" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The vendor of the application.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The version of the application.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="snapshot-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prev-snapshot-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This field contains the UUID of the previous snapshot (if any).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="snapshots"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of openstack snapshots")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:snapshot" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="metadatum"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Key/value pairs",indexedProps="metaname",dependentOn="image,service-instance,connector,configuration,model-ver,profile",container="metadata",uriTemplate="/metadata/metadatum/{metaname}",requiredProps="metaname,metaval")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="metaname" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true)</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="metaval" type="xs:string" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="metadata"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of metadatum (key/value pairs)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:metadatum" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="image"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Openstack image.",nameProps="image-name",indexedProps="application,image-name,application-vendor,image-id,application-version",dependentOn="cloud-region",container="images",uriTemplate="/images/image/{image-id}",requiredProps="image-id,image-name,image-os-distro,image-os-version,image-selflink")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="image-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Image id, expected to be unique across cloud region")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="image-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Image name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="image-architecture" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Operating system architecture.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="image-os-distro" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The common name of the operating system distribution in lowercase")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="image-os-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The operating system version as specified by the distributor.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The application that the image instantiates.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application-vendor" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The vendor of the application.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The version of the application.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="image-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collectio of Openstack images.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:image" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="availability-zones"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of availability zones")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:availability-zone" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vip-ipv4-address-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="IPv4 Address Range",indexedProps="vip-ipv4-address,vlan-id-inner,neutron-network-id,neutron-subnet-id",dependentOn="cloud-region",uriTemplate="/vip-ipv4-address-list/{vip-ipv4-address}",requiredProps="vip-ipv4-address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vip-ipv4-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="IP address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vip-ipv4-prefix-length" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prefix length, 32 for single address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-inner" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Inner VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-outer" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Outer VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-floating" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator of fixed or floating address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron network id of the interface that address belongs to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-subnet-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron id of subnet that address belongs to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vip-ipv6-address-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="IPv6 Address Range",indexedProps="vip-ipv6-address,vlan-id-inner,neutron-network-id,neutron-subnet-id",dependentOn="cloud-region",uriTemplate="/vip-ipv6-address-list/{vip-ipv6-address}",requiredProps="vip-ipv6-address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vip-ipv6-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="IP address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vip-ipv6-prefix-length" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prefix length, 128 for single address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-inner" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Inner VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-outer" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Outer VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-floating" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator of fixed or floating address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron network id of the interface that address belongs to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-subnet-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron id of subnet that address belongs to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlan-tag"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="vlan tag information",container="vlan-tags",dependentOn="vlan-range",uriTemplate="/vlan-tags/vlan-tag/{vlan-tag-id}",requiredProps="vlan-tag-id,vlan-tag-role,is-private")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vlan-tag-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Vlan Tag Id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-tag-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role assigned to this vlan-tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-inner" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Inner VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-outer" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Outer VLAN tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-private" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="is private flag.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-tag-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="VLAN tag Type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-tag-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="VLAN Tag Function")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="config-phase" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The config-phase associated with this vlan-tag")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlan-tags"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Vlan Tags Assigned out of a Vlan Range")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:vlan-tag" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlan-range"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of vlan range",indexedProps="vlan-range-id,vlan-type",dependentOn="cloud-region",container="vlan-ranges",uriTemplate="/vlan-ranges/vlan-range/{vlan-range-id}",searchable="vlan-range-id",requiredProps="vlan-range-id,vlan-id-lower,vlan-id-upper,vlan-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vlan-range-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="vlan id in range UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-lower" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="vlan id in range lower")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-upper" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="vlan id in range upper")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="vlan type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:vlan-tags" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlan-ranges"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:vlan-range" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="host-aggregate"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an hostAggregates",dependentOn="cloud-region",container="host-aggregates",uriTemplate="/host-aggregates/host-aggregate/{host-aggregate-id}",requiredProps="host-aggregate-id,host-aggregate-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="host-aggregate-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier for the host-aggregate.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="host-aggregate-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the host-aggregate.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="host-aggregates"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of HostAggregates.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:host-aggregate" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="activity-state"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an activities",uniqueProps="state-order",dependentOn="activity",container="activity-states",uriTemplate="/activity-states/activity-state/{state-order}",requiredProps="state-order,state-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="state-order" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Order for the activity state.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="state-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the activity state (ex, NVT-PROV).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="state-view" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="View of the activity state.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="activity-states"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of activity-states")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:activity-state" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="activity"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an activities",uniqueProps="activity-id",dependentOn="pserver,pnf,cloud-region,p-interface,network-range",container="activities",uriTemplate="/activities/activity/{activity-id}",requiredProps="activity-id,activity-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="activity-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id for the activity. (UUID)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="activity-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of activity (ex, provisioning).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="activity-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the activity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="activity-creator" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Application that created the activity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="activity-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Description of activity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="timestamp" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Date and Time activity is created.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="current-state" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Current state of the activity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="reflected-state" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="State reflected by the database.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="activity-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="activity-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Function")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="timestamp-last-updated" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Date/time last updated")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="timestamp-expiration" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Date/time expires")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:activity-states" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="activities"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of activities.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:activity" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="validation-audit"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="validation audit, value of validation status",indexedProps="validation-id",uniqueProps="validation-id",dependentOn="cloud-region",container="validation-audits",uriTemplate="/validation-audits/validation-audit/{validation-id}",requiredProps="validation-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="validation-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Validation-Audit UUID")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="validation-request-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Request-id to retrieve data from client related to the specified audit")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="validation-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Status of the audit")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="validation-phase" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Phase in the lifecycle of the configuration")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="validation-audits"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of validation-audit")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:validation-audit" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-system-info"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Persist common address information of external systems.",indexedProps="esr-system-info-id,system-name,system-type",searchable="esr-system-info-id,system-name,system-type",container="esr-system-info-list",dependentOn="cloud-region,esr-ems,esr-vnfm,esr-thirdparty-sdnc,ext-aai-network,esr-nfvo",requiredProps="esr-system-info-id,user-name,password,system-type",uriTemplate="/esr-system-info-list/esr-system-info/{esr-system-info-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="esr-system-info-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of esr system info.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="system-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="name of external system.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="type of external systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vendor" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="vendor of external systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="version of external systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-url" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="url used to access external systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="user-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="username used to access external systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="password" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="password used to access external systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="system-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="it could be vim/vnfm/thirdparty-sdnc/ems-resource/ems-performance/ems-alarm.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="protocol" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="protocol of third party SDNC, for example netconf/snmp.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ssl-cacert" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ca file content if enabled ssl on auth-url.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ssl-insecure" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Whether to verify VIM's certificate.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ip-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="service IP of ftp server.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="service port of ftp server.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-domain" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="domain info for authentication.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="default-tenant" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="default tenant of VIM.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="passive" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ftp passive mode or not.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="remote-path" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="resource or performance data file path.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="system-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the status of external system.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="openstack-region-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="OpenStack region ID used by MultiCloud plugin to interact with an OpenStack instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-system-info-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of persistent block-level external system auth info.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:esr-system-info" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="cloud-region"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="cloud-region designates an installation of a cloud cluster or region or instantiation. In AT&Ts AIC cloud, this could be an LCP or DCP. Cloud regions are uniquely identified by a composite key, cloud-owner + cloud-region-id. The format of the cloud-owner is vendor-cloudname and we will use att-aic for AT&T's AIC.",indexedProps="cloud-owner,cloud-region-id,cloud-type,owner-defined-type",nameProps="owner-defined-type",container="cloud-regions",namespace="cloud-infrastructure",uriTemplate="/cloud-infrastructure/cloud-regions/cloud-region/{cloud-owner}/{cloud-region-id}",requiredProps="cloud-owner,cloud-region-id,orchestration-disabled,in-maint")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="cloud-owner" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Identifies the vendor and cloud name. First part of composite key should be formatted as vendor-cloudname")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-region-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Identifier used by the vendor for the region. Second part of composite key")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of the cloud (e.g., openstack)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="owner-defined-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Cloud-owner defined type indicator (e.g., dcp, lcp)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-region-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Software version employed at the site. NOTE - THIS FIELD IS NOT KEPT UP TO DATE.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="identity-url" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL of the keystone identity service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-zone" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Zone where the cloud is homed. NOTE - THIS FIELD IS NOT CORRECTLY POPULATED.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="complex-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="complex name for cloud-region instance. NOTE - THIS FIELD IS NOT CORRECTLY POPULATED.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sriov-automation" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Whether the cloud region supports (true) or does not support (false) SR-IOV automation.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-extra-info" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ESR inputs extra information about the VIM or Cloud which will be decoded by MultiVIM.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-region-number" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Number that maps to the letter at the end of the cloud-region-id.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Function of cloud-region.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role of cloud-region.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cloud-region-number-definition" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The alias used for this cloud.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Status of cloud-region.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="upgrade-cycle" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Upgrade cycle for the cloud region. For AIC regions upgrade cycle is designated by A,B,C etc.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-disabled" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Used to indicate whether orchestration is enabled for this cloud-region.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Used to indicate whether or not cloud-region object is in maintenance mode.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:element ref="tns:vip-ipv4-address-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:vip-ipv6-address-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:vlan-ranges" minOccurs="0"/> + <xs:element ref="tns:host-aggregates" minOccurs="0"/> + <xs:element ref="tns:activities" minOccurs="0"/> + <xs:element ref="tns:validation-audits" minOccurs="0"/> + <xs:element ref="tns:hpa-capabilities" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="List of cloud-region specific HPA Capabilities")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:esr-system-info-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="cloud-regions"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(maximumDepth="0")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:cloud-region" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-profile"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Network profile populated by SDN-GP for SNMP",indexedProps="nm-profile-name",container="network-profiles",namespace="cloud-infrastructure",uriTemplate="/cloud-infrastructure/network-profiles/network-profile/{nm-profile-name}",requiredProps="nm-profile-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="nm-profile-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique name of network profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="community-string" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Encrypted SNMP community string")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-profiles"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of network profiles")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:network-profile" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="available-bandwidth"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of an available-bandwidth-map",indexedProps="ab-id",searchable="ab-id",uniqueProps="ab-id",container="available-bandwidth-map",dependentOn="bandwidth-attribute",requiredProps="ab-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="ab-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Id that identifies the attribute")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="odu-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ODU Type that identifies the ODU Eg. ODU0, ODU1, ODU2, ODU3, ODU4")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="number" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The value of available bandwidth. Applicable only for ENNI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="available-bandwidth-map"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of Available Bandwidth. Added for ENNI in MDONS use case.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:available-bandwidth" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="otn-label-restriction"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a otn-label-restriction attribute",indexedProps="lr-id",searchable="lr-id",uniqueProps="lr-id",container="otn-label-restrictions",dependentOn="bandwidth-attribute",requiredProps="lr-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="lr-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Id that identifies the label restriction")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="range-bitmap" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Bitmap of available labels starting from label-start to label-end.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="label-step" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Step of labels in label range.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="otn-label-restrictions"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of Label Restriction. Added for ENNI in MDONS use case.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:otn-label-restriction" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="bandwidth-attribute"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a bandwidth-attribute",indexedProps="bwa-id",searchable="bwa-id",uniqueProps="bwa-id",container="bandwidth-attributes",dependentOn="pnf,p-interface",requiredProps="bwa-id",uriTemplate="/bandwidth-attributes/bandwidth-attribute/{bwa-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="bwa-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Id that identifies the bandwidth attribute")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:available-bandwidth-map" minOccurs="0"/> + <xs:element ref="tns:otn-label-restrictions" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="bandwidth-attributes"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of bandwidth attribute. Added for ENNI in MDONS use case.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:bandwidth-attribute" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sriov-pf"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="SR-IOV Physical Function",indexedProps="pf-pci-id",dependentOn="p-interface",container="sriov-pfs",uriTemplate="/sriov-pfs/sriov-pf/{pf-pci-id}",requiredProps="pf-pci-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="pf-pci-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Identifier for the sriov-pf")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sriov-pfs"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of SR-IOV Physical Functions.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:sriov-pf" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="p-interface"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Physical interface (e.g., nic)",indexedProps="interface-name,prov-status,network-ref,operational-status,interface-role,interface-name2",nameProps="prov-status",dependentOn="vpls-pe,pserver,pnf",container="p-interfaces",uriTemplate="/p-interfaces/p-interface/{interface-name}",searchable="interface-name",requiredProps="interface-name,in-maint")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="interface-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name that identifies the physical interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-name2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Alternate name that identifies the physical interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the numeric part of the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the units corresponding to the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Nature of the services and connectivity on this port.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="domain-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Domain type of the SDNC controllerr.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equipment-identifier" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CLEI or other specification for p-interface hardware.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role specification for p-interface hardware.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicates the physical properties of the interface.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-interface-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicates the physical properties of the interface.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:bandwidth-attributes" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The data structure to indicate value of available bandwidth. Applicable only for ENNI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Trigger for operational monitoring of this resource by Service Assurance systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mac-addresss" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="MAC Address of the p-interface.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this object is in maintenance mode (maintenance mode = true)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="inv-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="inventory status")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by this pInterface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="macaddr" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="MAC address for the interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-ref" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the network-ref of this p-interface. Derived from ietf-restconf-notification that identifies a termination-point.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="transparent" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the transparent value of this p-interface.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="oper Status of this p-interface.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="inter-domain-plug-id" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="connect interdomain link")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:sriov-pfs" minOccurs="0"/> + <xs:element ref="tns:l-interfaces" minOccurs="0"/> + <xs:element ref="tns:activities" minOccurs="0"/> + <xs:element ref="tns:l3-interface-ipv4-address-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:l3-interface-ipv6-address-list" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="p-interfaces"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of physical interfaces.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:p-interface" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="lag-interface"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Link aggregate interface",indexedProps="interface-name,interface-id,interface-role,interface-function,prov-status",dependentOn="generic-vnf,pserver,vpls-pe,pnf",container="lag-interfaces",uriTemplate="/lag-interfaces/lag-interface/{interface-name}",requiredProps="interface-name,in-maint")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="interface-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name that identifies the link aggregate interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Human friendly text regarding this interface.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the numeric part of the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the units corresponding to the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ID of interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role assigned to this Interface, should use values as defined in ONAP Yang models.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Trigger for operational monitoring of this resource by Service Assurance systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this object is in maintenance mode (maintenance mode = true)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="lacp-system-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The system id used by the LACP protocol.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by this Lag interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="min-links" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Minimum links in service before a LAG should be taken out of service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:l-interfaces" minOccurs="0"/> + <xs:element ref="tns:l3-interface-ipv4-address-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:l3-interface-ipv6-address-list" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="lag-interfaces"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of link aggregate interfaces.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:lag-interface" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="hpa-capacity"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="HPA Capacity information for compute node",indexedProps="hpa-capacity-key",dependentOn="pserver",requiredProps="hpa-capacity-key")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="hpa-capacity-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Composite key formed with hpaFeature and append list of hpaFeatureAttributes needed for capacity check")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="hpa-capacity-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="JSON string specifying the capacity (total,free), unit and metadata of the specific HPA attribute")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pserver"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Compute host whose hostname must be unique and must exactly match what is sent as a relationship to a vserver.",nameProps="pserver-name2,fqdn",indexedProps="hostname,pserver-id,pserver-name2,inv-status,fqdn,prov-status,ptnii-equip-name",searchable="hostname,pserver-name2,pserver-id,ipv4-oam-address,operational-status",uniqueProps="hostname",container="pservers",namespace="cloud-infrastructure",uriTemplate="/cloud-infrastructure/pservers/pserver/{hostname}",requiredProps="hostname,in-maint")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="hostname" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Value from executing hostname on the compute node.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ptnii-equip-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="PTNII name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="number-of-cpus" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Number of cpus")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="disk-in-gigabytes" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Disk size, in GBs")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ram-in-megabytes" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="RAM size, in MBs")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Equipment type. Source of truth should define valid values.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-vendor" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Equipment vendor. Source of truth should define valid values.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-model" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Equipment model. Source of truth should define valid values.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="fqdn" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Fully-qualified domain name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pserver-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-oam-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to configure device, also used for troubleshooting and is IP used for traps generated by device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="serial-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Serial number, may be queried")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v4-loopback-0" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV4 Loopback 0 address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v6-loopback-0" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV6 Loopback 0 address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v4-aim" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV4 AIM address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v6-aim" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV6 AIM address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v6-oam" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV6 OAM address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="inv-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CANOPI's inventory status. Only set with values exactly as defined by CANOPI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pserver-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ID of Pserver")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="internet-topology" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="internet topology of Pserver")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this object is in maintenance mode (maintenance mode = true). This field (in conjunction with prov-status) is used to suppress alarms and vSCL on VNFs/VMs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pserver-name2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="alternative pserver name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="purpose" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="purpose of pserver")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prov Status of this device (not under canopi control) Valid values [PREPROV/NVTPROV/PROV]")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="management-option" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicates who owns and or manages the device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="host-profile" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The host profile that defines the configuration of the pserver.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The role performed by the pserver.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by the pserver.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational. Valid values are in-service-path and out-of-service-path.",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:p-interfaces" minOccurs="0"/> + <xs:element ref="tns:l-interfaces" minOccurs="0"/> + <xs:element ref="tns:lag-interfaces" minOccurs="0"/> + <xs:element ref="tns:activities" minOccurs="0"/> + <xs:element ref="tns:hpa-capacity" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pservers"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of compute hosts.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:pserver" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="virtual-data-center"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Virtual organization of cloud infrastructure elements in a data center context",nameProps="vdc-name",indexedProps="vdc-name,vdc-id",container="virtual-data-centers",namespace="cloud-infrastructure",uriTemplate="/cloud-infrastructure/virtual-data-centers/virtual-data-center/{vdc-id}",requiredProps="vdc-id,vdc-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vdc-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of the vdc")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vdc-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the virtual data center")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="virtual-data-centers"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Virtual organization of cloud infrastructure elements in a data center context")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:virtual-data-center" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="operational-environment"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="It is a logical partition of the cloud which allows to have multiple environments in the production AIC.",indexedProps="operational-environment-id",nameProps="operational-environment-name",uniqueProps="operational-environment-id",container="operational-environments",namespace="cloud-infrastructure",uriTemplate="/cloud-infrastructure/operational-environments/operational-environment/{operational-environment-id}",requiredProps="operational-environment-id,operational-environment-name,operational-environment-type,operational-environment-status,tenant-context,workload-context")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="operational-environment-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID of an operational environment")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-environment-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Operational Environment name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-environment-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Operational Environment Type.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-environment-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Status")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="tenant-context" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Tenant Context.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="workload-context" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Workload Context.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="operational-environments"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="a logical partition of the cloud which allows to have multiple environments in the production AIC.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:operational-environment" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="geo-region"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Top level node for a cg-nat geographical region.",indexedProps="geo-region-id",uniqueProps="geo-region-id",container="geo-regions",namespace="cloud-infrastructure",uriTemplate="/cloud-infrastructure/geo-regions/geo-region/{geo-region-id}",requiredProps="geo-region-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="geo-region-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID, key for geo-region object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="geo-region-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of geo-region")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="geo-region-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of geo-region")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="geo-region-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role of geo-region")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="geo-region-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Function of geo-region")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="geo-regions"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of geo-regions")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:geo-region" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-technology"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="The network-technology object is used to capture the supported network technologies of a cloud-region.",nameProps="network-technology-id,network-technology-name",uniqueProps="network-technology-id",container="network-technologies",namespace="cloud-infrastructure",uriTemplate="/cloud-infrastructure/network-technologies/network-technology/{network-technology-id}",requiredProps="network-technology-id,network-technology-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="network-technology-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier of the network-technology object (UUID)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-technology-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The network-technology that a cloud-region can support. Current valid values- CONTRAIL AIC_SR_IOV OVS STANDARD-SR-IOV")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-technologies"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description=" The network-technology object is used to capture the supported network technologies of a cloud-region.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:network-technology" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="cloud-infrastructure"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Namespace for cloud infrastructure.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <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:element ref="tns:operational-environments" minOccurs="0"/> + <xs:element ref="tns:geo-regions" minOccurs="0"/> + <xs:element ref="tns:network-technologies" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-ems"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Persist EMS address information used by EMS driver.",indexedProps="ems-id",searchable="ems-id",container="esr-ems-list",namespace="external-system",requiredProps="ems-id",uriTemplate="/external-system/esr-ems-list/esr-ems/{ems-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="ems-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of EMS.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:esr-system-info-list" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-ems-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(maximumDepth="0")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:esr-ems" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-vnfm"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Persist VNFM address information used by VF-C.",indexedProps="vnfm-id",searchable="vnfm-id",container="esr-vnfm-list",namespace="external-system",requiredProps="vnfm-id",uriTemplate="/external-system/esr-vnfm-list/esr-vnfm/{vnfm-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vnfm-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of VNFM.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vim-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indecate the VIM to deploy VNF.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="certificate-url" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="certificate url of VNFM.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:esr-system-info-list" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-vnfm-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(maximumDepth="0")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:esr-vnfm" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-nfvo"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Persist NFVO address information used by VF-C.",indexedProps="nfvo-id",searchable="nfvo-id",container="esr-nfvo-list",namespace="external-system",requiredProps="nfvo-id",uriTemplate="/external-system/esr-nfvo-list/esr-nfvo/{nfvo-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="nfvo-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of nfvo.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="api-root" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indecate the api-root.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:esr-system-info-list" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-nfvo-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(maximumDepth="0")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:esr-nfvo" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-thirdparty-sdnc"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Persist SDNC address information used by ONAP SDNC.",container="esr-thirdparty-sdnc-list",namespace="external-system",requiredProps="thirdparty-sdnc-id",uriTemplate="/external-system/esr-thirdparty-sdnc-list/esr-thirdparty-sdnc/{thirdparty-sdnc-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="thirdparty-sdnc-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of SDNC.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="location" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="used for DC type to indicate the location of SDNC, such as Core or Edge.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="product-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="password used to access SDNC server.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="domain-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Domain type of the SDNC controllerr.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:esr-system-info-list" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="esr-thirdparty-sdnc-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(maximumDepth="0")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:esr-thirdparty-sdnc" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="external-system"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Namespace for external system.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:esr-ems-list" minOccurs="0"/> + <xs:element ref="tns:esr-vnfm-list" minOccurs="0"/> + <xs:element ref="tns:esr-nfvo-list" minOccurs="0"/> + <xs:element ref="tns:esr-thirdparty-sdnc-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="connector"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of resource instances used to connect a variety of disparate inventory widgets",indexedProps="resource-instance-id,model-invariant-id,model-version-id,widget-model-id,widget-model-version",container="connectors",namespace="business",uriTemplate="/business/connectors/connector/{resource-instance-id}",requiredProps="resource-instance-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="resource-instance-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id of resource instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary widget model. This maps directly to the A&AI widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary version of the widget model.This maps directly to the A&AI version of the widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of resource instances used to connect a variety of disparate inventory widgets")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:connector" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="tunnel-xconnect"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Represents the specifics of a tunnel cross connect piece of a resource that gets separately allotted",uniqueProps="id",indexedProps="id",dependentOn="allotted-resource",container="tunnel-xconnects",uriTemplate="/tunnel-xconnects/tunnel-xconnect/{id}",requiredProps="id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Allotted Resource id UUID assigned to this instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="tunnel-xconnects"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="This object is used to store the specific tunnel cross connect aspects of an allotted resource")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:tunnel-xconnect" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="allotted-resource"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Represents a slice or partial piece of a resource that gets separately allotted",nameProps="description,allotted-resource-name",uniqueProps="id",indexedProps="id,model-invariant-id,model-version-id,type,role,allotted-resource-name,access-provider-id,access-client-id,access-topology-id,access-node-id,access-ltp-id,vpn-name,orchestration-status",dependentOn="service-instance",container="allotted-resources",uriTemplate="/allotted-resources/allotted-resource/{id}",requiredProps="id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Allotted Resource id UUID assigned to this instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The descriptive information assigned to this allotted resource instance")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Link back to more information in the controller")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Generic description of the type of allotted resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="role in the network that this resource will be providing.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="allotted-resource-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the name of this allotted-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-provider-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access provider of this allotted-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-client-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access client of this allotted-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-topology-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access topology of this allotted-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-node-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access node of this allotted-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-ltp-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access ltp of this allotted-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cvlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the cvlan of this allotted-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpn-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the vpn-name of this allotted-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:tunnel-xconnects" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="allotted-resources"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="This object is used to store slices of services being offered")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:allotted-resource" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="communication-service-profile"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Requirement of comunication service.",uniqueProps="profile-id",indexedProps="profile-id",container="communication-service-profiles",dependentOn="service-instance",uriTemplate="/service-instances/service-instance/{service-instance-id}/communication-service-profiles/communication-service-profile/{profile-id}",searcheable="profile-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="profile-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="ID of the profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-number-of-UEs" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The maximum number of UEs may simultaneously access the communication service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="coverage-area-list" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="A list of TrackingAreas where the NSI can be selected.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="latency" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The packet transmission latency (millisecond) through the RAN, CN, and TN part of 5G network and is used to evaluate utilization performance of the end-to-end network slice instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="exp-data-rate-UL" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="User experience data rate of upload.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="exp-data-rate-DL" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="User experience data rate of download.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ue-mobility-level" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="User mobility level, value can be stationary, nomadic, restricted mobility, fully mobility.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-sharing-level" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Whether the resources to be allocated to the network slice instance may be shared with another network slice instance(s).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="communication-service-profiles"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of communication service profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:communication-service-profile" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="service-profile"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Requirement of E2E Slice service.",uniqueProps="profile-id",indexedProps="profile-id",container="service-profiles",dependentOn="service-instance",uriTemplate="/service-instances/service-instance/{service-instance-id}/service-profiles/service-profile/{profile-id}",searcheable="profile-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="profile-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="ID of the profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="latency" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The packet transmission latency (millisecond) through the RAN, CN, and TN part of 5G network and is used to evaluate utilization performance of the end-to-end network slice instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-number-of-UEs" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The maximum number of UEs may simultaneously access the E2E slice service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="coverage-area-TA-list" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="A list of TrackingAreas where the NSI can be selected.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ue-mobility-level" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="User mobility level, value can be stationary, nomadic, restricted mobility, fully mobility.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-sharing-level" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Whether the resources to be allocated to the network slice instance may be shared with another network slice instance(s).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="activity-factor" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Percentage value of the amount of simultaneous active UEs to the total number of UEs where active means the UEs are exchanging data with the network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="jitter" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The jitter requirements of network slice.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="survival-time" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="An attribute specifies the time that an application consuming a communication service may continue without an anticipated message.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="availability" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This parameter specifies the availability requirement, expressed as a percentage.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="reliability" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="An attribute specifies in the context of network layer packet transmissions, percentage value of the amount of sent network layer packets successfully delivered to a given system entity within the time constraint required by the targeted service, divided by the total number of sent network layer packets.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dl-thpt-per-slice" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This attribute defines achievable data rate of the network slice in downlink that is available ubiquitously across the coverage area of the slice.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dl-thpt-per-UE" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This attribute defines downlink data rate supported by the network slice per UE.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ul-thpt-per-slice" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This attribute defines achievable data rate of the network slice in uplink that is available ubiquitously across the coverage area of the slice.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ul-thpt-per-UE" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This attribute defines uplink data rate supported by the network slice per UE.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-pkt-size" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This parameter specifies the maximum packet size supported by the network slice.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-number-of-conns" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This parameter defines the maximum number of concurrent sessions supported by the network slice.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="term-density" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="An attribute specifies the overall user density over the coverage area of the network slice.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="service-profiles"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of E2E slice service profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:service-profile" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="slice-profile"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Requirement of network slice subnet service.",uniqueProps="profile-id",indexedProps="profile-id",container="slice-profiles",dependentOn="service-instance",uriTemplate="/service-instances/service-instance/{service-instance-id}/slice-profiles/slice-profile/{profile-id}",searcheable="profile-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="profile-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="ID of the profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="latency" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The packet transmission latency (millisecond) through the RAN or CN or TN and is used to evaluate utilization performance of the end-to-end network slice instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-number-of-UEs" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The maximum number of UEs may simultaneously access the slice subnet service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="coverage-area-TA-list" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="A list of TrackingAreas where the NSSI can be selected.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ue-mobility-level" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="User mobility level, value can be stationary, nomadic, restricted mobility, fully mobility.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-sharing-level" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Whether the resources to be allocated to the slice subnet instance may be shared with another network slice instance(s).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="exp-data-rate-UL" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="User experience data rate of upload.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="exp-data-rate-DL" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="User experience data rate of download.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="area-traffic-cap-UL" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The area traffic capbility of upload.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="area-traffic-cap-DL" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The area traffic capbility of download.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="activity-factor" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="An attribute specfies the percentage value of the amount of simultaneous active UEs to the total number of UEs where active means the UEs are exchanging data with the network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="jitter" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The jitter requirements of network slice subnet.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="survival-time" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Survival time for network slice subnet.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cs-availability-target" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Communication service availability target value.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-bandwidth" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Maxmun bandwidth value of TN network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="exp-data-rate" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Expected date rate for uRLLC.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-number-of-PDU-session" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="maxNumberofPDUSession Integer 1 The maximum number of PDU sessions that can simultaneously/concurrently access to the network slice.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="overall-user-density" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Overall User Density.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cs-reliability-mean-time" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Communication service reliability mean time between failures.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="msg-size-byte" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Message size(byte) .")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="transfer-interval-target" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="transferIntervalTarget String 1 Target value of transfer interval.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="slice-profiles"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of slice subnet service profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:slice-profile" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="service-instance"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a service",indexedProps="service-instance-id,model-invariant-id,model-version-id,widget-model-id,widget-model-version,service-instance-name,service-instance-location-id,orchestration-status,environment-context,workload-context",nameProps="service-instance-name",searchable="service-instance-id,service-instance-name,operational-status",uniqueProps="service-instance-id",dependentOn="service-subscription",container="service-instances",uriTemplate="/service-instances/service-instance/{service-instance-id}",requiredProps="service-instance-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="service-instance-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this instance of a service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-instance-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This field will store a name assigned to the service-instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="String capturing type of service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="String capturing the service role.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-rate" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Rate of the service instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-layer" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Definition of the service layer.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="due-date" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Due date of the service creation.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="end-date" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="End date of the service creation.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="environment-context" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This field will store the environment context assigned to the service-instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="workload-context" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This field will store the workload context assigned to the service-instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="created-at" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="create time of Network Service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="updated-at" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="last update of Network Service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="short description for service-instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="persona-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="internal",dataCopy="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}#model-version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary widget model. This maps directly to the A&AI widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary version of the widget model.This maps directly to the A&AI version of the widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bandwidth-total" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicates the total bandwidth to be used for this service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bandwidth-up-wan1" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indicates the upstream bandwidth this service will use on the WAN1 port of the physical device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bandwidth-down-wan1" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indicates the downstream bandwidth this service will use on the WAN1 port of the physical device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bandwidth-up-wan2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indicates the upstream bandwidth this service will use on the WAN2 port of the physical device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bandwidth-down-wan2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indicates the downstream bandwidth this service will use on the WAN2 port of the physical device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vhn-portal-url" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL customers will use to access the vHN Portal.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-instance-location-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="An identifier that customers assign to the location where this service is being used.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Path to the controller object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="input-parameters" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="String capturing request parameters from SO to pass to Closed Loop.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="String capturing function of the service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:metadata" minOccurs="0"/> + <xs:element ref="tns:allotted-resources" minOccurs="0"/> + <xs:element ref="tns:communication-service-profiles" minOccurs="0"/> + <xs:element ref="tns:service-profiles" minOccurs="0"/> + <xs:element ref="tns:slice-profiles" minOccurs="0"/> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational. Valid values are in-service-path and out-of-service-path.",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="service-instances"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of service instances")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:service-instance" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="service-subscription"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Object that group service instances.",indexedProps="service-type",dependentOn="customer",container="service-subscriptions",crossEntityReference="service-instance,service-type",uriTemplate="/service-subscriptions/service-subscription/{service-type}",requiredProps="service-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="service-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Value defined by orchestration to identify this service across ONAP.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="temp-ub-sub-account-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This property will be deleted from A&AI in the near future. Only stop gap solution.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of objects that group service instances.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:service-subscription" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="customer"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="customer identifiers to provide linkage back to BSS information.",nameProps="subscriber-name",indexedProps="subscriber-name,global-customer-id,subscriber-type",searchable="global-customer-id,subscriber-name",uniqueProps="global-customer-id",container="customers",namespace="business",uriTemplate="/business/customers/customer/{global-customer-id}",requiredProps="global-customer-id,subscriber-name,subscriber-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="global-customer-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Global customer id used across ONAP to uniquely identify customer.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="subscriber-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Subscriber name, an alternate way to retrieve a customer.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="subscriber-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Subscriber type, a way to provide VID with only the INFRA customers.",defaultValue="CUST")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of customer identifiers to provide linkage back to BSS information.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:customer" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="line-of-business"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes a line-of-business",indexedProps="line-of-business-name",uniqueProps="line-of-business-name",container="lines-of-business",namespace="business",uriTemplate="/business/lines-of-business/line-of-business/{line-of-business-name}",requiredProps="line-of-business-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="line-of-business-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name of the line-of-business (product)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="lines-of-business"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of lines-of-business")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:line-of-business" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="owning-entity"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an owning-entity",indexedProps="owning-entity-id,owning-entity-name",searchable="owning-entity-id",uniqueProps="owning-entity-id,owning-entity-name",container="owning-entities",namespace="business",uriTemplate="/business/owning-entities/owning-entity/{owning-entity-id}",requiredProps="owning-entity-id,owning-entity-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="owning-entity-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID of an owning entity")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="owning-entity-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Owning entity name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="owning-entities"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of owning-entities")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:owning-entity" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="platform"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes a platform",indexedProps="platform-name",uniqueProps="platform-name",container="platforms",namespace="business",uriTemplate="/business/platforms/platform/{platform-name}",requiredProps="platform-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="platform-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name of the platform")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="platforms"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of platforms")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:platform" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="project"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes the project",indexedProps="project-name",uniqueProps="project-name",container="projects",namespace="business",uriTemplate="/business/projects/project/{project-name}",requiredProps="project-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="project-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name of the project deploying a service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="project-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of project (ex, VPMO)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="project-state" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Current state of the project.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Description of the project.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="projects"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of projects")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:project" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sp-partner"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of an sp-partner",indexedProps="sp-partner-id,url,callsource,model-invariant-id,model-version-id",nameProps="sp-partner-id",searchable="sp-partner-id",uniqueProps="sp-partner-id",container="sp-partners",namespace="business",uriTemplate="/business/sp-partners/sp-partner/{sp-partner-id}",requiredProps="sp-partner-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="sp-partner-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this sp-partner by id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="url" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the URL of this sp-partner.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="callsource" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the callsource of this sp-partner.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this sp-partner.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this sp-partner.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this sp-partner model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this sp-partner model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sp-partners"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of sp-partners")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:sp-partner" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="business"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Namespace for business related constructs")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:connectors" minOccurs="0"/> + <xs:element ref="tns:customers" minOccurs="0"/> + <xs:element ref="tns:lines-of-business" minOccurs="0"/> + <xs:element ref="tns:owning-entities" minOccurs="0"/> + <xs:element ref="tns:platforms" minOccurs="0"/> + <xs:element ref="tns:projects" minOccurs="0"/> + <xs:element ref="tns:sp-partners" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vnf-image"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Image object that pertain to a VNF that doesn't have associated vservers. This is a kludge.",indexedProps="application,vnf-image-uuid,application-vendor,application-version",uniqueProps="vnf-image-uuid",container="vnf-images",namespace="service-design-and-creation",uriTemplate="/service-design-and-creation/vnf-images/vnf-image/{vnf-image-uuid}",requiredProps="vnf-image-uuid,application,application-vendor")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vnf-image-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of this asset")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The application that the image instantiates.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application-vendor" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The vendor of the application.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The version of the application.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vnf-images"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of image objects that pertain to a VNF that doesn't have associated vservers. This is a kludge.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:vnf-image" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="service"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Stand-in for service model definitions. Likely to be deprecated in favor of models from ASDC. Does not strictly map to ASDC services.",indexedProps="service-description,service-id",container="services",namespace="service-design-and-creation",uriTemplate="/service-design-and-creation/services/service/{service-id}",requiredProps="service-id,service-description")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="service-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="This gets defined by others to provide a unique ID for the service, we accept what is sent.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Description of the service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="service version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="services"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of service model definitions. Likely to be deprecated in favor of models from ASDC.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:service" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="service-capability"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Early definition of server/resource pairings, likely to be replaced by models. No new use should be made of this.",indexedProps="service-type,vnf-type",container="service-capabilities",namespace="service-design-and-creation",uriTemplate="/service-design-and-creation/service-capabilities/service-capability/{service-type}/{vnf-type}",requiredProps="service-type,vnf-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="service-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="This gets defined by others to provide a unique ID for the service, we accept what is sent.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="String capturing type of vnf, that was intended to identify the SDC resource. This field has been overloaded in service-specific ways and clients should expect changes to occur in the future to this field as ONAP matures.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="service-capabilities"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of service capabilities.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:service-capability" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="element-choice-set"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="This is how we would capture constraints defining allowed sets of elements.",uniqueProps="element-choice-set-uuid",indexedProps="element-choice-set-uuid",allowDirectRead="true",allowDirectWrite="false",dependentOn="constrained-element-set",container="element-choice-sets",uriTemplate="/element-choice-sets/element-choice-set/{element-choice-set-uuid}",requiredProps="element-choice-set-uuid,element-choice-set-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="element-choice-set-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,autoGenerateUuid="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="element-choice-set-name" type="xs:string" minOccurs="0"/> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="constrained-element-set"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="This is how we would capture constraints defining allowed sets of elements.",uniqueProps="constrained-element-set-uuid",indexedProps="constrained-element-set-uuid",allowDirectRead="true",allowDirectWrite="false",dependentOn="model-constraint,model-element",container="constrained-element-sets",uriTemplate="/constrained-element-sets/constrained-element-set/{constrained-element-set-uuid}",requiredProps="constrained-element-set-uuid,constraint-type,check-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="constrained-element-set-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,autoGenerateUuid="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="constraint-type" type="xs:string" minOccurs="0"/> + <xs:element name="check-type" type="xs:string" minOccurs="0"/> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="model-constraint"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="This is how we would capture constraints defining allowed sets of elements.",uniqueProps="model-constraint-uuid",indexedProps="model-constraint-uuid",allowDirectRead="true",allowDirectWrite="false",dependentOn="model-element",container="model-constraints",uriTemplate="/model-constraints/model-constraint/{model-constraint-uuid}",requiredProps="model-constraint-uuid,constrained-element-set-uuid-to-replace")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="model-constraint-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,autoGenerateUuid="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="constrained-element-set-uuid-to-replace" type="xs:string" minOccurs="0"/> + <xs:element ref="tns:constrained-element-sets" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="model-constraints"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:model-constraint" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="model-element"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Defines how other models combine to make up a higher-level model.",uniqueProps="model-element-uuid",indexedProps="model-element-uuid",allowDirectRead="true",dependentOn="element-choice-set,model-element,model-ver",allowDirectWrite="false",container="model-elements",uriTemplate="/model-elements/model-element/{model-element-uuid}",requiredProps="model-element-uuid,new-data-del-flag,cardinality")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="model-element-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,autoGenerateUuid="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="new-data-del-flag" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicates whether this element was created as part of instantiation from this model")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cardinality" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="How many of this type of element are required/allowed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="linkage-points" type="xs:string" minOccurs="0" maxOccurs="5000"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:model-elements" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Defines how other models combine to make up a higher-level model")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:model-constraints" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Describes new constraints on this model element that are not part of that model's definition")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="model-ver"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Subgraph definition provided by ASDC to describe a specific version of an inventory asset and its connections related to ASDC models",nameProps="model-name",indexedProps="model-version-id,model-name,model-version,distribution-status",uniqueProps="model-version-id",dependentOn="model",container="model-vers",uriTemplate="/model-vers/model-ver/{model-version-id}",requiredProps="model-version-id,model-name,model-version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier corresponding to one version of a model in ASDC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the model, which can change from version to version.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="distribution-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Distribution Status")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Description")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sdnc-model-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The CDS blue print name associated with the resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sdnc-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The version of the CDS blue print.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="model-vers"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:model-ver" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="model"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Subgraph definition provided by ASDC to describe an inventory asset and its connections related to ASDC models, independent of version",nameProps="model-type",indexedProps="model-invariant-id,model-type",uniqueProps="model-invariant-id",container="models",namespace="service-design-and-creation",uriTemplate="/service-design-and-creation/models/model/{model-invariant-id}",requiredProps="model-invariant-id,model-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier corresponding to the main definition of a model in ASDC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of the model, e.g., service, resource, widget, etc.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role of the model,e.g.,NST,NSST,CST,etc")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:model-vers" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="models"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of subgraph definitions provided by ASDC to describe the inventory assets and their connections related to ASDC models")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:model" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="related-lookup"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="TBD",uniqueProps="related-lookup-uuid",indexedProps="related-lookup-uuid",allowDirectRead="true",allowDirectWrite="false",dependentOn="named-query-element",container="related-lookups",requiredProps="related-lookup-uuid,source-node-type,source-node-property,target-node-type,target-node-property",uriTemplate="/related-lookups/related-lookup/{related-lookup-uuid}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="related-lookup-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,autoGenerateUuid="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="source-node-type" type="xs:string" minOccurs="0"/> + <xs:element name="source-node-property" type="xs:string" minOccurs="0"/> + <xs:element name="target-node-type" type="xs:string" minOccurs="0"/> + <xs:element name="target-node-property" type="xs:string" minOccurs="0"/> + <xs:element name="property-collect-list" type="xs:string" minOccurs="0" maxOccurs="5000"/> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="property-constraint"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="TBD",uniqueProps="property-constraint-uuid",indexedProps="property-constraint-uuid",allowDirectRead="true",allowDirectWrite="false",dependentOn="named-query-element",container="property-constraints",requiredProps="property-constraint-uuid,constraint-type,property-name,property-value",uriTemplate="/property-constraints/property-constraint/{property-constraint-uuid}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="property-constraint-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,autoGenerateUuid="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="constraint-type" type="xs:string" minOccurs="0"/> + <xs:element name="property-name" type="xs:string" minOccurs="0"/> + <xs:element name="property-value" type="xs:string" minOccurs="0"/> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="named-query-element"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="TBD",uniqueProps="named-query-element-uuid",indexedProps="named-query-element-uuid",allowDirectRead="true",allowDirectWrite="false",dependentOn="named-query,named-query-element",container="named-query-elements",requiredProps="named-query-element-uuid",uriTemplate="/named-query-elements/named-query-element/{named-query-element-uuid}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="named-query-element-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,autoGenerateUuid="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="property-collect-list" type="xs:string" minOccurs="0" maxOccurs="5000"/> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="named-query"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="TBD",nameProps="named-query-name",uniqueProps="named-query-uuid",indexedProps="named-query-uuid,named-query-name",container="named-queries",namespace="service-design-and-creation",requiredProps="named-query-uuid,named-query-name,named-query-version",uriTemplate="/service-design-and-creation/named-queries/named-query/{named-query-uuid}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="named-query-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true)</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="named-query-name" type="xs:string" minOccurs="0"/> + <xs:element name="named-query-version" type="xs:string" minOccurs="0"/> + <xs:element name="required-input-params" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="required-input-param" type="xs:string" minOccurs="0" maxOccurs="5000"/> + </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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="service-design-and-creation"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Namespace for objects managed by ASDC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Logical links generally connect l-interfaces but are used to express logical connectivity between two points",indexedProps="link-name,model-invariant-id,model-version-id,widget-model-id,widget-model-version,link-id,prov-status,circuit-id,link-function,link-type,purpose,operational-status",uniqueProps="link-id",container="logical-links",namespace="network",searchable="link-name",uriTemplate="/network/logical-links/logical-link/{link-name}",requiredProps="link-name,in-maint,link-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="link-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="e.g., evc-name, or vnf-nameA_interface-nameA_vnf-nameZ_interface-nameZ")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this object is in maintenance mode (maintenance mode = true). This field (in conjunction with prov-status) is used to suppress alarms and vSCL on VNFs/VMs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of logical link, e.g., evc")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the numeric part of the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the units corresponding to the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="available-capacity" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the units corresponding to the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="admin-state" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the administrative state of the link")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ip-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="v4, v6, or ds for dual stack")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="routing-protocol" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="For example, static or BGP")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary widget model. This maps directly to the A&AI widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary version of the widget model.This maps directly to the A&AI version of the widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indication of operational status of the logical link.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Trigger for operational monitoring of this VNF by BAU Service Assurance systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indication of the network use of the logical link.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-name2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Alias or alternate name (CLCI or D1 name).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="UUID of the logical-link, SDNC generates this.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="circuit-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Circuit id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="purpose" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Reason for this entity, role it is playing")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="A description for the logical-link.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="segment-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="A segment-id assigned to the logical-link (ex, esi for ethernet segments).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by this logical link")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="logical-links"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of logical connections")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:logical-link" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="class-of-service"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(indexedProps="cos",dependentOn="site-pair",container="classes-of-service",uriTemplate="/classes-of-service/class-of-service/{cos}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="cos" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="unique identifier of probe")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="probe-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="identifier of probe")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="probe-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="type of probe")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="classes-of-service"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="class-of-service of probe")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:class-of-service" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="site-pair"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(indexedProps="site-pair-id",uniqueProps="site-pair-id",dependentOn="routing-instance",container="site-pairs",uriTemplate="/site-pairs/site-pair/{site-pair-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="site-pair-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="unique identifier of probe")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="source-ip" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prefix address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="destination-ip" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prefix address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ip-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ip version, v4, v6")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="destination-hostname" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Hostname of the destination equipment to which SLAs are measured against.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="destination-equip-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of destinatination equipment. Could be Router, UCPE, etc.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="probe within a set")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:site-pair" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="routing-instance"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(indexedProps="routing-instance-id",dependentOn="site-pair-set",container="routing-instances",uriTemplate="/routing-instances/routing-instance/{routing-instance-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="routing-instance-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id of routing instance")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="rpm-owner" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="rpm owner")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="set of probes related to generic-vnf routing instance")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:routing-instance" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="site-pair-set"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Set of instances for probes used to measure service level agreements",indexedProps="site-pair-set-id",uniqueProps="site-pair-set-id",container="site-pair-sets",namespace="network",uriTemplate="/network/site-pair-sets/site-pair-set/{site-pair-set-id}",requiredProps="site-pair-set-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="site-pair-set-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id of site pair set.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of sets of instances for probes related to generic-vnf")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:site-pair-set" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="route-target"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Route target information",container="route-targets",dependentOn="vpn-binding,vrf",canBeLinked="true",uriTemplate="/route-targets/route-target/{global-route-target}/{route-target-role}",requiredProps="global-route-target,route-target-role")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="global-route-target" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Number used to identify an RT, globally unique in the network")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="route-target-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Role assigned to this route target")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="route-targets"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of route target information")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:route-target" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vpn-binding"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="VPN binding",nameProps="vpn-name,vpn-type",indexedProps="vpn-name,vpn-id,vpn-type,access-provider-id,access-client-id,access-topology-id,src-access-node-id,src-access-ltp-id,dst-access-node-id,dst-access-ltp-id,operational-status,model-invariant-id,model-version-id",searchable="vpn-id,vpn-name",uniqueProps="vpn-id",container="vpn-bindings",namespace="network",uriTemplate="/network/vpn-bindings/vpn-binding/{vpn-id}",requiredProps="vpn-id,vpn-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vpn-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="VPN ID, globally unique within A&AI")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpn-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="VPN Name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpn-platform" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the platform associated with the VPN example AVPN, Mobility")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpn-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of the vpn, should be taken from enumerated/valid values")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpn-region" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="region of customer vpn")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="customer-vpn-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="id for this customer vpn")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="route-distinguisher" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to distinguish the distinct VPN routes of separate customers who connect to the provider in an MPLS network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-provider-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access provider of this vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-client-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access client of this vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-topology-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access topology of this vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="src-access-node-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the src-access-node of this vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="src-access-ltp-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the src-access-ltp of this vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dst-access-node-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the dst-access-node of this vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dst-access-ltp-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the dst-access-ltp of this vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-prefix-v4" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Max prefix for IPv4.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-prefix-v6" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Max prefix for IPv6.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-prefix-threshold" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Max prefix threshold.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="label-mode-v4" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Label mode for IPv4.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="label-mode-v6" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Label mode for IPv6.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpn-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The description of the vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vxlan-network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="A VNI associated with the VPN.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-path" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="A variable BGP max AS path length.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:route-targets" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="l3-networks relate to vpn-bindings")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vpn-bindings"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:vpn-binding" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vpls-pe"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="VPLS Provider Edge routers.",indexedProps="prov-status,equipment-name",container="vpls-pes",namespace="network",uriTemplate="/network/vpls-pes/vpls-pe/{equipment-name}",requiredProps="equipment-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="equipment-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true)</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Trigger for operational monitoring of this VNF by BAU Service Assurance systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-oam-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Address tail-f uses to configure generic-vnf, also used for troubleshooting and is IP used for traps generated by GenericVnf (v4-loopback0-ip-address).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equipment-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Client should send valid enumerated value, e.g., VPLS-PE.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-outer" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Temporary location for stag to get to VCE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of VPLS Provider Edge routers")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:vpls-pe" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="multicast-configuration"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(indexedProps="multicast-configuration-id",uniqueProps="multicast-configuration-id",container="multicast-configurations",namespace="network",uriTemplate="/network/multicast-configurations/multicast-configuration/{multicast-configuration-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="multicast-configuration-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id of multicast configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="multicast-protocol" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="protocol of multicast configuration")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="rp-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="rp type of multicast configuration")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="multicast-configurations"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="multicast configuration of generic-vnf ip-address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:multicast-configuration" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="cvlan-tag-entry"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(dependentOn="port-group",indexedProps="cvlan-tag",container="cvlan-tags",uriTemplate="/cvlan-tags/cvlan-tag/{cvlan-tag}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="cvlan-tag" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="See mis-na-virtualization-platform.yang")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="port-group"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Used to capture the network interfaces of this VCE",nameProps="port-group-name",indexedProps="port-group-id,heat-stack-id,interface-id,switch-name,interface-role,orchestration-status",dependentOn="vce",container="port-groups",uriTemplate="/port-groups/port-group/{interface-id}",requiredProps="interface-id,orchestration-status")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="interface-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of the interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron network id of this Interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-network-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron network name of this Interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="interface-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role assigned to this Interface, should use values as defined in ECOMP Yang models.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-group-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Unique ID for port group in vmware")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-group-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Likely to duplicate value of neutron network name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="switch-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="DVS or standard switch name (should be non-null for port groups associated with DVS)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this VNF, mastered by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="heat-stack-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Heat stack id corresponding to this instance, managed by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mso-catalog-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Corresponds to the SDN-C catalog id used to configure this VCE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="license"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Metadata for license group.",indexedProps="group-uuid,resource-uuid,project-number,order-number,receipt-date",dependentOn="chassis,generic-vnf,vce",container="licenses",uriTemplate="/licenses/license/{group-uuid}/{resource-uuid}",requiredProps="group-uuid,resource-uuid")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="group-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID for the license group the resource belongs to, should be uuid.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of a license resource. ")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="project-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to store CFAS or other project numbers.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="order-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Order number.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="receipt-date" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Date of receipt.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="licenses"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Licenses to be allocated across resources, keyed by group-uuid and resource-uuid, related to license management")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:license" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="entitlement"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Metadata for entitlement group.",indexedProps="group-uuid,resource-uuid",dependentOn="generic-vnf,vce",container="entitlements",uriTemplate="/entitlements/entitlement/{group-uuid}/{resource-uuid}",requiredProps="group-uuid,resource-uuid")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="group-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID for the entitlement group the resource comes from, should be uuid.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of an entitlement resource. ")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="entitlements"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Entitlements, keyed by group-uuid and resource-uuid, related to license management")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:entitlement" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vce"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Virtual Customer Edge Router, used specifically for Gamma. This object is deprecated.",nameProps="vnf-name",indexedProps="vnf-name,vnf-name2,vnf-type,heat-stack-id,vnf-id,regional-resource-zone,vpe-id,prov-status,service-id,orchestration-status",searchable="vnf-id,vnf-name,vnf-name2",uniqueProps="vnf-id",container="vces",namespace="network",extendsFrom="vnf",uriTemplate="/network/vces/vce/{vnf-id}",requiredProps="vnf-id,vnf-name,vnf-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vnf-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id of VNF. This is unique across the graph.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of VNF.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-name2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Alternate name of VNF.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="String capturing type of vnf, that was intended to identify the SDC resource. This field has been overloaded in service-specific ways and clients should expect changes to occur in the future to this field as ONAP matures.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Unique identifier of service, does not strictly map to ASDC services, SOON TO BE DEPRECATED.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="regional-resource-zone" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Regional way of organizing pservers, source of truth should define values")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Trigger for operational monitoring of this resource by Service Assurance systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="license-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="OBSOLETE - do not use")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equipment-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Network role being played by this VNF")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this VNF, mastered by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="heat-stack-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Heat stack id corresponding to this instance, managed by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mso-catalog-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Corresponds to the SDN-C catalog id used to configure this VCE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpe-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Unique ID of VPE connected to this VCE.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="v6-vce-wan-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Valid v6 IP address for the WAN Link on this router. Implied length of /64.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-oam-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Address tail-f uses to configure vce, also used for troubleshooting and is IP used for traps generated by VCE.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-loopback0-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Loopback0 address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="entitlement-resource-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="OBSOLETE - see child relationships")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:port-groups" minOccurs="0"/> + <xs:element ref="tns:licenses" minOccurs="0"/> + <xs:element ref="tns:entitlements" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vces"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of Virtual Customer Edge Routers, used specifically for Gamma. This object is deprecated.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:vce" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="cp"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="| SE group | This object captures the point of attachment from services or resources to a virtual link or network. | A&AI clients for this object are typically: DCAE-DTI, (DMaaP-DCAE,...) |",uniqueProps="cp-instance-id",dependentOn="vnfc",container="cps",uriTemplate="/cps/cp/{cp-instance-id}",requiredProps="cp-instance-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="cp-instance-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of the connection point.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-id" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="port index to represent multiple CPs on VNFC connected to same network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:l3-interface-ipv4-address-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:l3-interface-ipv6-address-list" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="cps"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of connection points.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:cp" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vnfc"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(indexedProps="vnfc-name,prov-status,nfc-function,nfc-naming-code,ipaddress-v4-oam-vip,is-closed-loop-disabled,group-notation,model-invariant-id,model-version-id,orchestration-status",searchable="vnfc-name",container="vnfcs",namespace="network",uriTemplate="/network/vnfcs/vnfc/{vnfc-name}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vnfc-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of vnfc.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nfc-naming-code" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Short code that is used in naming instances of the item being modeled")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nfc-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="English description of function that the specific resource deployment is providing. Assigned as part of the customization of a resource in a service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="prov status of this vnfc")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this VNF, mastered by APP-C")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v4-oam-vip" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Oam V4 vip address of this vnfc")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this object is in maintenance mode (maintenance mode = true)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-closed-loop-disabled" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether closed loop function is enabled on this node")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="group-notation" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Group notation of VNFC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="captures the id of all the configuration used to customize the resource for the service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:cps" minOccurs="0"/> + <xs:element ref="tns:l3-interface-ipv4-address-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:l3-interface-ipv6-address-list" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vnfcs"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="virtual network components associated with a vserver from application controller.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:vnfc" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="host-route"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(indexedProps="host-route-id",dependentOn="subnet",container="host-routes",uriTemplate="/host-routes/host-route/{host-route-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="host-route-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="host-route id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="route-prefix" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="subnet prefix")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="next-hop" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Could be ip-address, hostname, or service-instance")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="next-hop-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Should be ip-address, hostname, or service-instance to match next-hop")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="metric" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Value that is assigned to an IP route for a particular network interface that identifies the cost that is associated with using that route.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="host-routes"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:host-route" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="address-family"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of address family",indexedProps="address-family-id,af-type",nameProps="address-family-id,af-type",dependentOn="bgp-group,bgp-neighbor",container="address-families",uriTemplate="/address-families/address-family/{address-family-id}",requiredProps="address-family-id,af-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="address-family-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="address family UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="af-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="address family type (aka afi)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="af-subtype" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="address family subtype (aka safi)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="af-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="role of address-family")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="af-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="function of address-family")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="address-families"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:address-family" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="bgp-neighbor"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of bgp-neighbor",indexedProps="bgp-neighbor-id",dependentOn="pnf,vrf,subnet,generic-vnf",nameProps="bgp-neighbor-id",container="bgp-neighbors",uriTemplate="/bgp-neighbors/bgp-neighbor/{bgp-neighbor-id}",requiredProps="bgp-neighbor-id,bgp-neighbor-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="bgp-neighbor-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bgp-neighbor-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="name of bgp-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bgp-neighbor-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="type of bgp-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bgp-neighbor-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="role of bgp-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="local-as" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="local a-s number type of vrf (bridge-domain as an example)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="local-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="local address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="peer-as" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="peer a-s number")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="peer-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="peer address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="description of bgp-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="provisioning status. Valid values can be found at (https://wiki.web.att.com/display/SPTIIRP/prov-status).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="peer-hostname" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="hostname of the peer")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:address-families" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="bgp-neighbors"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:bgp-neighbor" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="subnet"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(indexedProps="subnet-id,subnet-name,subnet-type,subnet-function,orchestration-status",nameProps="subnet-name",uniqueProps="subnet-id",dependentOn="l3-network,zone",container="subnets",uriTemplate="/subnets/subnet/{subnet-id}",requiredProps="subnet-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="subnet-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Subnet ID, should be UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="subnet-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name associated with the subnet.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-subnet-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron id of this subnet")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="gateway-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="gateway ip address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-start-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="network start address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cidr-mask" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="cidr mask")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ip-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ip version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this VNF, mastered by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="text used for documentation")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dhcp-enabled" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="dhcp enabled")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dhcp-start" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the start address reserved for use by dhcp")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dhcp-end" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the last address reserved for use by dhcp")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="subnet-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="role of the subnet, referenced when assigning IPs")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="subnet-model" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="subnet model BGP, VRPP")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="subnet-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Subtype used to categorize this physical link")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="subnet-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by this Linterface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ip-assignment-direction" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ip address assignment direction of the subnet")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="subnet-sequence" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="sequence of the subnet")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:host-routes" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:bgp-neighbors" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="subnets"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:subnet" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="ctag-assignment"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(indexedProps="vlan-id-inner",dependentOn="l3-network",container="ctag-assignments",uriTemplate="/ctag-assignments/ctag-assignment/{vlan-id-inner}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vlan-id-inner" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="id.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="segmentation-assignment"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Openstack segmentation assignment.",indexedProps="segmentation-id",dependentOn="l3-network",container="segmentation-assignments",uriTemplate="/segmentation-assignments/segmentation-assignment/{segmentation-id}",requiredProps="segmentation-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="segmentation-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Route Table Reference id, UUID assigned to this instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="segmentation-assignments"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of openstack segmentation assignments")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:segmentation-assignment" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="aggregate-route"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Aggregate route configs are used on the D2 IPE’s for the Voice services. In 1902, SDNC will create aggregate-route objects and write them to A&AI. ",uniqueProps="agg-route-id",container="aggregate-routes",dependentOn="vrf,l3-network",uriTemplate="/aggregate-routes/aggregate-route/{agg-route-id}",requiredProps="agg-route-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="agg-route-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Route UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-start-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the forwarding-path")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cidr-mask" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CIDR-mask for aggregate route subnet")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ip-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Identifies is aggregate route is ipv4 or ipv6")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="aggregate-routes"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of aggregate routes.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:aggregate-route" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="l3-network"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Generic network definition",nameProps="network-name",indexedProps="heat-stack-id,service-id,network-id,network-name,model-invariant-id,model-version-id,widget-model-id,widget-model-version,contrail-network-fqdn,network-role,network-function,orchestration-status",searchable="network-id,network-name",uniqueProps="network-id",container="l3-networks",namespace="network",uriTemplate="/network/l3-networks/l3-network/{network-id}",requiredProps="network-id,is-bound-to-vpn,is-provider-network,is-shared-network,is-external-network")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Network ID, should be uuid. Unique across A&AI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the network, governed by some naming convention..")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of the network - who defines these values?")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role the network plans - who defines these values?")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-technology" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Network technology - who defines these values?")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="text used for documentation")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="neutron-network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Neutron network id of this Interface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-bound-to-vpn" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Set to true if bound to VPN")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Unique identifier of service from ASDC. Does not strictly map to ASDC services. SOON TO BE DEPRECATED")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-role-instance" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="network role instance")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this VNF, mastered by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="heat-stack-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Heat stack id corresponding to this instance, managed by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mso-catalog-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Corresponds to the SDN-C catalog id used to configure this VCE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="contrail-network-fqdn" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Contrail FQDN for the network")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="persona-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="internal",dataCopy="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}#model-version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="captures the id of all the configuration used to customize the resource for the service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary widget model. This maps directly to the A&AI widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary version of the widget model.This maps directly to the A&AI version of the widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="physical-network-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name associated with the physical network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-provider-network" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="boolean indicatating whether or not network is a provider network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-shared-network" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="boolean indicatating whether or not network is a shared network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-external-network" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="boolean indicatating whether or not network is an external network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Path to the controller object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-trunked" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Trunked network indication.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by this l3 network")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:aggregate-routes" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Relates to tenant (or is it a child of tenant), complex, service, vpn-binding")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="l3-networks"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:l3-network" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-policy"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(nameProps="network-policy-fqdn",indexedProps="network-policy-id,network-policy-fqdn",searchable="network-policy-id,network-policy-fqdn",uniqueProps="network-policy-id",container="network-policies",namespace="network",uriTemplate="/network/network-policies/network-policy/{network-policy-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="network-policy-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID representing unique key to this instance")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-policy-fqdn" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Contrail FQDN for the policy")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="heat-stack-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ID for the openStack Heat instance")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the policy")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of the policy")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="latency" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The packet transmission latency (millisecond) through the Transport slice connections and is used to evaluate utilization performance of the end-to-end network slice instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="jitter" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="jitter")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="max-bandwidth" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The maximum bandwidth (mb) of the connection links in a transport slice instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="reliability" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The reliability requirement for an network slice subnet instance, expressed as a percentage.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vf-module"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="a deployment unit of VNFCs",indexedProps="vf-module-id,vf-module-name,heat-stack-id,model-invariant-id,model-version-id,widget-model-id,widget-model-version,contrail-service-instance-fqdn,orchestration-status",searchable="vf-module-id,vf-module-name,operational-status",dependentOn="generic-vnf",container="vf-modules",uriTemplate="/vf-modules/vf-module/{vf-module-id}",requiredProps="vf-module-id,is-base-vf-module,automated-assignment")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vf-module-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of vf-module.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vf-module-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of vf-module")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="heat-stack-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Heat stack id corresponding to this instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="orchestration status of this vf-module, mastered by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-base-vf-module" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this object is base vf module")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="automated-assignment" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Indicates whether vf-module assignment was done via automation or manually")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="persona-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="internal",dataCopy="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}#model-version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="captures the id of all the configuration used to customize the resource for the service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary widget model. This maps directly to the A&AI widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary version of the widget model.This maps directly to the A&AI version of the widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="contrail-service-instance-fqdn" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the Contrail unique ID for a service-instance")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="module-index" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the index will track the number of modules of a given type that have been deployed in a VNF, starting with 0, and always choosing the lowest available digit")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Path to the controller object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational. Valid values are in-service-path and out-of-service-path.",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vf-modules"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of vf-modules, a deployment unit of VNFCs")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:vf-module" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="bgp-group"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of bgp-group",indexedProps="bgp-group-id",dependentOn="pnf,vrf,generic-vnf",nameProps="bgp-group-id,bgp-group-name",container="bgp-groups",uriTemplate="/bgp-groups/bgp-group/{bgp-group-id}",requiredProps="bgp-group-id,bgp-group-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="bgp-group-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bgp-group-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="name of bgp-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bgp-group-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="type of bgp-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bgp-group-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="role of bgp-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bgp-group-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="function of bgp-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="local-as" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="local a-s number type of vrf (bridge-domain as an example)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="local-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="local address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="peer-as" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="peer a-s number")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="peer-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="peer address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="description of bgp-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:address-families" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="bgp-groups"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:bgp-group" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="generic-vnf"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="General purpose VNF",nameProps="vnf-name",indexedProps="is-closed-loop-disabled,vnf-name2,vnf-type,heat-stack-id,vnf-name,vnf-id,regional-resource-zone,prov-status,service-id,model-invariant-id,model-version-id,widget-model-id,widget-model-version,nf-type,nf-function,nf-naming-code,nf-role,nm-profile-name,orchestration-status",searchable="vnf-id,vnf-name,vnf-name2,operational-status",uniqueProps="vnf-id",container="generic-vnfs",namespace="network",extendsFrom="vnf",containsSuggestibleProps="true",suggestionAliases="VNFs",uriTemplate="/network/generic-vnfs/generic-vnf/{vnf-id}",requiredProps="vnf-id,vnf-type,in-maint,is-closed-loop-disabled")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vnf-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id of VNF. This is unique across the graph.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-instance-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="vnf instance id.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of VNF.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-name2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Alternate name of VNF.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="String capturing type of vnf, that was intended to identify the ASDC resource. This field has been overloaded in service-specific ways and clients should expect changes to occur in the future to this field as ECOMP matures.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Unique identifier of service, does not necessarily map to ASDC service models. SOON TO BE DEPRECATED")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="regional-resource-zone" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Regional way of organizing pservers, source of truth should define values")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Trigger for operational monitoring of this resource by Service Assurance systems.",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational. Valid values are in-service-path and out-of-service-path.",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="license-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="OBSOLETE - do not use")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equipment-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Client should send valid enumerated value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this VNF, used by MSO.",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-package-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-discriptor-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="vnf discriptor name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="job-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="job id corresponding to vnf")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="heat-stack-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Heat stack id corresponding to this instance, managed by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mso-catalog-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Corresponds to the SDN-C catalog id used to configure this VCE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="management-option" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="identifier of managed customer")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-oam-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Address tail-f uses to configure generic-vnf, also used for troubleshooting and is IP used for traps generated by generic-vnf.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-loopback0-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="v4 Loopback0 address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nm-lan-v6-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="v6 Loopback address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="management-v6-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="v6 management address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vcpu" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="number of vcpus ordered for this instance of VNF, used for VNFs with no vservers/flavors, to be used only by uCPE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vcpu-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="units associated with vcpu, used for VNFs with no vservers/flavors, to be used only by uCPE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vmemory" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="number of GB of memory ordered for this instance of VNF, used for VNFs with no vservers/flavors, to be used only by uCPE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vmemory-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="units associated with vmemory, used for VNFs with no vservers/flavors, to be used only by uCPE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vdisk" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="number of vdisks ordered for this instance of VNF, used for VNFs with no vservers/flavors, to be used only uCPE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vdisk-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="units associated with vdisk, used for VNFs with no vservers/flavors, to be used only by uCPE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nshd" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="number of associated SHD in vnf.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nvm" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="number of vms in vnf.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nnet" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="number of network in vnf.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this object is in maintenance mode (maintenance mode = true). This field (in conjunction with prov-status) is used to suppress alarms and vSCL on VNFs/VMs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-closed-loop-disabled" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether closed loop function is enabled on this node")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="summary-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="details regarding the generic-vnf operation, PLEASE DISCONTINUE USE OF THIS FIELD.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="encrypted-access-flag" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indicates whether generic-vnf access uses SSH")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="entitlement-assignment-group-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="UUID of the Entitlement group used for licensing VNFs, OBSOLETE - See child relationships.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="entitlement-resource-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="UUID of the specific entitlement resource. OBSOLETE - See child relationships.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="license-assignment-group-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="UUID of the license assignment group. OBSOLETE - See child relationships.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="license-key-uuid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="UUID of the actual license resource. OBSOLETE - See child relationships.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="persona-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="internal",dataCopy="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}#model-version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="captures the id of all the configuration used to customize the resource for the service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary widget model. This maps directly to the A&AI widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="widget-model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC data dictionary version of the widget model.This maps directly to the A&AI version of the widget.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="as-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="as-number of the VNF")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="regional-resource-subzone" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="represents sub zone of the rr plane")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nf-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Generic description of the type of NF",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nf-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="English description of Network function that the specific VNF deployment is providing")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nf-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="role in the network that this model will be providing",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nf-naming-code" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="string assigned to this model used for naming purposes")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Path to the controller object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-oam-gateway-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Gateway address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-oam-gateway-address-prefix-length" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prefix length for oam-address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id-outer" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Temporary location for S-TAG to get to VCE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nm-profile-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Network Management profile of this VNF")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="software-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="VNF instance specific software version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="application-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="vnf application-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:element ref="tns:licenses" minOccurs="0"/> + <xs:element ref="tns:bgp-groups" minOccurs="0"/> + <xs:element ref="tns:bgp-neighbors" minOccurs="0"/> + <xs:element ref="tns:entitlements" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="generic-vnfs"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of VNFs")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:generic-vnf" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="lag-link"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="LAG links can connect lag-interfaces",indexedProps="link-name",container="lag-links",namespace="network",uriTemplate="/network/lag-links/lag-link/{link-name}",requiredProps="link-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="link-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Alphabetical concatenation of lag-interface names")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="lag-links"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of link aggregation connections")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:lag-link" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="newvce"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="This object fills in the gaps from vce that were incorporated into generic-vnf. This object will be retired with vce.",nameProps="vnf-name",indexedProps="vnf-name,vnf-name2,vnf-type,heat-stack-id,prov-status,vnf-id2,orchestration-status",searchable="vnf-id2,vnf-name,vnf-name2",uniqueProps="vnf-id2",container="newvces",namespace="network",uriTemplate="/network/newvces/newvce/{vnf-id2}",requiredProps="vnf-id2,vnf-name,vnf-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vnf-id2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id of VNF, can't use same attribute name right now until we promote this new object")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of VNF.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-name2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Alternate name of VNF.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vnf-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="String capturing type of vnf, that was intended to identify the ASDC resource. This field has been overloaded in service-specific ways and clients should expect changes to occur in the future to this field as ECOMP matures.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Trigger for operational monitoring of this VNF by BAU Service Assurance systems.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="license-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="OBSOLETE - do not use")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-oam-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Address tail-f uses to configure generic-vnf, also used for troubleshooting and is IP used for traps generated by GenericVnf (v4-loopback0-ip-address).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equipment-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Client should send valid enumerated value.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-loopback0-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="v4 Loopback0 address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this VNF, mastered by MSO.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="heat-stack-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Heat stack id corresponding to this instance, managed by MSO")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mso-catalog-key" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Corresponds to the SDN-C catalog id used to configure this VCE")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="This object fills in the gaps from vce that were incorporated into generic-vnf. This object will be retired with vce.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:newvce" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="software-version"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Software Version",indexedProps="software-version-id,is-active-sw-ver",dependentOn="pnf",container="pnf",requiredProps="software-version-id,is-active-sw-ver",uriTemplate="/pnf/software-version/{software-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="software-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Identifier of the software version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-active-sw-ver" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="used to indicate whether or not this software-version is the active one (activeSw = true)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="software-versions"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of software versions.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:software-version" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vrf"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of vrf",indexedProps="vrf-id,vrf-role,vrf-function",nameProps="vrf-name",dependentOn="pnf",container="vrfs",uriTemplate="/vrfs/vrf/{vrf-id}",requiredProps="vrf-id,vrf-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vrf-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="VRF UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vrf-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="VRF Name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vrf-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="VRF Description")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="route-distinguisher" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Route Distinguisher")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vrf-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of vrf (bridge-domain as an example)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vrf-address-family" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IP address family (v6/v4/both)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vrf-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for the use of this physical link")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vrf-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by this Linterface")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vrf-group-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Bridge domain group name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:bgp-groups" minOccurs="0"/> + <xs:element ref="tns:bgp-neighbors" minOccurs="0"/> + <xs:element ref="tns:aggregate-routes" minOccurs="0"/> + <xs:element ref="tns:route-targets" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vrfs"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:vrf" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pnf"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="PNF represents a physical network function. typically equipment used in the D1 world. in 1607, this will be populated by SDN-C to represent a premises router that a uCPE connects to. But this can be used to represent any physical device that is not an AIC node or uCPE.",indexedProps="pnf-name,orchestration-status,inv-status,model-invariant-id,model-version-id,operational-status,nf-type,admin-status,nf-role,prov-status,nf-naming-code,equipment-clli",searchable="pnf-name",uniqueProps="pnf-name",container="pnfs",namespace="network",uriTemplate="/network/pnfs/pnf/{pnf-name}",requiredProps="pnf-name,in-maint")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="pnf-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="unique name of Physical Network Function.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pnf-name2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="name of Physical Network Function.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pnf-name2-source" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="source of name2")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pnf-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="id of pnf")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nf-naming-code" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Naming code for network function")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-operating-system" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Network operating system used on the device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nf-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by the pnf.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Equipment type. Source of truth should define valid values.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-vendor" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Equipment vendor. Source of truth should define valid values.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-model" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Equipment model. Source of truth should define valid values.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="management-option" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="identifier of managed customer")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this pnf")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v4-oam" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ipv4-oam-address with new naming convention for IP addresses")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sw-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="sw-version is the version of SW for the hosted application on the PNF.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Used to indicate whether or not this object is in maintenance mode (maintenance mode = true). This field (in conjunction with prov-status) is used to suppress alarms and vSCL on VNFs/VMs.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="frame-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ID of the physical frame (relay rack) where pnf is installed.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="serial-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Serial number of the device")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v4-loopback-0" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV4 Loopback 0 address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v6-loopback-0" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV6 Loopback 0 address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v4-aim" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV4 AIM address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v6-aim" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV6 AIM address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v6-oam" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="IPV6 OAM address")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="inv-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CANOPI's inventory status. Only set with values exactly as defined by CANOPI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prov Status of this device (not under canopi control) Valid values [PREPROV/NVTPROV/PROV]")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nf-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Nf Role is the role performed by this instance in the network.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="admin-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="admin Status of this PNF")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The ASDC model id for this resource model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The ASDC model version for this resource model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ops-note" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Notes to aid OPs in troubleshooting, such as attribute aliases or additional descriptions/instructions about an object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="config-validation-request-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Contains the value of the request id to the most recent configuration file/validation report for this PNF.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="config-validation-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Status of latest configuration attempt represented by the config-url.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nf-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Subtype used to categorize this pnf")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="common-base-indicator" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicates the PNF/R-Leaf was built with the VNF agnostic common base")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equipment-clli" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="11-character equipment CLLI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pnf-ipv4-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This is the IP address (IPv4) for the PNF itself. This is the IPv4 address that the PNF iself can be accessed at.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pnf-ipv6-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="This is the IP address (IPv6) for the PNF itself. This is the IPv6 address that the PNF iself can be accessed at.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:software-versions" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:p-interfaces" minOccurs="0"/> + <xs:element ref="tns:l-interfaces" minOccurs="0"/> + <xs:element ref="tns:lag-interfaces" minOccurs="0"/> + <xs:element ref="tns:activities" minOccurs="0"/> + <xs:element ref="tns:vrfs" minOccurs="0"/> + <xs:element ref="tns:bgp-groups" minOccurs="0"/> + <xs:element ref="tns:bgp-neighbors" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pnfs"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of Physical Network Functions.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:pnf" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="port"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of port",indexedProps="port-name",dependentOn="chassis,pluggable,card",container="ports",uriTemplate="/ports/port/{port-name}",requiredProps="port-name,port-type,port-role,speed-value,speed-units")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="port-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="A unique name for the port relative to the containing hardware.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of port.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The role of the port.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The numeric value for the speed of the port.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The units for the speed of the port.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="xcvr-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of transceiver that creates this port.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-identifier" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="clei-code or other similar identifier")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="part-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="part number")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-start" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Port range start")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-end" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Port range end")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="ports"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:port" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pluggable"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of pluggable",indexedProps="pluggable-type,part-number,equip-identifier",dependentOn="pluggable-slot",container="pluggables",uriTemplate="/pluggables/pluggable/{pluggable-type}",requiredProps="pluggable-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="pluggable-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="The type of pluggable.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="part-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Part number for this pluggable.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-identifier" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CLEI or other specification for pluggable hardware.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:ports" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pluggables"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:pluggable" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pluggable-slot"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of card-slot",indexedProps="slot-name",dependentOn="chassis,card",container="pluggable-slots",uriTemplate="/pluggable-slots/pluggable-slot/{slot-name}",requiredProps="slot-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="slot-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="The name of the pluggable-slot. (unique relative to the chassis or card).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:pluggables" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="pluggable-slots"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:pluggable-slot" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="card"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of card",indexedProps="card-type",dependentOn="card-slot",container="cards",uriTemplate="/cards/card/{card-type}",requiredProps="card-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="card-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="The type of card.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:ports" minOccurs="0"/> + <xs:element ref="tns:pluggable-slots" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="cards"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:card" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="card-slot"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of card-slot",indexedProps="slot-name",dependentOn="chassis",container="card-slots",uriTemplate="/card-slots/card-slot/{slot-name}",requiredProps="slot-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="slot-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="The name of the card-slot (unique relative to the chassis).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:cards" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="card-slots"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:card-slot" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="chassis"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of chassis",uniqueProps="chassis-name",indexedProps="chassis-name,part-number,orchestration-status,equip-model,equip-vendor,equip-identifier",container="chassies",namespace="network",uriTemplate="/network/chassies/chassis/{chassis-name}",requiredProps="chassis-name,chassis-type,chassis-role")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="chassis-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="A globally unique name for the chassis.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="chassis-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of chassis..")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="chassis-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The role of the chassis relative to the pnf/pserver..")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operating-system" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Operating system of the hardware.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="serial-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The serial number of the chassis..")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="asset-tag" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The asset tag of the chassis.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="chassis-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Description of the chassis.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="part-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Part number for this chassis.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of this chassis.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-model" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Equipment model.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-vendor" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Equipment vendor. Source of truth should define valid values.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="equip-identifier" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CLEI or other specification for chassis hardware.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="slot-number" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Slot number associated with this chassis.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="admin-state" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Reflects the admin-state of the device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:ports" minOccurs="0"/> + <xs:element ref="tns:card-slots" minOccurs="0"/> + <xs:element ref="tns:pluggable-slots" minOccurs="0"/> + <xs:element ref="tns:licenses" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="chassies"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:chassis" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="physical-link"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of physical connections, typically between p-interfaces",indexedProps="circuit-id,link-name,link-function,link-role,link-type",alternateKeys1="circuit-id",container="physical-links",namespace="network",searchable="link-name,circuit-id,operational-status",uriTemplate="/network/physical-links/physical-link/{link-name}",requiredProps="link-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="link-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="e.g., hostnameA_p-connection_nameA_hostnameZ+p_connection-nameZ")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the numeric part of the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="speed-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the units corresponding to the speed")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="circuit-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Circuit it")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dual-mode" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Dual access mode (e.g., primary, secondary")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="management-option" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="To provide information on who manages this circuit. A&AI or 3rd party transport provider")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-provider-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the service Provider on this link.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-provider-bandwidth-up-value" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Upstream Bandwidth value agreed with the service provider")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-provider-bandwidth-up-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Units for the upstream BW value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-provider-bandwidth-down-value" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Downstream Bandwidth value agreed with the service provider")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-provider-bandwidth-down-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Units for downstream BW value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The function performed by this physical link")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for the use of this physical link")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Subtype used to categorize this physical link")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational. Valid values are in-service-path and out-of-service-path.",suggestibleOnSearch="true")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="physical-links"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of physical connections, typically between p-interfaces")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:physical-link" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vig-server"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="vig-server contains information about a vig server used for IPSec-configuration. Populated by SDN-C from 1607",indexedProps="vig-address-type",dependentOn="ipsec-configuration",container="vig-servers",uriTemplate="/vig-servers/vig-server/{vig-address-type}",requiredProps="vig-address-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vig-address-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="indicates whether the VIG is for AVPN or INTERNET")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v4-vig" type="xs:string" minOccurs="0" maxOccurs="5000"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="v4 IP of the vig server")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipaddress-v6-vig" type="xs:string" minOccurs="0" maxOccurs="5000"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="v6 IP of the vig server")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="ipsec-configuration"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="IPSec configuration node will contain various configuration data for the NMTE VNF. This node will have an edge to the generic-vnf (vnf type = TE). Starting 1607, this data will be populated by SDN-C",indexedProps="ipsec-configuration-id",uniqueProps="ipsec-configuration-id",container="ipsec-configurations",namespace="network",uriTemplate="/network/ipsec-configurations/ipsec-configuration/{ipsec-configuration-id}",requiredProps="ipsec-configuration-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="ipsec-configuration-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID of this configuration")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="requested-vig-address-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicate the type of VIG server like AVPN, INTERNET, BOTH")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="requested-encryption-strength" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Encryption values like 3des-cbc, des-cbc, aes-128-cbc, aes-192-cbc, aes-265-cbc")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="requested-dmz-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Shared DMZ or a DMZ specific to a customer")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="shared-dmz-network-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Network address of shared DMZ")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="requested-customer-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="If the DMZ is a custom DMZ, this field will indicate the customer information")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ike-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="can be 1 or 2")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ikev1-authentication" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Contains values like md5, sha1, sha256, sha384")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ikev1-encryption" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Encyption values like 3des-cbc, des-cbc, aes-128-cbc, aes-192-cbc, aes-265-cbc")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ikev1-dh-group" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Diffie-Hellman group like DH-GROUP2, DH-GROUP5, DH-GROUP14")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ikev1-am-group-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Group name defined in VIG for clients using aggressive mode")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ikev1-am-password" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="pre-shared key for the above group name ")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ikev1-sa-lifetime" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Lifetime for IKEv1 SA")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipsec-authentication" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="md5, sha1, sha256, sha384")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipsec-encryption" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="3des-cbc, des-cbc, aes-128-cbc, aes-192-cbc, aes-265-cbc")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipsec-sa-lifetime" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Life time for IPSec SA")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipsec-pfs" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="enable PFS or not")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="xauth-userid" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="user ID for xAuth, sm-user,ucpeHostName,nmteHostName")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="xauth-user-password" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Encrypted using the Juniper $9$ algorithm")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dpd-interval" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The time between DPD probe")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dpd-frequency" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Maximum number of DPD before claiming the tunnel is down")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <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="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="route-table-reference"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Openstack route table reference.",nameProps="route-table-reference-fqdn",uniqueProps="route-table-reference-id",indexedProps="route-table-reference-id,route-table-reference-fqdn",container="route-table-references",namespace="network",uriTemplate="/network/route-table-references/route-table-reference/{route-table-reference-id}",requiredProps="route-table-reference-id,route-table-reference-fqdn")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="route-table-reference-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Route Table Reference id, UUID assigned to this instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="route-table-reference-fqdn" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="FQDN entry in the route table.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="route-table-references"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of openstack route table references")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:route-table-reference" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="instance-group"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="General mechanism for grouping instances",nameProps="description,instance-group-name",uniqueProps="id",searchable="id,description",indexedProps="id,model-invariant-id,model-version-id",container="instance-groups",namespace="network",uriTemplate="/network/instance-groups/instance-group/{id}",requiredProps="id,instance-group-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Instance Group ID, UUID assigned to this instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="instance-group-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="role of the instance group.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ASDC model version uid for this resource model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Descriptive text to help identify the usage of this instance-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="instance-group-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Only valid value today is lower case ha for high availability")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="instance-group-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Instance-Group Name.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="instance-group-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Instance-Group Function")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="instance-group-number" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Number used to identify an instance-group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="priority-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to identify the primary and secondary priority")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="instance-groups"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of openstack route table references")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:instance-group" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="zone"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="A zone is a grouping of assets in a location homing to the same connections into the CBB",nameProps="zone-name",indexedProps="zone-id,design-type,zone-context",uniqueProps="zone-id",container="zones",namespace="network",uriTemplate="/network/zones/zone/{zone-id}",requiredProps="zone-id,zone-name,design-type,zone-context,in-maint")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="zone-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Code assigned by AIC to the zone")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="zone-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="English name associated with the zone")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="zone-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of zone (ex. AIC or NC).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="design-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Design of zone [Medium/Large…]")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="zone-context" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Context of zone [production/test]")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Status of a zone.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="zone-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role of a zone.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="zone-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Function of a zone.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="in-maint" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Used to indicate whether or not zone object is in maintenance mode.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:subnets" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="zones"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of zones")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:zone" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="autonomous-system"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Description of Autonomous System",nameProps="autonomous-system-id,autonomous-system-number",indexedProps="autonomous-system-id,autonomous-system-number,autonomous-system-type",uniqueProps="autonomous-system-id",container="autonomous-systems",namespace="network",uriTemplate="/network/autonomous-systems/autonomous-system/{autonomous-system-id}",requiredProps="autonomous-system-id,autonomous-system-number,autonomous-system-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="autonomous-system-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="autonomous-system-number" type="xs:unsignedInt" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="asn in the range of 0 to 9223372036854775807")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="autonomous-system-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="type (global vs. local).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="autonomous-system-region" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="geographic region")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="autonomous-system-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="role of autonomous system")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="autonomous-systems"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of Autonomous Systems")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:autonomous-system" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-range"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Description of Network Range",nameProps="network-range-name,network-range-type",indexedProps="network-range-id,network-range-name",container="network-ranges",namespace="network",uriTemplate="/network/network-ranges/network-range/{network-range-id}",requiredProps="network-range-id,network-range-name,network-range-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="network-range-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-range-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-range-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="type (ex, esi, vni, vni-rt, lacp-id).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-range-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="role of network-range")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-range-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="descriptive function")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="start-range" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="starting range for simple network ranges.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="end-range" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="end range for simple network ranges.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="last-assigned" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="last assigned value for simple network ranges")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="range-format" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Format Decimal, Hexadecimal, etc.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="range-prefix" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Prefix of network range.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Concurrency value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:activities" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-ranges"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of Network Ranges")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:network-range" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="mapping"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="General mechanism for mapping between instances; cg-nat.",indexedProps="mapping-id",uniqueProps="mapping-id",container="mappings",namespace="network",uriTemplate="/network/mappings/mapping/{mapping-id}",requiredProps="mapping-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="mapping-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Key for mapping object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mapping-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of mapping")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mapping-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of mapping.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mapping-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role of mapping")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mapping-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Function of mapping")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mapping-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Number of mapping")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="location-1" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Location 1")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="location-2" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Location 2")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="mapping-group-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Non-unique ID for grouping mappings")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prov-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Provision status for the mapping object. Valid values can be found at (https://wiki.web.att.com/display/SPTIIRP/prov-status).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="homed-location" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Location the object is homed to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="planned-location" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Location the object is planned for")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="mappings"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of mappings.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:mapping" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="hw-component"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="create/update/delete the hw-component node",indexedProps="hw-component-id",uriTemplate="/network/hw-components/hw-component/{hw-component-id}",requiredProps="hw-component-id",namespace="network",container="hw-components")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="hw-component-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="hw-component-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of hardware component")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="hw-component-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of hardware component")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="hw-component-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role of hardware component")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="hw-component-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Function of hardware component")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="hw-components"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:hw-component" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sw-component"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="create/update/delete the sw-component node",indexedProps="sw-component-id",uriTemplate="/network/sw-components/sw-component/{sw-component-id}",requiredProps="sw-component-id",namespace="network",container="sw-components")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="sw-component-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sw-component-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of software component")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sw-component-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of software component")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sw-component-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Role of software component")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sw-component-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Function of software component")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sw-components"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:sw-component" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-route"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="This object represents a network route. For instance, host-route, static-route.",indexedProps="route-id,type,role,function,ip-address,prefix-length,next-hop",uriTemplate="/network/network-routes/network-route/{route-id}",requiredProps="route-id,type,role,function,ip-address,prefix-length,address-family",namespace="network",container="network-routes")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="route-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="unique identifier example uuid.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="used to categorize this object in conjunction with role & function. The most generic category.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="used to categorize this object in conjunction with type & function.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="used to categorize this object in conjunction with type & role. The most specific category.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ip-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ip address that of the specific network-route.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="prefix-length" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ip-address prefix length.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="logical-interface-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Identity of a logical interface, e.g., VLAN ID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="next-hop" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Could be ip-address, hostname, or service-instance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="next-hop-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Should be ip-address, hostname, or service-instance to match next-hop.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="metric" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Value that is assigned to an IP route for a particular network interface that identifies the cost that is associated with using that route.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="address-family" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="whether the route address is ipv4, ipv6.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-routes"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:network-route" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlan-mapping"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="vlan-mapping object is an optional child object of the forwarder-evc object. A given forwarder-evc object may have multiple vlan-mapping objects.",dependentOn="forwarder-evc",uniqueProps="vlan-mapping-id",container="vlan-mappings",uriTemplate="/vlan-mappings/vlan-mapping/{vlan-mapping-id}",requiredProps="vlan-mapping-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vlan-mapping-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Key for vlan-mapping object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="uni-cvlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CVLAN value from the UNI/ingress side of the SAREA gateway access device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nni-svlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="SVLAN value from the NNI/egress side of the SAREA gateway access device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nni-cvlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CVLAN value from the NNI/egress side of the SAREA gateway access device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ivlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The internal VLAN ('IVLAN') value. Specific to Arista devices.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlan-mappings"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of vlan mappings.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:vlan-mapping" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="forwarder-evc"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="forwarder object is an optional child object of the Configuration object.",dependentOn="configuration",uniqueProps="forwarder-evc-id",container="forwarder-evcs",uriTemplate="/forwarder-evcs/forwarder-evc/{forwarder-evc-id}",requiredProps="forwarder-evc-id",indexedProps="circuit-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="forwarder-evc-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Key for forwarder-evc object")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="circuit-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Circuit ID from customer/ESP/ingress end of EVC, or reference to beater circuit on gateway/network/egress end of EVC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ivlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Internal VLAN.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="svlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="SVLAN value for ingress of egress forwarder.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cvlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CVLAN value for ingress of egress forwarder.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:vlan-mappings" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="forwarder-evcs"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:forwarder-evc" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="evc"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="evc object is an optional child object of the Configuration object.",dependentOn="configuration",uniqueProps="evc-id",container="evcs",uriTemplate="/evcs/evc/{evc-id}",requiredProps="evc-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="evc-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique/key field for the evc object")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="forwarding-path-topology" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Point-to-Point, Multi-Point")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cir-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Commited Information Rate")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cir-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CIR units")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="connection-diversity-group-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Diversity Group ID")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-hours" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="formerly Performance Group")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="esp-evc-circuit-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="EVC Circuit ID of ESP EVC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="esp-evc-cir-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Committed Information Rate (For ESP)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="esp-evc-cir-units" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="CIR units (For ESP)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="esp-itu-code" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Identifies ESP")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="collector-pop-clli" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Collector POP CLLI (from the hostname of the access pnf)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="inter-connect-type-ingress" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Interconnect type on ingress side of EVC.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="tagmode-access-ingress" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="tagode for collector side of EVC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="tagmode-access-egress" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="tagMode for network side of EVC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="product-entry-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Product ID")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="evcs"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:evc" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="configuration"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Generic configuration object.",indexedProps="configuration-id,configuration-name,configuration-type,model-invariant-id,model-version-id,orchestration-status,configuration-role,configuration-function,orchestration-version",uniqueProps="configuration-id",container="configurations",namespace="network",uriTemplate="/network/configurations/configuration/{configuration-id}",requiredProps="configuration-id,configuration-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="configuration-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID assigned to configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="management-option" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicates the entity that will manage this feature. Could be an organization or the name of the application as well.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="configuration-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="configuration-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="port-mirroring-configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="configuration-sub-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="vprobe, pprobe.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Orchestration status of the configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicator for whether the resource is considered operational.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="configuration-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details from SDN-GC.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="id of the configuration used to customize the resource")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="tunnel-bandwidth" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="DHV Site Effective Bandwidth")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vendor-allowed-max-bandwidth" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Velocloud Nominal Throughput - VNT")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="config-policy-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to capture the name of the fabric configuration policy that was used to generate the payload sent to PINC for fabric configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="configuration-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize the configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="configuration-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize the configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="primary-role" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used by some configurations to identify if it's filling a primary role.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize the configuration.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:metadata" minOccurs="0"/> + <xs:element ref="tns:forwarder-evcs" minOccurs="0"/> + <xs:element ref="tns:evcs" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="configurations"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of configurations")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:configuration" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="forwarder"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(indexedProps="sequence",description="Entity describing a sequenced segment of forwarding path",container="forwarders",dependentOn="forwarding-path",uriTemplate="/forwarders/forwarder/{sequence}",requiredProps="sequence")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="sequence" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of this segmentation")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="forwarder-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ingress, intermediate, egress")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="forwarders"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:forwarder" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="forwarding-path"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(namespace="network",indexedProps="forwarding-path-id,forwarding-path-name",description="Entity that describes the sequenced forwarding path between interfaces of services or resources",container="forwarding-paths",nameProps="forwarding-path-name",uniqueProps="forwarding-path-id",uriTemplate="/network/forwarding-paths/forwarding-path/{forwarding-path-id}",requiredProps="forwarding-path-id,forwarding-path-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="forwarding-path-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of this FP")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="forwarding-path-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the FP")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the self link for this FP")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:forwarders" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="forwarding-paths"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:forwarding-path" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="collection"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(namespace="network",description="represents the collection resource in the TOSCA model",uniqueProps="collection-id",indexedProps="collection-id,model-invariant-id,model-version-id,orchestration-status",container="collections",uriTemplate="/network/collections/collection/{collection-id}",requiredProps="collection-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="collection-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Collection Object UUID")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ASDC model id for this resource or service model",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Model Version",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="collection-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="collection name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="collection-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Collection type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="collection-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Collection Role")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="collection-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Collection function")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="orchestration-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="orchestration status")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="collection-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Captures the id of all the configuration used to customize the resource for the service")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="collections"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:collection" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="next-hop"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Is among the series of routers that are connected together in a network and is the next possible destination for a data packet.",indexedProps="next-hop-id",namespace="network",container="next-hops",uriTemplate="/network/next-hops/next-hop/{next-hop-id}",uniqueProps="next-hop-id",requiredProps="next-hop-id,next-hop-type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="next-hop-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="next-hop-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize this object in conjunction with role & function. The most generic category.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="next-hop-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize this object in conjunction with type & function.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="next-hop-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize this object in conjunction with type & role. The most specific category.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sequence" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Sequence number.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="address-family" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Ipv4 or Ipv6.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ip-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Next hop ip-address.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="metric" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Cost that is associated with using the route.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="next-hops"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:next-hop" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="bfd"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="BFD (Bidirectional Forwarding Detection) is a protocol for detecting link failures.The BFD object is for persisting attributes for the links that have BFD enabled.",indexedProps="bfd-id",namespace="network",container="bfds",uriTemplate="/network/bfds/bfd/{bfd-id}",uniqueProps="bfd-id",requiredProps="bfd-id,bfd-type",nameProps="bfd-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="bfd-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bfd-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize this object in conjunction with role & function. The most generic category.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bfd-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize this object in conjunction with type & function.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bfd-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize this object in conjunction with type & role. The most specific category.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bfd-keep-alive" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="bfd keep-alive parameter")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bfd-timeout" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="bfd timeout parameter")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="bfds"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:bfd" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="fqdn"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="A fully qualified domain name (FQDN) is the complete domain name for a specific computer, or host, on the internet.",requiredProps="fqdn,dns-domain",indexedProps="fqdn",namespace="network",container="fqdns",uriTemplate="/network/fqdns/fqdn/{fqdn}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="fqdn" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Fully qualified domain name.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="fqdn-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize this object in conjunction with role & function. The most generic category.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="fqdn-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize this object in conjunction with type & function.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="fqdn-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used to categorize this object in conjunction with type & role. The most specific category.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dns-domain" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Domain name.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="fqdns"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:fqdn" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="connectivity"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a connectivity",indexedProps="connectivity-id,etht-svc-name,bandwidth-profile-name,vpn-type,color-aware,coupling-flag,access-provider-id,access-client-id,access-topology-id,access-node-id,access-ltp-id,operational-status,model-invariant-id,model-version-id",nameProps="etht-svc-name",searchable="connectivity-id",uniqueProps="connectivity-id",container="connectivities",namespace="network",requiredProps="connectivity-id",uriTemplate="/network/connectivities/connectivity/{connectivity-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="connectivity-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this connectivity by id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="bandwidth-profile-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the name of a bandwidth profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpn-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the type of a bandwidth profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cir" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the CIR of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="eir" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the EIR of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cbs" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the CBS of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ebs" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the EBS of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="color-aware" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the color-awareness of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="coupling-flag" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the coupling flag of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="etht-svc-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The ethernet service name for this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-provider-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access provider of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-client-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access client of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-topology-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access topology of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-node-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access node of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-ltp-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the access ltp of this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="connectivity-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cvlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the cvlan for this connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="connectivities"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of connectivities")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:connectivity" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="dhcp-service"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a dhcp-service",indexedProps="dhcp-service-id,dhcp-service-type,domain-name,server-ipv4-address,server-ipv6-address",nameProps="domain-name",searchable="dhcp-service-id",uniqueProps="dhcp-service-id",container="dhcp-services",dependentOn="lan-port-config",namespace="network",requiredProps="dhcp-service-id",uriTemplate="/network/dhcp-services/dhcp-service/{dhcp-service-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="dhcp-service-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this dhcp-service by id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="server-ipv4-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the server-ip4-address of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="server-ipv6-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the server-ipv6-address of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="service-enable" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the service-enable of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dhcp-service-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the dhcp-service-type of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="lease-time" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the lease-time of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="domain-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the domain-name of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dns" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the dns of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ntp-primary" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the ntp-primary of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ntp-secondary" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the ntp-secondary of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="nbns" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the nbns of this dhcp-service.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="dhcp-services"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of dhcp-services")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:dhcp-service" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="lan-port-config"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a lan-port-config",indexedProps="lan-port-config-id,lan-port-config-name,device-id,port-id,ipv4-address,ipv6-address,vlan-tag",nameProps="lan-port-config-name",searchable="lan-port-config-id",uniqueProps="lan-port-config-id",container="lan-port-configs",namespace="network",requiredProps="lan-port-config-id",uriTemplate="/network/lan-port-configs/lan-port-config/{lan-port-config-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="lan-port-config-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this lan-port-config by id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="lan-port-config-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the name of this lan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the description of this lan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="device-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the device-id of this lan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the port-id of this lan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the ipv4-address of this lan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv6-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the ipv6-address of this lan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-tag" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the vlan-tag of this lan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="input-bandwidth" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the input-bandwidth of this lan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="output-bandwidth" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the output-bandwidth of this lan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:dhcp-services" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="lan-port-configs"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of lan-port-configs")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:lan-port-config" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-resource"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a network-resource",indexedProps="network-id,provider-id,client-id,te-topo-id",nameProps="network-id",searchable="network-id",uniqueProps="network-id",container="network-resources",namespace="network",requiredProps="network-id",uriTemplate="/network/network-resources/network-resource/{network-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="network-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this network-resource by id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="provider-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the provider of this network-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="client-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the client of this network-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="te-topo-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the te-topo of this network-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="network-resource-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of a network topology, e.g., Ethernet, OTN, WSON.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network-resources"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of network-resources")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:network-resource" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="site-resource"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a site-resource",indexedProps="site-resource-id,site-resource-name,type,role,generated-site-id,operational-status,model-invariant-id,model-version-id",nameProps="site-resource-name",searchable="site-resource-id",uniqueProps="site-resource-id",container="site-resources",namespace="network",requiredProps="site-resource-id",uriTemplate="/network/site-resources/site-resource/{site-resource-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="site-resource-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this site-resource by id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="site-resource-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the name of this site-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the description of this site-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the type of this site-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the role of this site-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="generated-site-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the generated-site-id of this site-resource.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="site-resources"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of site-resources")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:site-resource" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sdwan-vpn"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of an sdwan-vpn",indexedProps="sdwan-vpn-id,sdwan-vpn-name,vxlan-id,topology,operational-status,model-invariant-id,model-version-id",nameProps="sdwan-vpn-name",searchable="sdwan-vpn-id",uniqueProps="sdwan-vpn-id",container="sdwan-vpns",namespace="network",requiredProps="sdwan-vpn-id",uriTemplate="/network/sdwan-vpns/sdwan-vpn/{sdwan-vpn-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="sdwan-vpn-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this sdwan-vpn by id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sdwan-vpn-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the name of this sdwan-vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vxlan-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the vxlan-id of this sdwan-vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="topology" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the topology of this sdwan-vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="tenant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the tenant-id of this sdwan-vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vpn-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the vpn-id of this sdwan-vpn.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="sdwan-vpns"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of sdwan-vpns")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:sdwan-vpn" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="device"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a device",indexedProps="device-id,device-name,esn,vendor,class,type,version,system-ip,system-ipv4,system-ipv6,operational-status,model-invariant-id,model-version-id",nameProps="device-name",searchable="device-id",uniqueProps="device-id",container="devices",namespace="network",requiredProps="device-id",uriTemplate="/network/devices/device/{device-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="device-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this device by id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="esn" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the esn of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="device-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the name of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the description of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vendor" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the vendor of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="class" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the class of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the type of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the version of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="system-ip" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the system-ip of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="system-ipv4" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the system-ipv4 of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="system-ipv6" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the system-ipv6 of this device.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="devices"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of devices")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:device" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="wan-port-config"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of a wan-port-config",indexedProps="wan-port-config-id,wan-port-config-name,device-id,ip-address,ipv4-address,ipv6-address,port-type,port-number,device-port-id,wan-port-id,operational-status,model-invariant-id,model-version-id",nameProps="wan-port-config-name",searchable="wan-port-config-id",uniqueProps="wan-port-config-id",container="wan-port-configs",namespace="network",requiredProps="wan-port-config-id",uriTemplate="/network/wan-port-configs/wan-port-config/{wan-port-config-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="wan-port-config-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Uniquely identifies this wan-port-config by id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="wan-port-config-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the name of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="device-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the device of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vlan-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the id of the vlan of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ip-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the ip-address of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv4-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the ipv4-address of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="ipv6-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the ipv6-address of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="provider-ip-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the provider-ip-address of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="provider-ipv4-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the provider-ipv4-address of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="provider-ipv6-address" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the provider-ipv6-address of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="input-bandwidth" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the input-bandwidth of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="output-bandwidth" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the output-bandwidth of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the description of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the port-type of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="port-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the port-number of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="transport-network-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the transport-network-name of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="device-port-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the device-port-id of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="wan-port-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the wan-port-id of this wan-port-config.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="wan-port-configs"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of wan-port-configs")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:wan-port-config" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="ext-aai-network"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Refer to an external AAI in another ONAP.",indexedProps="aai-id",searchable="aai-id",container="ext-aai-networks",namespace="network",requiredProps="aai-id",uriTemplate="/network/ext-aai-networks/ext-aai-network/{aai-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="aai-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique ID of the referenced AAI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="schema-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Schema version of the referenced AAI.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:esr-system-info" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="ext-aai-networks"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:ext-aai-network" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="network"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Namespace for network inventory resources.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <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: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:chassies" 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:element ref="tns:instance-groups" minOccurs="0"/> + <xs:element ref="tns:zones" minOccurs="0"/> + <xs:element ref="tns:autonomous-systems" minOccurs="0"/> + <xs:element ref="tns:network-ranges" minOccurs="0"/> + <xs:element ref="tns:mappings" minOccurs="0"/> + <xs:element ref="tns:hw-components" minOccurs="0"/> + <xs:element ref="tns:sw-components" minOccurs="0"/> + <xs:element ref="tns:network-routes" minOccurs="0"/> + <xs:element ref="tns:configurations" minOccurs="0"/> + <xs:element ref="tns:forwarding-paths" minOccurs="0"/> + <xs:element ref="tns:collections" minOccurs="0"/> + <xs:element ref="tns:next-hops" minOccurs="0"/> + <xs:element ref="tns:bfds" minOccurs="0"/> + <xs:element ref="tns:fqdns" minOccurs="0"/> + <xs:element ref="tns:connectivities" minOccurs="0"/> + <xs:element ref="tns:lan-port-configs" minOccurs="0"/> + <xs:element ref="tns:network-resources" minOccurs="0"/> + <xs:element ref="tns:site-resources" minOccurs="0"/> + <xs:element ref="tns:sdwan-vpns" minOccurs="0"/> + <xs:element ref="tns:devices" minOccurs="0"/> + <xs:element ref="tns:wan-port-configs" minOccurs="0"/> + <xs:element ref="tns:ext-aai-networks" minOccurs="0"/> + <xs:element ref="tns:label-restrictions" minOccurs="0"/> + <xs:element ref="tns:unis" minOccurs="0"/> + <xs:element ref="tns:te-link-attributes" minOccurs="0"/> + <xs:element ref="tns:interlayer-attachments" minOccurs="0"/> + <xs:element ref="tns:tunnel-termination-points" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="reserved-prop-names"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Internal map to define some reserved properties of a vertex",uniqueProps="aai-unique-key,aai-uri",indexedProps="aai-unique-key,source-of-truth,aai-node-type,aai-uri")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <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:element name="aai-uri" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="edge-prop-names"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Internal map to define the properties of an edge and interpret the map EdgeRules",edgeInfo="aaiUuid,edgeLabel,direction,multiplicityRule,isParent,usesResource,hasDelTarget,SVC-INFRA,SVC-INFRA-REV",uniqueProps="aai-uuid",indexedProps="aai-uuid")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <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="contains-other-v" type="xs:string" minOccurs="0"/> + <xs:element name="delete-other-v" type="xs:string" minOccurs="0"/> + <xs:element name="SVC-INFRA" type="xs:string" minOccurs="0"/> + <xs:element name="prevent-delete" type="xs:string" minOccurs="0"/> + <xs:element name="aai-uuid" 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="5000"/> + <xs:element ref="tns:edge-prop-names" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="hardware-catalog-item"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an hardware-catalog-items",indexedProps="item-name",uniqueProps="item-name",container="hardware-catalog-items",namespace="common",uriTemplate="/common/hardware-catalog-items/hardware-catalog-item/{item-name}",requiredProps="item-name,system-type,manufacturer,model,sku")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="item-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique name for the hardware-catalog-item")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="system-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of system defined by ATT")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="manufacturer" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Manufacturer of the hardware-catalog-item (ex,Cisco)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Model of the hardware-catalog-item (ex,5501 NCS)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="part-number" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Part number assigned by the manufacturer")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Description of the hardware-catalog-item")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sku" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Stock-keeping-unit (ATT specific identifier for the hardware-catalog-item)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="hardware-catalog-items"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of hardware-catalog-items")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:hardware-catalog-item" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="contact"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Contacts store the vendor information and have a relationship to the generic-vnf. In 1902, this will be populated by SDN-GC",uniqueProps="contact-name",container="contacts",namespace="common",nameProps="contact-name,vendor-type",uriTemplate="/common/contacts/contact/{contact-name}",requiredProps="contact-name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="contact-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name of the contact")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="contact-telephone" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Tel no. of contact")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="contact-email" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="e-mail of contact")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="vendor-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="NI (Network Integrator)SI (System Integrator) 3rd Party LCM")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="contacts"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of contacts")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:contact" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="profile"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an profiles",indexedProps="profile-name,profile-role,profile-function",uniqueProps="profile-name",nameProps="profile-type",container="profiles",namespace="common",uriTemplate="/common/profiles/profile/{profile-name}",requiredProps="profile-name,profile-type,characteristics")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="profile-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Name of the profile")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="profile-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of profile (ex,network-power-profile)")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="profile-characteristics" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Set of characteristics of the profile.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="profile-subtype" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Descriptive subtype.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="profile-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="used to categorize this object in conjunction with profile-type and profile-function.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="profile-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="used to categorize this object in conjunction with profile-type and profile-role. The most specific category")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="profile-selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="URL to endpoint where AAI can get more details")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + <xs:element ref="tns:metadata" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="profiles"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of profiles")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:profile" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="port-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Port List Range",dependentOn="endpoint,rule,object-group",uriTemplate="/port-list/{port}",requiredProps="port")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="port" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Port number")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="assignment" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name or assignment for the port")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type or usage of the port")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operator" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Operator to apply to the port (greater than, less than, etc).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="selector-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Selectors list",dependentOn="rule,object-group,endpoint,policy",uriTemplate="/selector-list/{selector}",requiredProps="selector")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="selector" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Selector")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="assignment" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name or assignment for the selector")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type or usage of the selector")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="rule"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an rules",container="rules",dependentOn="policy",uriTemplate="/rules/rule/{rule-id}",requiredProps="rule-id,log")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="rule-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="direction" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="ingress or egress")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="protocol" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Positive protocol match. tcp, udp, icmpv6, sctp, udplite, integer 1-255.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="not-protocol" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Negative protocol match. tcp, udp, icmpv6, sctp, udplite, integer 1-255.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="action" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Action to perform when matching this rule.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="icmp" type="xs:string" minOccurs="0" maxOccurs="5000"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="not-icmp" type="xs:string" minOccurs="0" maxOccurs="5000"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="sequence" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Sequence number of the rule.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="threshold" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Threshold")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="status")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="count-variable" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Named variable used for counting transactions.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="log" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Boolean to indicate whether or not logging is required.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Description.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:port-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:selector-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="rules"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of rules")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:rule" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="policy"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Definition of policy",indexedProps="policy-id",uniqueProps="policy-id",container="policies",namespace="common",uriTemplate="/common/policies/policy/{policy-id}",requiredProps="policy-id,do-not-track,pre-dnat,apply-on-forward")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="policy-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique Policy UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="policy-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Policy Name")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="policy-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Policy Type")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="policy-role" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Policy role")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="policy-function" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="policy function")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="do-not-track" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Do not track")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="pre-dnat" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Pre destination NAT")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="apply-on-forward" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="apply on forward")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selector" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Host and Interface Type Selector",dbAlias="selector-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="order" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Order")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Status")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="remote-asn" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Remote ASN")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="namespace" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Namespace filter to apply the policy")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="policy-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Description of the policy")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="policy-variables" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Set of rule variables")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:rules" minOccurs="0"/> + <xs:element ref="tns:selector-list" minOccurs="0" maxOccurs="5000"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="policies"> + <xs:complexType> + <xs:sequence> + <xs:element ref="tns:policy" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlan-characteristic"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an vlan characteristic",indexedProps="vlan-characteristic-id",container="vlan-characteristics",namespace="common",uriTemplate="/common/vlan-characteristics/vlan-characteristic/{vlan-characteristic-id}",requiredProps="vlan-characteristic-id,dhcp-pool,internet-access")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vlan-characteristic-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="root-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="applies-to" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Device role the vlan-characteristic applies to (c-agg-leaf-a, c-agg-leaf-b, r-leaf).")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="dhcp-pool" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="DHCP Agent access.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="internet-access" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(defaultValue="false",description="Boolean to represent if requires internet access.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vlan-characteristics"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of vlan characteristics")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:vlan-characteristic" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="relationship-component"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an relationship component",indexedProps="rule-node,rule-property,rule-value,component-order",container="relationship-components",dependentOn="relationship-rule",uriTemplate="common/relationship-components/relationship-component/{rule-node}",requiredProps="rule-node,rule-property,rule-value,component-order")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="rule-node" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="NARAD object")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="rule-property" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Object property")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="rule-value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Property value")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="component-order" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Order in traversal")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="relationship-components"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of relationship components")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:relationship-component" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="relationship-rule"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="describes an relationship rule",indexedProps="rule-id,context,rule-traversals,applies-to",uniqueProps="rule-id",container="relationship-rules",namespace="common",uriTemplate="/common/relationship-rules/relationship-rule/{rule-id}",requiredProps="rule-id,context,rule-traversals,applies-to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="rule-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="UUID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="context" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Example global,site")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="rule-traversals" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Number of traversals")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="applies-to" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Node the related object applies to")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-components" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="relationship-rules"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of relationship rules")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:relationship-rule" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="common"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Namespace for common inventory resources.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:hardware-catalog-items" minOccurs="0"/> + <xs:element ref="tns:contacts" minOccurs="0"/> + <xs:element ref="tns:profiles" minOccurs="0"/> + <xs:element ref="tns:policies" minOccurs="0"/> + <xs:element ref="tns:vlan-characteristics" minOccurs="0"/> + <xs:element ref="tns:relationship-rules" 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="overloaded-model"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Allows for legacy POST of old-style and new-style models",requiredProps="model-invariant-id,model-name-version-id,model-type,model-name,model-id,model-version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier corresponding to the main definition of a model in ASDC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-name-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique identifier corresponding to one version of a model in ASDC")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Type of the model, e.g., service, resource, widget, etc.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of the model, which can change from version to version.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Invariant unique ID which does not change from version to version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Version")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Description")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:model-vers" minOccurs="0"/> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="query-parameters"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="QueryParameters for performing a named-query or model query")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:named-query" minOccurs="0"/> + <xs:element ref="tns:overloaded-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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="InstanceFilters for performing a named-query or model query")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:instance-filter" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="secondary-filt"> + <xs:complexType> + <xs:sequence/> + </xs:complexType> + </xs:element> + <xs:element name="secondary-filts"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="SecondaryFilts for performing a named-query or model query")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:secondary-filt" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="model-and-named-query-search"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="ModelAndNamedQuerySearch holds query-parameters and instance-properties for performing a named-query or model query")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:query-parameters" minOccurs="0"/> + <xs:element ref="tns:instance-filters" minOccurs="0"/> + <xs:element ref="tns:secondary-filts" minOccurs="0"/> + <xs:element name="top-node-type" type="xs:string" minOccurs="0"/> + <xs:element name="secondary-filter-cut-point" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="properties"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Property holder for query properties or instance properties")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <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-property"> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Extra properties for inventory item for response list")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:extra-property" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="inventory-response-item"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Inventory item for response list",container="inventory-response-items")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <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:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Container for inventory items in response list",container="response-list")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:inventory-response-item" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="response-list"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Response container for the results of a named-query or model query")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:inventory-response-items" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="vnf"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Abstract vnf class",indexedProps="vnf-id",uniqueProps="vnf-id",inheritors="vce,generic-vnf",isAbstract="true",requiredProps="vnf-id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="vnf-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Unique id of VNF. This is unique across the graph.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="uni"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of an User network interface",indexedProps="id,tp-id,cvlan,operational-status,model-invariant-id,model-version-id",searchable="id",uniqueProps="id",container="unis",namespace="network",requiredProps="id",uriTemplate="/network/unis/uni/{id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Id that identifies the UNI")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="tp-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Termination point ID.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="cvlan" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The cvlan for the site used for ethernet type connectivity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="unis"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of User network interface.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:uni" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="interlayer-attachment"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of an inter layer topology attachment",indexedProps="id,model-invariant-id,model-version-id",searchable="id",uniqueProps="id",container="interlayer-attachments",namespace="network",requiredProps="id",uriTemplate="/network/interlayer-attachments/interlayer-attachment/{id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Id that identifies the interlayer topology attachment")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="inter-layer-lockId" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Inter layer lock id")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="interlayer-attachments"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of interlayer topology connectivities.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:interlayer-attachment" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="te-link-attribute"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of an te-link-attribute",indexedProps="id,link-protection-type,access-type,operational-status,model-invariant-id,model-version-id",searchable="id",uniqueProps="id",container="te-link-attributes",namespace="network",requiredProps="id",uriTemplate="/network/te-link-attributes/te-link-attribute/{id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Id that identifies the TE link attribute")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="link-protection-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicate desired protection type of the link e.g, unprotected, shared or 1+1")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="access-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicate link access type e.g, point-to-point or multi-access.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="available-bandwidth" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Bandwidth available on link.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="odu-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The type of ODU e.g, ODU1, ODU2, ODU3, ODU4.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="number" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="The value of available bandwidth.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="is-abstract" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicate wheather link is abstract or native")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="te-link-attributes"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of TE link attributes.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:te-link-attribute" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="label-restriction"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of an label restriction",indexedProps="id,label-start,label-end,range-bitmap,operational-status,model-invariant-id,model-version-id",searchable="id",uniqueProps="id",container="label-restrictions",namespace="network",requiredProps="id",uriTemplate="/network/label-restrictions/label-restriction/{id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Id that identifies the label restriction")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="label-start" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="First number in the label range")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="label-end" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Last number in the label range")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="range-bitmap" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Bitmap of available labels starting from label-start to label-end.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="label-step" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Step of labels in label range.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="inclusive-exclusive" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicate wheather range-bitmap items are inclusive or exclusive.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="range-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicate the label range e.g.trib-slot, trib-port")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="trib-slot-granularity" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicate trib slot granularity.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="priority" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Priority.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="label-restrictions"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of Label Restriction.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:label-restriction" minOccurs="0" maxOccurs="5000"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="tunnel-termination-point"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Instance of an tunnel termination point",indexedProps="ttp-id,tunnel-tp-id,name,operational-status,model-invariant-id,model-version-id",searchable="ttp-id",uniqueProps="ttp-id",container="tunnel-termination-points",namespace="network",requiredProps="ttp-id",uriTemplate="/network/tunnel-termination-points/tunnel-termination-point/{ttp-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="ttp-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(isKey=true,description="Id that identifies the tunnel termination point")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="tunnel-tp-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="TTP ID discovered from controller")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="name" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Name of tunnel termination point")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="admin-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Admin status of TTP e.g, up,down,testing,preparing-maintenance,maintenance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="oper-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Operational status of TTP e.g, up,down,testing,preparing-maintenance,maintenance.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="switching-capability" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicate switching capability of TTP e.g,PSC-1, EVPL,L2SC,TDM,OTN.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="encoding" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Encoding support by the TTP e.g, packet,ethernet,PDH,SDH,digital-wrapper,lambda,fiber,ODUK,line.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="protection-type" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Indicate supported protection type of this TTP e.g, unprotected,reroute,reroute-extra,1-for-n,unidir-1-to-1.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="inter-layer-lock-id" type="xs:int" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="correlation between related objects in ETH and OTN topology.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="selflink" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the link to get more information for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="operational-status" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the operational-status for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-customization-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Store the model-customization-id for this object.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-invariant-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model id for this resource or service model.",visibility="deployment",requires="model-version-id",dbAlias="model-invariant-id-local")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="model-version-id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="the ASDC model version for this resource or service model.",visibility="deployment",requires="model-invariant-id",dbAlias="model-version-id-local",privateEdge="service-design-and-creation/models/model/{model-invariant-id}/model-vers/model-ver/{model-version-id}")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element name="resource-version" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="Used for optimistic concurrency. Must be empty on create, valid on update and delete.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + </xs:element> + <xs:element ref="tns:relationship-list" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="tunnel-termination-points"> + <xs:complexType> + <xs:annotation> + <xs:appinfo> + <annox:annotate target="class">@org.onap.aai.annotations.Metadata(description="Collection of Tunnel Termination Point.")</annox:annotate> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element ref="tns:tunnel-termination-point" minOccurs="0" maxOccurs="5000"/> + </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:external-system" 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:element ref="tns:common" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/aai-service/provider/src/main/resources/aaiclient.properties b/aai-service/provider/src/main/resources/aaiclient.properties new file mode 100755 index 000000000..979537f8e --- /dev/null +++ b/aai-service/provider/src/main/resources/aaiclient.properties @@ -0,0 +1,76 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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 file for A&AI Client +# + +# +# Certificate keystore and truststore +# +org.onap.ccsdk.sli.adaptors.aai.ssl.trust=/opt/onap/ccsdk/data/stores/truststore.onap.client.jks +org.onap.ccsdk.sli.adaptors.aai.ssl.trust.psswd=adminadmin +org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore=true + +org.onap.ccsdk.sli.adaptors.aai.client.name=SDNC +org.onap.ccsdk.sli.adaptors.aai.client.psswd=SDNC + +org.onap.ccsdk.sli.adaptors.aai.application=CCSDK +# +# Configuration file for A&AI Client +# +org.onap.ccsdk.sli.adaptors.aai.uri=https://aai.api.simpledemo.onap.org:8443 +connection.timeout=60000 +read.timeout=60000 + +# aai version +org.onap.ccsdk.sli.adaptors.aai.version=/v21/ + +# query +org.onap.ccsdk.sli.adaptors.aai.path.query=/aai/v21/search/sdn-zone-query +org.onap.ccsdk.sli.adaptors.aai.query.nodes=/aai/v21/search/nodes-query?search-node-type={node-type}&filter={entity-identifier}:EQUALS:{entity-name} +org.onap.ccsdk.sli.adaptors.aai.query.generic=/aai/v21/search/generic-query?key={identifier}:{value}&start-node-type={start-node-type}&include=complex&depth=3 + +#update +org.onap.ccsdk.sli.adaptors.aai.update=/aai/v21/actions/update + +# UBB Notify +org.onap.ccsdk.sli.adaptors.aai.path.notify=/aai/v21/actions/notify +org.onap.ccsdk.sli.adaptors.aai.notify.selflink.fqdn=<%= @ubbUri %>/restconf/config/L3SDN-API:services/layer3-service-list/{service-instance-id} +org.onap.ccsdk.sli.adaptors.aai.notify.selflink.avpn=<%= @ubbUri %>/restconf/config/L3AVPN-EVC-API:services/service-list/{service-instance-id}/service-data/avpn-logicalchannel-information + +# VNF IMAGES +org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query=/aai/v21/service-design-and-creation/vnf-images/vnf-image?application={application_model}&application-vendor={application_vendor} + +# service instance +org.onap.ccsdk.sli.adaptors.aai.path.svcinst.query=/aai/v21/search/generic-query?key=service-instance.service-instance-id:{svc-instance-id}&start-node-type=service-instance&include=service-instance +org.onap.ccsdk.sli.adaptors.aai.path.service.instance=/aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances/service-instance/{service-instance-id} + +# VNF IMAGES QUERY +org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query=/aai/v21/service-design-and-creation/vnf-images/vnf-image?application={application_model}&application-vendor={application_vendor} + +# +# Formatting +# +org.onap.ccsdk.sli.adaptors.aai.param.format=filter=%s:%s +org.onap.ccsdk.sli.adaptors.aai.param.vnf_type=vnf-type +org.onap.ccsdk.sli.adaptors.aai.param.physical.location.id=physical-location-id +org.onap.ccsdk.sli.adaptors.aai.param.service.type=service-type diff --git a/aai-service/provider/src/main/resources/org/opendaylight/blueprint/aaiservice-blueprint.xml b/aai-service/provider/src/main/resources/org/opendaylight/blueprint/aaiservice-blueprint.xml new file mode 100755 index 000000000..970936610 --- /dev/null +++ b/aai-service/provider/src/main/resources/org/opendaylight/blueprint/aaiservice-blueprint.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 - 2018 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="provider" class="org.onap.ccsdk.sli.adaptors.aai.AAIServiceProvider" /> + + <bean id="aaiService" class="org.onap.ccsdk.sli.adaptors.aai.AAIService"> + <argument ref="provider" /> + </bean> + <service ref="aaiService"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.aai.AAIService</value> + <value>org.onap.ccsdk.sli.adaptors.aai.AAIClient</value> + </interfaces> + </service> + +</blueprint> diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AAIClientRESTExecutorTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AAIClientRESTExecutorTest.java new file mode 100644 index 000000000..f60b2da64 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AAIClientRESTExecutorTest.java @@ -0,0 +1,126 @@ +package org.onap.ccsdk.sli.adaptors.aai; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.assertNotNull; + +public class AAIClientRESTExecutorTest { + + private static AAIClientRESTExecutor aaiExecute; + private static AAIService aaiService; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + Properties properties = new Properties(); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore", "true"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.client.name", "SDNC"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.client.psswd", "SDNC"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.application", "CCSDK"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.uri", "http://localhost:8181"); + properties.setProperty("connection.timeout", "60000"); + properties.setProperty("read.timeout", "60000"); + aaiExecute = new AAIClientRESTExecutor(properties); + aaiService = new AAIService(properties); + + + } + + @Test + public void testGet() { + Map<String, String> nameValues = new HashMap<>(); + nameValues.put("generic-vnf.vnf-id", "vnf-001"); + AAIRequest request = AAIRequest.createRequest("generic-vnf", nameValues); + try { + aaiExecute.get(request); + } catch (AAIServiceException e) { + } + assert(true); + assertNotNull(nameValues); + } + + @Test + public void testPost() { + Map<String, String> nameValues = new HashMap<>(); + nameValues.put("generic-vnf.vnf-id", "vnf-001"); + AAIRequest request = AAIRequest.createRequest("generic-vnf", nameValues); + try { + aaiExecute.get(request); + } catch (AAIServiceException e) { + } + assert(true); + assertNotNull(nameValues); + } + + @Test + public void testDelete() { + Map<String, String> nameValues = new HashMap<>(); + nameValues.put("generic-vnf.vnf-id", "vnf-001"); + AAIRequest request = AAIRequest.createRequest("generic-vnf", nameValues); + try { + aaiExecute.get(request); + } catch (AAIServiceException e) { + } + assert(true); + assertNotNull(nameValues); + } + + @Test + public void testQuery() { + Map<String, String> nameValues = new HashMap<>(); + nameValues.put("generic-vnf.vnf-id", "vnf-001"); + AAIRequest request = AAIRequest.createRequest("generic-vnf", nameValues); + try { + aaiExecute.get(request); + } catch (AAIServiceException e) { + } + assert(true); + assertNotNull(nameValues); + } + + @Test + public void testPatch() { + Map<String, String> nameValues = new HashMap<>(); + nameValues.put("generic-vnf.vnf-id", "vnf-001"); + AAIRequest request = AAIRequest.createRequest("generic-vnf", nameValues); + try { + aaiExecute.patch(request, "1234567890"); + } catch (AAIServiceException e) { + } + assert(true); + assertNotNull(nameValues); + } + + + + @Test + public void testLOGwriteFirstTrace() { + try { + aaiExecute.LOGwriteFirstTrace("GET", null); + } catch (Exception e) { + } + assert(true); + } + + @Test + public void testLOGwriteDateTrace() { + try { + aaiExecute.LOGwriteDateTrace("GET", "<----- test data ------>"); + } catch (Exception e) { + } + assert(true); + } + + @Test + public void testLOGwriteEndingTrace() { + try { + aaiExecute.LOGwriteEndingTrace(200, "GET", "<----- test data ------>"); + } catch (Exception e) { + } + assert(true); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceProviderTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceProviderTest.java new file mode 100644 index 000000000..bfe3738e0 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceProviderTest.java @@ -0,0 +1,31 @@ +package org.onap.ccsdk.sli.adaptors.aai; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class AAIServiceProviderTest { + + private static AAIServiceProvider provider = null; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Test + public void testAAIServiceProvider() { + provider = new AAIServiceProvider(); + } + + @Test + public void testGetProperties() { + provider.getProperties(); + assert(true); + } + + @Test + public void testDeterminePropertiesFile() { + provider.determinePropertiesFile(); + assert(true); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceTest.java new file mode 100755 index 000000000..079c76cbd --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AAIServiceTest.java @@ -0,0 +1,212 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.ProtocolException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.net.ssl.HttpsURLConnection; +import javax.ws.rs.HttpMethod; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.runners.MockitoJUnitRunner; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.onap.aai.inventory.v21.*; + +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.onap.ccsdk.sli.adaptors.aai.AAIService.TransactionIdTracker; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; + +@RunWith(MockitoJUnitRunner.class) +public class AAIServiceTest { + private static AAIService aaiService = new AAIService( + AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES)); + + @Spy private AAIService aaiServiceSpy = new AAIService( + AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES)); + + @Mock private HttpsURLConnection connMock; + + // @Test + public void existsInvalidResource_shouldReturnFailure() throws MalformedURLException, Exception { + QueryStatus queryStatus = aaiServiceSpy.exists("InvalidResource", null, null, null); + assertEquals(QueryStatus.FAILURE, queryStatus); + } + +// @Test + public void existsGetPserverByCallBackUrl_shouldReturnSuccess() throws MalformedURLException, Exception { + String key = "https://aai.api.simpledemo.onap.org:8443/aai/v11/cloud-infrastructure/pservers/pserver/chcil129snd"; + String fileLocation = "json/pserverJson.txt"; + SvcLogicContext ctx = new SvcLogicContext(); + setConnMock(); + + when(aaiServiceSpy.getConfiguredConnection(new URL(key), HttpMethod.GET)).thenReturn(connMock); + when(connMock.getResponseCode()).thenReturn(200); + when(connMock.getInputStream()).thenReturn(getClass().getClassLoader().getResourceAsStream(fileLocation)); + + QueryStatus queryStatus = aaiServiceSpy.exists("pserver", key, "prefix.", ctx); + + assertEquals(QueryStatus.SUCCESS, queryStatus); + } + +// @Test + public void existsGetPserverByCallBackUrl_throwsExceptionAndReturnsFailure() + throws MalformedURLException, Exception { + String key = "https://aai.api.simpledemo.onap.org:8443/aai/v11/cloud-infrastructure/pservers/pserver/chcil129snd"; + String fileLocation = "json/pserverJson.txt"; + SvcLogicContext ctx = new SvcLogicContext(); + setConnMock(); + + when(aaiServiceSpy.getConfiguredConnection(new URL(key), HttpMethod.GET)).thenReturn(connMock); + when(connMock.getResponseCode()).thenReturn(200); + when(connMock.getInputStream()).thenReturn(getClass().getClassLoader().getResourceAsStream(fileLocation)); + + when(aaiServiceSpy.dataChangeRequestAaiData(key, Pserver.class)).thenThrow( + new AAIServiceException("testException")); + + QueryStatus queryStatus = aaiServiceSpy.exists("pserver", key, "prefix.", ctx); + + assertEquals(QueryStatus.FAILURE, queryStatus); + } + +// @Test + public void pserverDataChangeRequestData_shouldSucceed() throws Exception { + String fileLocation = "json/pserverJson.txt"; + String url = "https://aai.api.simpledemo.onap.org:8443/aai/v11/cloud-infrastructure/pservers/pserver/chcil129snd"; + setConnMock(); + + when(aaiServiceSpy.getConfiguredConnection(new URL(url), HttpMethod.GET)).thenReturn(connMock); + when(connMock.getResponseCode()).thenReturn(200); + when(connMock.getInputStream()).thenReturn(getClass().getClassLoader().getResourceAsStream(fileLocation)); + + Pserver pserver = aaiServiceSpy.dataChangeRequestAaiData(url, Pserver.class); + + assertEquals("chcil129snd", pserver.getHostname()); + } + +// @Test + public void pserverDataChangeRequestData_shouldReturnNullFor404() throws Exception { + String fileLocation = "json/pserverJson.txt"; + String url = "https://aai.api.simpledemo.onap.org:8443/aai/v11/cloud-infrastructure/pservers/pserver/chcil129snd"; + setConnMock(); + + when(aaiServiceSpy.getConfiguredConnection(new URL(url), HttpMethod.GET)).thenReturn(connMock); + when(connMock.getResponseCode()).thenReturn(404); + when(connMock.getErrorStream()).thenReturn(getClass().getClassLoader().getResourceAsStream(fileLocation)); + + Pserver pserver = aaiServiceSpy.dataChangeRequestAaiData(url, Pserver.class); + + assertEquals(null, pserver); + } + + @Test(expected = AAIServiceException.class) + public void dataChangeRequestData_throwsAAIServiceException() throws Exception { + String fileLocation = "json/pserverJson.txt"; + String url = "https://aai.api.simpledemo.onap.org:8443/aai/v11/cloud-infrastructure/pservers/pserver/chcil129snd"; + setConnMock(); + + // The following lines are not needed and cause latest version of mockito to throw an exception +// when(aaiServiceSpy.getConfiguredConnection(new URL(url), HttpMethod.GET)).thenReturn(connMock); +// when(connMock.getResponseCode()).thenReturn(500); +// when(connMock.getInputStream()).thenReturn(getClass().getClassLoader().getResourceAsStream(fileLocation)); + + aaiServiceSpy.dataChangeRequestAaiData(url, Class.class); + } + + public String readFileToString(String fileName) throws IOException, URISyntaxException { + URL url = AAIServiceTest.class.getResource(fileName); + Path resPath = Paths.get(url.toURI()); + + return new String(Files.readAllBytes(resPath), "UTF8"); + } + + public <T> T getObjectFromJson(String text, Class<T> type) + throws JsonParseException, JsonMappingException, IOException { + ObjectMapper mapper = AAIService.getObjectMapper(); + + return type.cast(mapper.readValue(text, type)); + } + + private void setConnMock() throws ProtocolException { + // Set up the connection properties + connMock.setRequestProperty("Connection", "close"); + connMock.setDoInput(true); + connMock.setDoOutput(true); + connMock.setUseCaches(false); + connMock.setConnectTimeout(1000); + connMock.setReadTimeout(1000); + connMock.setRequestMethod(HttpMethod.GET); + connMock.setRequestProperty("Accept", "application/json"); + connMock.setRequestProperty("Content-Type", "application/json"); + connMock.setRequestProperty("X-FromAppId", "testId"); + connMock.setRequestProperty("X-TransactionId", TransactionIdTracker.getNextTransactionId()); + } + + @Test + public void testSetStatusMessage_shouldSucceed() throws SvcLogicException, MalformedURLException { + SvcLogicContext ctx = new SvcLogicContext(); + Map<String, String> parameters = new HashMap<String, String>(); + + parameters.put("key1", "ActivateSubnet failure, need to manually activate in EIPAM."); + aaiService.setStatusMethod(parameters, ctx); + + Pattern r8601 = Pattern.compile( + "(\\d{4})-(\\d{2})-(\\d{2})T((\\d{2}):(\\d{2}):(\\d{2}))Z"); + Matcher isoDate = r8601.matcher(ctx.getAttribute("aai-summary-status-message")); + + assertTrue(isoDate.lookingAt()); + + assertTrue(ctx.getAttribute("aai-summary-status-message") + .contains("ActivateSubnet failure, need to manually activate in EIPAM.")); + } + + @Test(expected = SvcLogicException.class) + public void testSetStatusMessage_nullContext() throws SvcLogicException, MalformedURLException { + SvcLogicContext ctx = null; + Map<String, String> parameters = new HashMap<String, String>(); + + parameters.put("key1", "ActivateSubnet failure, need to manually activate in EIPAM."); + aaiService.setStatusMethod(parameters, ctx); + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/ActionUpdateTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/ActionUpdateTest.java new file mode 100755 index 000000000..64f9b45ef --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/ActionUpdateTest.java @@ -0,0 +1,44 @@ +package org.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.*; + +import java.util.ArrayList; + +import org.onap.ccsdk.sli.adaptors.aai.update.Action; +import org.onap.ccsdk.sli.adaptors.aai.update.ActionDatum; +import org.junit.Test; + +public class ActionUpdateTest { + @Test + public void getActionData() throws Exception { + final Action resolver = new Action(); + assertNotNull(resolver.getActionData()); + } + + @Test + public void setActionData() throws Exception { + final Action resolver = new Action(); + resolver.setActionData( new ArrayList<ActionDatum>()); + assertNotNull(resolver); + } + + @Test + public void setActionType() throws Exception { + final Action resolver = new Action(); + resolver.setActionType("create"); + assertEquals("create", resolver.getActionType()); + } + + @Test + public void getAdditionalProperties() throws Exception { + final Action resolver = new Action(); + assertNotNull(resolver.getAdditionalProperties()); + } + + @Test + public void setAdditionalProperty() throws Exception { + final Action resolver = new Action(); + resolver.setAdditionalProperty("outcome", "success"); + assertEquals("success", resolver.getAdditionalProperties().get("outcome")); + } +}
\ No newline at end of file diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AutoGeneratedRegressionTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AutoGeneratedRegressionTest.java new file mode 100755 index 000000000..5ac503ff5 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/AutoGeneratedRegressionTest.java @@ -0,0 +1,906 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; +import java.util.Stack; +import java.util.UUID; + +import javax.xml.bind.SchemaOutputResolver; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Result; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; + +import org.apache.commons.lang.RandomStringUtils; +import org.apache.commons.lang.StringUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.onap.aai.inventory.v21.GenericVnf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.AnnotationUtils; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; + + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class AutoGeneratedRegressionTest { + + static { + System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "INFO"); + System.setProperty(org.slf4j.impl.SimpleLogger.LOG_FILE_KEY, String.format("AutoGeneratedRegressionTest-%d.txt", System.currentTimeMillis())); + } + private static final Logger LOG = LoggerFactory.getLogger(AutoGeneratedRegressionTest.class); + + + protected static AAIClient client; + + protected Map<String, String> cache = new HashMap<String, String>(); + + @BeforeClass + public static void setUp() throws Exception { + URL url = AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES); + client = new AAIService(url); + LOG.info("----------------------- aicAAIResourceTest.setUp -----------------------"); + } + + @AfterClass + public static void tearDown() throws Exception { + client = null; + LOG.info("----------------------- AAIResourceTest.tearDown -----------------------"); + } + + + @Test + public void mainLoadTest () + { + try + { + String currentDir = System.getProperty("user.dir"); + File dir = new File(currentDir); + if(!dir.exists()) { + System.exit(1); + } + dir = new File(dir, "src/main/resources"); + if(!dir.exists()) { + System.exit(1); + } + // parse the document + File file = new File(dir, "aai_schema_v11.xsd"); + if(!file.exists()) { + assert(false); + return; + } + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(file); + + Stack<String> stack = new Stack<String>(); + List<String> commands = new ArrayList<String>(); + listSubNodes("network", doc, stack, commands); + listSubNodes("cloud-infrastructure", doc, stack, commands); + listSubNodes("service-design-and-creation", doc, stack, commands); + listSubNodes("license-management", doc, stack, commands); + listSubNodes("business", doc, stack, commands); + + String[] requestDefinition = commands.toArray(new String[0]); + LOG.info("\n----------------------------"); + + executeTests(requestDefinition); + } + catch (Throwable e) + { + LOG.error("", e); + } + } + + @Test + public void testFromFile() { + String filename = "testCommands.txt"; + List<String> lines = new ArrayList<String>(); + Scanner scanner = null; + + try { + File testFile = new File(filename); + if(!testFile.exists()) + return; + scanner = new Scanner(testFile); + while (scanner.hasNextLine()) { + lines.add(scanner.nextLine()); + } + } catch (Exception exc) { + + } finally { + if(scanner != null) + scanner.close(); + } + + String[] requestDefinition = lines.toArray(new String[0]); + executeTests(requestDefinition); + } + + + @Test + public void test01AutoGeneratedRequest() { + + String[] requestDefinition = { + "save|generic-vnf|generic-vnf.vnf-id:assign:value:adb28ac0-a260-4b7d-9ce5-adf15733c458", + "update|generic-vnf|generic-vnf.vnf-id:assign:value:adb28ac0-a260-4b7d-9ce5-adf15733c458", + "query|generic-vnf|generic-vnf.vnf-id:assign:value:adb28ac0-a260-4b7d-9ce5-adf15733c458", + "delete|generic-vnf|generic-vnf.vnf-id:assign:value:adb28ac0-a260-4b7d-9ce5-adf15733c458" + }; + + executeTests(requestDefinition); + } + + public void executeTests(String[] requestDefinition) { + + for(String line : requestDefinition){ + LOG.info("Executing: " + line); + + // parse request line resource | key structure + String[] segments = line.split("\\|"); + String action = segments[0]; + String resource = segments[1]; + String[] tmpKeys = segments[2].split("&"); + // String array keyStructure can be tmpKey. + // options :assign:uuid:cache + // :cached + // :query:random + + + String localId = null; + + List<String> keys = new ArrayList<String>(); + String keyLine = null; + + for(String instruction : tmpKeys) { + String[] parts = instruction.split(":"); + String identifier = parts[0]; + String method = parts[2]; + + if(identifier.startsWith(resource)) { + localId = identifier; + } else if(identifier.startsWith("l-interface") && "l2-bridge-bgf".equals(resource)) { + localId = identifier; + } else if(identifier.startsWith("l-interface") && "l2-bridge-sbg".equals(resource)) { + localId = identifier; + } else if("nodes-query".equals(resource)) { + localId = identifier; + } + + switch(parts[1]) { + case "assign": + String postProcesss = parts[3]; + keyLine = processAssign(identifier, method, postProcesss); + if(keyLine != null && !keyLine.trim().isEmpty()) { + keys.add(keyLine); + } + break; + case "cached": + keyLine = processCached(identifier, method); + if(keyLine != null && !keyLine.trim().isEmpty()) { + keys.add(keyLine); + } + break; + } + + } + + List<String> x = Arrays.asList(localId.split("\\.")); + switch(action){ + case "save": + testAutoGeneratedSaveRequest(resource, keys, x.get(x.size() - 1), cache.get(localId)); + break; + case "update": + testAutoGeneratedUpdateRequest(resource, keys, x.get(x.size() - 1), cache.get(localId)); + break; + + case "query": + test03AutoGeneratedQueryRequest(resource, keys); + break; + case "delete": + test03AutoGeneratedDeleteRequest(resource, keys); + break; + } + } + + LOG.info("done"); + } + + + public void testAutoGeneratedSaveRequest(String resource, List<String> requestKeys, String identifier, String idValue) { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + Map<String, String> nameValues = keyToHashMap(StringUtils.join(requestKeys, " AND "), new SvcLogicContext()); + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + Class<AAIDatum> resourceClass = (Class<AAIDatum>) (request==null ? GenericVnf.class : request.getModelClass()); + + Map<String, String> data = new HashMap<String, String>(); + + for(Field field : resourceClass.getDeclaredFields()) { + String type = field.getType().getName(); + switch(type){ + case "bool": + case "boolean": + type = Boolean.class.getName(); + break; + case "int": + type = Integer.class.getName(); + break; + case "long": + type = Long.class.getName(); + break; + + } + if(type.startsWith("java.lang.")){ + Annotation[] fieldAnnotations = field.getAnnotations(); + for(int i = 0; i < fieldAnnotations.length; i++) { + Annotation a = fieldAnnotations[i]; + if(a instanceof JsonProperty){ + JsonProperty pa = (JsonProperty)a; + String name = pa.value(); + String value; + switch(type) { + case "java.lang.Integer": + case "java.lang.Long": + value = RandomStringUtils.random(6, false, true); + break; + case "java.lang.Boolean": + value = "false"; + break; + default: + if(name.equals(identifier)) { + value = idValue; + } else { + value = RandomStringUtils.random(10, true, false); + } + } + data.put(name, value); + } else + if(a instanceof javax.xml.bind.annotation.XmlElement) { + XmlElement xe = (XmlElement)a; + String name = xe.name(); + if("model-version-id".equals(name)) { + continue; + } + if("model-invariant-id".equals(name)) { + continue; + } + if("link-type".equals(name)){ + data.put(name, "roadmTail"); + continue; + } + if("operational-status".equals(name)){ + data.put(name, "available"); + continue; + } + if(name.equals(identifier)) { + data.put(name, idValue); + continue; + } + + String value; + switch(type) { + case "java.lang.Integer": + case "java.lang.Long": + value = RandomStringUtils.random(6, false, true); + break; + case "java.lang.Boolean": + value = "false"; + break; + default: + if(name.equals(identifier)) { + value = idValue; + } else { + value = RandomStringUtils.random(10, true, false); + } + } + data.put(name, value); + } + } + } + } + + SvcLogicContext ctx = new SvcLogicContext(); + + data.remove("resource-version"); + + QueryStatus resp = null; + + //(String resource, boolean force, boolean localOnly, String key, Map<String, String> parms, String prefix, SvcLogicContext ctx) + resp = client.save(resource, false, false, StringUtils.join(requestKeys, " AND "), data, "aaidata", ctx); + if(resp == QueryStatus.SUCCESS) { + LOG.info(String.format("Save %s successfull", resource)); + } else { + LOG.info(String.format("Save %s failed due to : %s", resource, ctx.getAttribute("aaidata.error.message"))); + } + } + catch (Throwable e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + public void test03AutoGeneratedQueryRequest(String resource, List<String> requestKeys) { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + SvcLogicContext ctx = new SvcLogicContext(); + try + { + + QueryStatus response = null; + + response = client.query(resource, false, null, StringUtils.join(requestKeys, " AND "), "aaiTest", null, ctx); + if(response == QueryStatus.SUCCESS) { + LOG.info(String.format("Query %s successfull", resource)); + Set<String> tokens = ctx.getAttributeKeySet(); + Map<String, String> reponseData = new HashMap<String, String>(); + + String responsePrefix = String.format("%s", "aaiTest"); + + for(String token : tokens) { + if(token.startsWith(responsePrefix)){ + reponseData.put(token, ctx.getAttribute(token)); + } else { + LOG.info(String.format("%s = ", token, ctx.getAttribute(token))); + } + } + + LOG.info("AAIResponse: " + response.toString()); + assertTrue("AAIRequest:"+resource, reponseData.size() > 0); + } else { + LOG.info(String.format("Query %s failed due to : %s", resource, ctx.getAttribute("aaidata.error.message"))); + assert(false); + } + } + catch (Throwable e) + { + LOG.error("Caught exception", e); + } + } + + + public void test03AutoGeneratedDeleteRequest(String resource, List<String> requestKeys) { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + QueryStatus response = null; + + response = client.delete(resource, StringUtils.join(requestKeys, " AND "), ctx); + if(response == QueryStatus.SUCCESS) { + LOG.info(String.format("Delete %s successfull", resource)); + } else { + LOG.info(String.format("Delete %s failed due to : %s", resource, ctx.getAttribute("aaiDelete.error.message"))); + } + } + catch (Throwable e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + public void testAutoGeneratedUpdateRequest(String resource, List<String> requestKeys, String identifier, String idValue) { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + Map<String, String> nameValues = keyToHashMap(StringUtils.join(requestKeys, " AND "), new SvcLogicContext()); + AAIRequest request = AAIRequest.createRequest(resource, nameValues); + Class<AAIDatum> resourceClass = (Class<AAIDatum>) (request==null ? GenericVnf.class : request.getModelClass()); + + Map<String, String> data = new HashMap<String, String>(); + + boolean skipFirst = true; + boolean breakLoop = false; + for(Field field : resourceClass.getDeclaredFields()) { + if(skipFirst){ + skipFirst = false; + continue; + } + if(breakLoop){ + break; + } + String type = field.getType().getName(); + if(type.startsWith("java.lang.")){ + Annotation[] fieldAnnotations = field.getAnnotations(); + for(int i = 0; i < fieldAnnotations.length; i++) { + Annotation a = fieldAnnotations[i]; + if(a instanceof JsonProperty){ + JsonProperty pa = (JsonProperty)a; + String name = pa.value(); + String value; + switch(type) { + case "java.lang.Integer": + case "java.lang.Long": + value = RandomStringUtils.random(6, false, true); + break; + case "java.lang.Boolean": + value = "false"; + break; + default: + if(name.equals(identifier)) { + value = idValue; + } else { + value = RandomStringUtils.random(10, true, false); + } + } + data.put(name, value); + breakLoop = true; + } else + if(a instanceof javax.xml.bind.annotation.XmlElement) { + XmlElement xe = (XmlElement)a; + String name = xe.name(); + if("link-type".equals(name)){ + data.put(name, "roadmTail"); + continue; + } + if("operational-status".equals(name)){ + data.put(name, "available"); + continue; + } + String value; + switch(type) { + case "java.lang.Integer": + case "java.lang.Long": + value = RandomStringUtils.random(6, false, true); + break; + case "java.lang.Boolean": + value = "false"; + break; + default: + if(name.equals(identifier)) { + value = idValue; + } else { + value = RandomStringUtils.random(10, true, false); + } + } + data.put(name, value); + breakLoop = true; + } + } + } + } + + SvcLogicContext ctx = new SvcLogicContext(); + + data.remove("resource-version"); + + QueryStatus resp = null; + + //client.update("ipsec-configuration", "ipsec-configuration.ipsec-configuration-id = 'testConfigurationId01'", data, "aaiTest", ctx); + resp = client.update(resource, StringUtils.join(requestKeys, " AND "), data, "aaidata", ctx); + if(resp == QueryStatus.SUCCESS) { + LOG.info(String.format("Update %s successfull", resource)); + } else { + LOG.info(String.format("Update %s failed due to : %s", resource, ctx.getAttribute("aaidata.error.message"))); + } + + } + catch (Throwable e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + static ArrayList<Method> findSetters(Class<?> c) { + ArrayList<Method> list = new ArrayList<Method>(); + Method[] methods = c.getDeclaredMethods(); + for (Method method : methods) + if (isGetter(method)) + list.add(method); + return list; + } + + + public static boolean isGetter(Method method) { + if (Modifier.isPublic(method.getModifiers()) && + method.getParameterTypes().length == 0) { + if (method.getName().matches("^get[A-Z].*") && + !method.getReturnType().equals(void.class)) + return true; + if (method.getName().matches("^is[A-Z].*") && + method.getReturnType().equals(boolean.class)) + return true; + } + return false; + } + + public static boolean isSetter(Method method) { + return Modifier.isPublic(method.getModifiers()) && + method.getReturnType().equals(void.class) && + method.getParameterTypes().length == 1 && + method.getName().matches("^set[A-Z].*"); + } + + private String processAssign(String identifier, String method, String postProcess) { + String value = null; + if("uuid".equals(method)) { + value = UUID.randomUUID().toString(); + } + + if("cache".equals(postProcess)) { + cache.put(identifier, value); + } + + if("value".equals(method)) { + cache.put(identifier, postProcess); + value = postProcess; + } + + String key = String.format("%s = '%s'", identifier, value); + return key; + } + + private String processCached(String identifier, String method) { + String value = cache.get(identifier); + + String key = String.format("%s = '%s'", identifier, value); + return key; + } + + protected HashMap<String,String> keyToHashMap(String key, SvcLogicContext ctx) { + if (key == null) { + return (null); + } + + LOG.debug("Converting key [" + key + "] to where clause"); + + if (key.startsWith("'") && key.endsWith("'")) { + key = key.substring(1, key.length() - 1); + + LOG.debug("Stripped outer single quotes - key is now [" + key + "]"); + } + + String[] keyTerms = key.split("\\s+"); + + String term1 = null; + String op = null; + String term2 = null; + HashMap<String, String> results = new HashMap<String, String>(); + + for (int i = 0; i < keyTerms.length; i++) { + if (term1 == null) { + if ("and".equalsIgnoreCase(keyTerms[i]) + || "or".equalsIgnoreCase(keyTerms[i])) { + // Skip over ADD/OR + } else { + term1 = resolveTerm(keyTerms[i], ctx); + } + } else if (op == null) { + if ("==".equals(keyTerms[i])) { + op = "="; + } else { + op = keyTerms[i]; + } + } else { + term2 = resolveTerm(keyTerms[i], ctx); + term2 = term2.trim().replace("'", "").replace("$", "").replace("'", ""); + results.put(term1, term2); + + term1 = null; + op = null; + term2 = null; + } + } + + return (results); + } + + private String resolveTerm(String term, SvcLogicContext ctx) { + if (term == null) { + return (null); + } + + LOG.debug("resolveTerm: term is " + term); + + if (term.startsWith("$") && (ctx != null)) { + // Resolve any index variables. + + return ("'" + resolveCtxVariable(term.substring(1), ctx) + "'"); + } else if (term.startsWith("'") || term.startsWith("\"")) { + return (term); + } else { + return (term.replaceAll("-", "_")); + + } + + } + + private String resolveCtxVariable(String ctxVarName, SvcLogicContext ctx) { + + if (ctxVarName.indexOf('[') == -1) { + // Ctx variable contains no arrays + return (ctx.getAttribute(ctxVarName)); + } + + // Resolve any array references + StringBuffer sbuff = new StringBuffer(); + String[] ctxVarParts = ctxVarName.split("\\["); + sbuff.append(ctxVarParts[0]); + for (int i = 1; i < ctxVarParts.length; i++) { + if (ctxVarParts[i].startsWith("$")) { + int endBracketLoc = ctxVarParts[i].indexOf("]"); + if (endBracketLoc == -1) { + // Missing end bracket ... give up parsing + LOG.warn("Variable reference " + ctxVarName + + " seems to be missing a ']'"); + return (ctx.getAttribute(ctxVarName)); + } + + String idxVarName = ctxVarParts[i].substring(1, endBracketLoc); + String remainder = ctxVarParts[i].substring(endBracketLoc); + + sbuff.append("["); + sbuff.append(ctx.getAttribute(idxVarName)); + sbuff.append(remainder); + + } else { + // Index is not a variable reference + sbuff.append("["); + sbuff.append(ctxVarParts[i]); + } + } + + return (ctx.getAttribute(sbuff.toString())); + } + +// @Test + public void test90QueryTenantRequest() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + URL url; + + try { + url = client.requestVserverURLNodeQuery("bpsx0001vm001bps001"); + url = new URL("https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v4/cloud-infrastructure/tenants/tenant/6b012c07bdf1427190ae58f794a86344/vservers/vserver/5acfe828-82e9-swgk092815-13-4d2c-85bb-9c2c1fafcce6"); + client.getTenantIdFromVserverUrl(url); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + static class MySchemaOutputResolver extends SchemaOutputResolver { + + public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException { + File file = new File(suggestedFileName); + StreamResult result = new StreamResult(file); + result.setSystemId(file.getAbsolutePath()); + return result; + } + + } + + private static void listSubNodes(String parent, Document doc, Stack<String> stack, List<String> commands) throws Exception { + XPathFactory xFactory = XPathFactory.newInstance(); + XPath xPath = xFactory.newXPath(); + String format = "/schema/element[@name='%s']/complexType/sequence/element[@ref]"; + + String path = String.format(format, parent); + +// XPathExpression exp = xPath.compile("/schema/element[@name='generic-vnf']/complexType/sequence/element[@ref]"); + XPathExpression exp = xPath.compile(path); + + NodeList nl = (NodeList)exp.evaluate(doc.getFirstChild(), XPathConstants.NODESET); + LOG.debug("Nodes to process : "+nl.getLength()); + for (int index = 0; index < nl.getLength(); index++) { + + Node node = nl.item(index); + + if(!(node instanceof Element)) + continue; + + String classAlias = null; + + if(node.hasAttributes()) + { + String nm = ((Element)node).getAttribute("ref"); + if(nm != null && !nm.isEmpty()) { + String[] split = nm.split(":"); + classAlias = split[split.length - 1]; + if("relationship-list".equals(classAlias)) + continue; + if("metadata".equals(classAlias)) + continue; + if("classes-of-service".equals(classAlias)) { + classAlias = "class-of-service"; + } else if("l3-interface-ipv4-address-list".equals(classAlias)) { + ; + } else if("l3-interface-ipv6-address-list".equals(classAlias)) { + ; + } else if("cvlan-tags".equals(classAlias)) { + classAlias = "cvlan-tag-entry"; + } else if("network-policies".equals(classAlias)) { + classAlias = "network-policy"; + } else if("complexes".equals(classAlias)) { + classAlias = "complex"; + } else if("dvs-switches".equals(classAlias)) { + classAlias = "dvs-switch"; + } else if("service-capabilities".equals(classAlias)) { + classAlias = "service-capability"; + } else { + classAlias = classAlias.substring(0, classAlias.length() -1); + } + AAIRequest request = AAIRequest.createRequest(classAlias, new HashMap<String, String>()); + if(request != null) { + Class<?> clazz = request.getModelClass(); + Field[] fieldz = clazz.getDeclaredFields(); + Field field = fieldz[0]; + String fieldName = field.getName(); + XmlElement annotation = field.getAnnotation(XmlElement.class); + + Map<String, Object> map = AnnotationUtils.getAnnotationAttributes(annotation); + String id = (String)map.get("name"); + if("##default".equals(id)) { + id = fieldName; + } + + if("cloud-region".equals(classAlias)) { + String keystring = "cloud-region.cloud-owner:assign:value:att-aic&cloud-region.cloud-region-id:assign:value:AAIAIC25"; + stack.push(keystring); + String[] array = stack.toArray(new String[0]); + String key = StringUtils.join(array, "&"); + + String query = String.format("query|%s|%s", classAlias, key); + commands.add(query); + listSubNodes(classAlias, doc, stack, commands); + stack.pop(); + } else if("entitlement".equals(classAlias)) { + String keystring = "entitlement.group-uuid:assign:value:"+UUID.randomUUID()+"&entitlement.resource-uuid:assign:value:"+UUID.randomUUID(); + stack.push(keystring); + String[] array = stack.toArray(new String[0]); + String key = StringUtils.join(array, "&"); + + String query = String.format("query|%s|%s", classAlias, key); + commands.add(query); + listSubNodes(classAlias, doc, stack, commands); + stack.pop(); + } else if("license".equals(classAlias)) { + String keystring = "license.group-uuid:assign:value:"+UUID.randomUUID()+"&license.resource-uuid:assign:value:"+UUID.randomUUID(); + stack.push(keystring); + String[] array = stack.toArray(new String[0]); + String key = StringUtils.join(array, "&"); + + String query = String.format("query|%s|%s", classAlias, key); + commands.add(query); + listSubNodes(classAlias, doc, stack, commands); + stack.pop(); + } else if("route-target".equals(classAlias)) { + String keystring = "route-target.global-route-target:assign:value:"+UUID.randomUUID()+"&route-target.route-target-role:assign:value:"+UUID.randomUUID(); + stack.push(keystring); + String[] array = stack.toArray(new String[0]); + String key = StringUtils.join(array, "&"); + + String query = String.format("query|%s|%s", classAlias, key); + commands.add(query); + listSubNodes(classAlias, doc, stack, commands); + stack.pop(); + } else if("service-capability".equals(classAlias)) { + String keystring = "service-capability.service-type:assign:value:"+UUID.randomUUID()+"&service-capability.vnf-type:assign:value:"+UUID.randomUUID(); + stack.push(keystring); + String[] array = stack.toArray(new String[0]); + String key = StringUtils.join(array, "&"); + + String query = String.format("query|%s|%s", classAlias, key); + commands.add(query); + listSubNodes(classAlias, doc, stack, commands); + stack.pop(); + } else if("ctag-pool".equals(classAlias)) { + String keystring = "ctag-pool.target-pe:assign:value:"+UUID.randomUUID()+"&ctag-pool.availability-zone-name:assign:value:"+UUID.randomUUID(); + stack.push(keystring); + String[] array = stack.toArray(new String[0]); + String key = StringUtils.join(array, "&"); + + String query = String.format("query|%s|%s", classAlias, key); + commands.add(query); + listSubNodes(classAlias, doc, stack, commands); + stack.pop(); + } else { + String keystring = String.format("%s.%s:assign:value:%s", classAlias, id, UUID.randomUUID()); + stack.push(keystring); + String[] array = stack.toArray(new String[0]); + String key = StringUtils.join(array, "&"); + + String save = String.format("save|%s|%s", classAlias, key); + commands.add(save); + + String query = String.format("query|%s|%s", classAlias, key); + commands.add(query); + + String update = String.format("update|%s|%s", classAlias, key); + commands.add(update); + + if(!parent.equals(classAlias) && !containsCircular(classAlias, id, stack)) { + listSubNodes(classAlias, doc, stack, commands); + } + String delete = String.format("delete|%s|%s", classAlias, key); + commands.add(delete); + stack.pop(); + } + } + } + } + } + } + + public static boolean containsCircular(String classAlias, String id, Stack<String> stack) { + String keystring = String.format("%s.%s", classAlias, id); + + Stack<String> localStack = new Stack<String>(); + localStack.addAll(stack); + + localStack.pop(); + + while(!localStack.isEmpty()) { + String instruction = localStack.pop(); + if(instruction.contains(keystring)) { + return true; + } + } + + return false; + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/CustomQueryRequestTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/CustomQueryRequestTest.java new file mode 100644 index 000000000..955f5c4a1 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/CustomQueryRequestTest.java @@ -0,0 +1,117 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertNotNull; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class CustomQueryRequestTest { + + private static final Logger LOG = LoggerFactory.getLogger(CustomQueryRequestTest.class); + + private static AAIRequest request; + private static AAIService aaiService; + + @BeforeClass + public static void setUp() throws Exception { + aaiService = new AAIService(AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES)); + Map<String, String> nameValues = new HashMap<>(); + nameValues.put("generic-vnf.vnf-id", "vnf-001"); + request = AAIRequest.createRequest("generic-vnf", nameValues); + LOG.info("\nEchoRequestTest.setUp\n"); + } + + @AfterClass + public static void tearDown() throws Exception { + request = null; + LOG.info("----------------------- EchoRequestTest.tearDown -----------------------"); + } + + @Test + public void runGetRequestUrlTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + URL url; + try { + url = request.getRequestUrl("GET", null); + assertNotNull(url); + } catch (UnsupportedEncodingException | MalformedURLException | URISyntaxException exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runToJSONStringTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String json = request.toJSONString(); + assertNotNull(json); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetArgsListTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String[] args = request.getArgsList(); + assertNotNull(args); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetModelTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + Class<? extends AAIDatum> clazz = request.getModelClass(); + assertNotNull(clazz); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/EchoRequestTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/EchoRequestTest.java new file mode 100755 index 000000000..3e0a72f3a --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/EchoRequestTest.java @@ -0,0 +1,136 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertNotNull; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class EchoRequestTest { + + private static final Logger LOG = LoggerFactory.getLogger(EchoRequestTest.class); + + private static EchoRequest request; + private static AAIService aaiService; + + @BeforeClass + public static void setUp() throws Exception { + aaiService = new AAIService( + AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES)); + request = new EchoRequest(); + LOG.info("\nEchoRequestTest.setUp\n"); + } + + @AfterClass + public static void tearDown() throws Exception { + request = null; + LOG.info("----------------------- EchoRequestTest.tearDown -----------------------"); + } + + @Test + public void runGetRequestUrlTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + URL url; + try { + url = request.getRequestUrl("GET", null); + assertNotNull(url); + } catch (UnsupportedEncodingException | MalformedURLException exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runToJSONStringTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String json = request.toJSONString(); + assertNotNull(json); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetArgsListTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String[] args = request.getArgsList(); + assertNotNull(args); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetModelTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + Class<? extends AAIDatum> clazz = request.getModelClass(); + assertNotNull(clazz); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + +// @Test + public void EchoTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + QueryStatus resp = null; + +// (String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) + resp = aaiService.query("echo", false, null, "", "aaidata", null, ctx); + assert(resp == QueryStatus.SUCCESS); + } + catch (Throwable e) + { + LOG.error("Caught exception", e); +// fail("Caught exception"); + } + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/GenericRequestTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/GenericRequestTest.java new file mode 100755 index 000000000..3ce8a6dc5 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/GenericRequestTest.java @@ -0,0 +1,190 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.aai.inventory.v21.LInterface; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class GenericRequestTest { + + private static final Logger LOG = LoggerFactory.getLogger(GenericRequestTest.class); + + protected static AAIClient client; + protected static AAIRequest request; + + @BeforeClass + public static void setUp() throws Exception { + URL url = AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES); + client = new AAIService(url); + request = AAIRequest.createRequest("generic-vnf", new HashMap<String, String>()); + LOG.info("\nTaicAAIResourceTest.setUp\n"); + } + + @AfterClass + public static void tearDown() throws Exception { + client = null; + LOG.info("----------------------- AAIResourceTest.tearDown -----------------------"); + } + + @Test + public void test001() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + Map<String, String> key = new HashMap<String, String>(); + AAIRequest request = AAIRequest.createRequest("vserver", key); + key.put("vserver.vserver_id", "e8faf166-2402-4ae2-be45-067954c63aed"); + key.put("tenant.tenant_id", "1863027683132547"); + request.processRequestPathValues(key); + String uri = request.getTargetUri(); + + assertNotNull(uri); + + } + catch (Exception e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + @Test + public void test002() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + try + { + URL resource = this.getClass().getResource("json/linterfaceJson.txt"); + + LOG.info("Resource is " + resource.getFile()); + File requestFile = new File(resource.getFile()); + if(!requestFile.exists()) { + fail("Test file does not exist"); + } + + ObjectMapper mapper = AAIService.getObjectMapper(); + LInterface request = mapper.readValue(requestFile, LInterface.class); + String vnf_id = request.getInterfaceName(); + LOG.info(vnf_id); + + } + catch (Exception e) + { + LOG.error("Caught exception", e); + } + } + +// @Test +// public void test003() { +// LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); +// try +// { +// String vnf_id = "4718302b-7884-4959-a499-f470c62418ff"; +// +// GenericVnf genericVnf = client.requestGenericVnfData(vnf_id); +// +// client.deleteGenericVnfData(vnf_id, genericVnf.getResourceVersion()); +// +// } +// catch (Throwable e) +// { +// LOG.error("Caught exception", e); +// } +// } + + + @Test + public void test004() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + URL url; + try { + url = request.getRequestUrl("GET", null); + assertNotNull(url); + } catch (UnsupportedEncodingException | MalformedURLException | URISyntaxException exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runToJSONStringTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String json = request.toJSONString(); + assertNotNull(json); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetArgsListTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String[] args = request.getArgsList(); + assertNotNull(args); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetModelTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + Class<? extends AAIDatum> clazz = request.getModelClass(); + assertNotNull(clazz); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/GenericVnfRequestTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/GenericVnfRequestTest.java new file mode 100644 index 000000000..062e02d1f --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/GenericVnfRequestTest.java @@ -0,0 +1,117 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertNotNull; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class GenericVnfRequestTest { + + private static final Logger LOG = LoggerFactory.getLogger(GenericVnfRequestTest.class); + + private static AAIRequest request; + private static AAIService aaiService; + + @BeforeClass + public static void setUp() throws Exception { + aaiService = new AAIService(AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES)); + Map<String, String> nameValues = new HashMap<>(); + nameValues.put("generic-vnf.vnf-id", "vnf-001"); + request = AAIRequest.createRequest("generic-vnf", nameValues); + LOG.info("\nEchoRequestTest.setUp\n"); + } + + @AfterClass + public static void tearDown() throws Exception { + request = null; + LOG.info("----------------------- EchoRequestTest.tearDown -----------------------"); + } + + @Test + public void runGetRequestUrlTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + URL url; + try { + url = request.getRequestUrl("GET", null); + assertNotNull(url); + } catch (UnsupportedEncodingException | MalformedURLException | URISyntaxException exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runToJSONStringTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String json = request.toJSONString(); + assertNotNull(json); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetArgsListTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String[] args = request.getArgsList(); + assertNotNull(args); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetModelTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + Class<? extends AAIDatum> clazz = request.getModelClass(); + assertNotNull(clazz); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/GenericVnfTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/GenericVnfTest.java new file mode 100755 index 000000000..5a594298f --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/GenericVnfTest.java @@ -0,0 +1,243 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 - 2018 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.lang.StringUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.aai.AAIClient; +import org.onap.ccsdk.sli.adaptors.aai.AAIRequest; +import org.onap.ccsdk.sli.adaptors.aai.AAIService; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.onap.aai.inventory.v21.GenericVnf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class GenericVnfTest { + + private static final Logger LOG = LoggerFactory.getLogger(GenericVnfTest.class); + + protected static AAIClient client; + + @BeforeClass + public static void setUp() throws Exception { + Properties properties = new Properties(); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore", "true"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.client.name", "SDNC"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.client.psswd", "SDNC"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.application", "CCSDK"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.uri", "http://localhost:8181"); + properties.setProperty("connection.timeout", "60000"); + properties.setProperty("read.timeout", "60000"); + client = new AAIService(properties); + ((AAIService)client).setExecutor(new TestExecutor()); + LOG.info("\nTaicAAIResourceTest.setUp\n"); + } + + @AfterClass + public static void tearDown() throws Exception { + client = null; + LOG.info("----------------------- GenericVnfTest.tearDown -----------------------"); + } + + + @Test + public void test01SaveGenericVnf() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + String uuid = UUID.randomUUID().toString(); + Map<String, String> data = new HashMap<String, String>(); + data.put("vnf-id", uuid); + data.put("vnf-name" , "Demo-vmtn5scpx01"); + data.put("vnf-type", "asc_heat-int"); + data.put("service-id", "SDN-MOBILITY"); + data.put("equipment-role", "vSCP"); + data.put("orchestration-status", "active"); + data.put("heat-stack-id", "Devmtn5scpx04/" + data.get("vnf-id")); + data.put("in-maint", "false"); + data.put("is-closed-loop-disabled", "false"); + data.put("encrypted-access-flag","true"); + + QueryStatus resp = client.save("generic-vnf", false, false, "generic-vnf.vnf-id = '"+uuid+"'", data, "aaidata", ctx); + assertNotNull(ctx); + + } + catch (Throwable e) + { + + } + ; + } + + @Test + public void test02QueryGenericVnf() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + List<String> keys = new ArrayList<String>(); + keys.add("vnf-id = 'ec14a84d-7b43-45ad-bb04-c12b74083648'"); + keys.add("depth = 'all'"); + + SvcLogicContext ctx = new SvcLogicContext(); + QueryStatus response = client.query("generic-vnf", false, null, StringUtils.join(keys, " AND "), "aaiTest", null, ctx); + + assertTrue(response == QueryStatus.SUCCESS); + LOG.info("AAIResponse: " + response.toString()); + } + catch (Exception e) { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + @Test + public void test03UpdateGenericVnf() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + String uuid = UUID.randomUUID().toString(); + Map<String, String> data = new HashMap<String, String>(); + data.put("service-id", "SDN-MOBILITY"); + data.put("equipment-role", "vSCP"); + data.put("orchestration-status", "active"); + data.put("heat-stack-id", "Devmtn5scpx04/" + data.get("vnf-id")); + data.put("in-maint", "false"); + data.put("is-closed-loop-disabled", "false"); + data.put("encrypted-access-flag","true"); + + QueryStatus resp = client.update("generic-vnf", "generic-vnf.vnf-id = '"+uuid+"'", data, "aaidata", ctx); + assertNotNull(uuid); + } + catch (Throwable e) + { + + } + } + + @Test + public void test04DeleteGenericVnf() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + List<String> keys = new ArrayList<String>(); + keys.add("generic-vnf.vnf-id = 'VNF-S7'"); + + QueryStatus response = client.delete("generic-vnf", StringUtils.join(keys, " AND "), ctx); + + assertTrue(response == QueryStatus.SUCCESS); + LOG.info("AAIResponse: " + response.toString()); + } + catch (Exception e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + @Test + public void test05GetResource() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + GenericVnf response = ((AAIService)client).getResource("/network/generic-vnfs/generic-vnf/ec14a84d-7b43-45ad-bb04-c12b74083648", GenericVnf.class); + + assertNotNull(response); + } + catch (Exception e) + { + + } + } + + static class TestExecutor implements AAIExecutorInterface { + private String data = "{\"vnf-id\":\"7324200933\",\"vnf-name\":\"vnfinst1m001\",\"vnf-type\":\"TestVnf\",\"service-id\":\"9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"equipment-role\":\"vTEST\",\"orchestration-status\":\"active\",\"in-maint\":false,\"is-closed-loop-disabled\":false,\"resource-version\":\"1520720941585\"}"; + + @Override + public String get(AAIRequest request) throws AAIServiceException { + return data; + } + + @Override + public String post(AAIRequest request) throws AAIServiceException { + return "success"; + } + + @Override + public Boolean delete(AAIRequest request, String resourceVersion) throws AAIServiceException { + return Boolean.TRUE; + } + + @Override + public Object query(AAIRequest request, Class clas) throws AAIServiceException { + ObjectMapper mapper = AAIService.getObjectMapper(); + try { + return mapper.readValue(data, GenericVnf.class); + } catch (IOException e) { + return new GenericVnf(); + } + } + + @Override + public Boolean patch(AAIRequest request, String resourceVersion) throws AAIServiceException { + return Boolean.TRUE; + } + + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/NodesQueryRequestTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/NodesQueryRequestTest.java new file mode 100644 index 000000000..e52f1de04 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/NodesQueryRequestTest.java @@ -0,0 +1,88 @@ +package org.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertNotNull; + +import java.net.URL; +import java.util.Properties; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NodesQueryRequestTest { + + private static final Logger LOG = LoggerFactory.getLogger(NodesQueryRequestTest.class); + + private static NodesQueryRequest request; + + @BeforeClass + public static void setUp() throws Exception { + Properties properties = new Properties(); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore", "true"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.client.name", "SDNC"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.client.psswd", "SDNC"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.application", "CCSDK"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.uri", "http://localhost:8181"); + properties.setProperty("connection.timeout", "60000"); + properties.setProperty("read.timeout", "60000"); + properties.setProperty("org.onap.ccsdk.sli.adaptors.aai.query.nodes","/aai/v11/search/nodes-query?search-node-type={node-type}&filter={entity-identifier}:EQUALS:{entity-name}"); + + AAIRequest.configProperties = properties; + request = new NodesQueryRequest(); + LOG.info("\nEchoRequestTest.setUp\n"); + } + + @Test + public void runGetRequestUrlTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + URL url = request.getRequestUrl("GET", null); + assertNotNull(url); + } catch (Exception exc) { + } + assert(true); + + } + + @Test + public void runToJSONStringTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String json = request.toJSONString(); + assertNotNull(json); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetArgsListTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String[] args = request.getArgsList(); + assertNotNull(args); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetModelTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + Class<? extends AAIDatum> clazz = request.getModelClass(); + assertNotNull(clazz); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/PathCreationTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/PathCreationTest.java new file mode 100755 index 000000000..098414fd9 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/PathCreationTest.java @@ -0,0 +1,204 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 - 2018 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.fail; +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.io.FileReader; +import java.net.URL; +import java.util.Arrays; +import java.util.BitSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.ListIterator; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.commons.lang3.StringUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.aai.AAIRequest; +import org.onap.ccsdk.sli.adaptors.aai.AAIService; +import org.onap.ccsdk.sli.adaptors.aai.AAIServiceUtils; +import org.onap.ccsdk.sli.adaptors.aai.EchoRequest; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class PathCreationTest { + + private static final Logger LOG = LoggerFactory.getLogger(PathCreationTest.class); + + private static AAIService aaiService; + + @BeforeClass + public static void setUp() throws Exception { + aaiService = new AAIService( + AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES)); + LOG.info("\nTaicAAIResourceTest.setUp\n"); + } + + @AfterClass + public static void tearDown() throws Exception { + LOG.info("----------------------- AAIResourceTest.tearDown -----------------------"); + } + + static Set<String> resourceNames = new TreeSet<String>(); + static Map<String, String> tagValues = new LinkedHashMap<String, String>(); + + + @Test + public void test01() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + File file = new File(this.getClass().getResource("/aai-path.properties").getFile()); + if(!file.exists()) { + fail("File does not exist"); + return; + } + FileReader reader = new FileReader(file); + + Properties properties = new Properties(); + properties.load(reader); + LOG.info("loaded " + properties.size()); + + Set<String> keys = properties.stringPropertyNames(); + + int index = 0; + + for(String key : keys) { + String[] tags = key.split("\\|"); + for(String tag : tags) { + if(!resourceNames.contains(tag)) { + resourceNames.add(tag); + tagValues.put(tag, Integer.toString(++index)); + } + } + BitSet bs = new BitSet(256); + for(String tag : tags) { + String value = tagValues.get(tag); + Integer bitIndex = Integer.parseInt(value) ; + bs.set(bitIndex); + } + String path = properties.getProperty(key); + LOG.info(String.format("bitset %s\t\t%s", bs.toString(), path)); + } + } + catch (Exception e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + @Test + public void test02() { + try { + Map<String, String> nameValues = new HashMap<String, String> (); + nameValues.put("pserver.hostname", "USAUTOUFTIL0205UJZZ01"); + + AAIRequest request = AAIRequest.createRequest("pserver", nameValues); + request.addRequestProperty("pserver.hostname", "USAUTOUFTIL0205UJZZ01"); + + URL url = request.getRequestUrl("GET", null); + url.getPath(); + LOG.info("Received response"); + assertNotNull(nameValues); + + } catch(Exception exc) { + LOG.info("Caught exception", exc); + } + } + + @Test + public void test03() { + HashMap<String, String> nameValues = new HashMap<String, String>(); + + String path = +// "/aai/v11/network/site-pair-sets/site-pair-set/a3839637-575e-49b3-abb7-a003b0d4cc35/routing-instances/routing-instance/7f08a85e-716f-4bc2-a4f4-70801b07a5e6"; + "/aai/v10/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25"; + + String[] split = path.split("/"); + + LinkedList<String> list = new LinkedList<String>( Arrays.asList(split)); + ListIterator<String> it = list.listIterator(); + +// for(String tag : split) { + while(it.hasNext()) { + String tag = it.next(); + if(!tag.isEmpty()) { + if(resourceNames.contains(tag)){ + LOG.info(tag); + // get the class from tag + Class<? extends AAIDatum> clazz = null; + try { + clazz = AAIRequest.getClassFromResource(tag); + String fieldName = AAIServiceUtils.getPrimaryIdFromClass(clazz); + int nextIndex = it.nextIndex(); + + String value = list.get(nextIndex); + if(!StringUtils.isEmpty(value)){ + nameValues.put(String.format("%s.%s", tag, fieldName), value); + switch(tag) { + case "cloud-region": + case "entitlement": + case "license": + case "route-target": + case "service-capability": + case "ctag-pool": + String secondaryFieldName = AAIServiceUtils.getSecondaryIdFromClass(clazz); + if(secondaryFieldName != null) { + value = it.next(); + nameValues.put(String.format("%s.%s", tag, secondaryFieldName), value); + } + break; + default: + break; + } + } + } catch (Exception exc) { + LOG.info("Caught exception", exc); + } + // get id from class + // read the follwoing field + // create relationship data + } + } + } + LOG.info(nameValues.toString()); + assertNotNull(nameValues); + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/RegressionTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/RegressionTest.java new file mode 100755 index 000000000..eb8dbc4a8 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/RegressionTest.java @@ -0,0 +1,422 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.lang.StringUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class RegressionTest { + + static { + System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "INFO"); +// System.setProperty(org.slf4j.impl.SimpleLogger.LOG_FILE_KEY, String.format("RegressionTest-%d.txt", System.currentTimeMillis())); + } + + private static final Logger LOG = LoggerFactory.getLogger(RegressionTest.class); + + protected static AAIService client; + + @BeforeClass + public static void setUp() throws Exception { +// super.setUp(); + URL url = AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES); + client = new AAIService(url); + LOG.info("\nTaicAAIResourceTest.setUp\n"); + } + + @AfterClass + public static void tearDown() throws Exception { +// super.tearDown(); + client = null; + LOG.info("----------------------- AAIResourceTest.tearDown -----------------------"); + } + +// @Test +// public void R1510Test05GenericVnfDataRequestDelete() { +// LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); +// try +// { +// String vnf_id = "bpsx0001v-7071"; +// boolean response = client.deleteGenericVnfData(vnf_id, null); +// assertTrue(response); +// +// } +// catch (Throwable e) +// { +// assert(true); +// } +// } + + @Test + public void R1604TestWanConnectorSave01Request() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + Map<String, String> data = new HashMap<String, String>(); + data.put("resource-instance-id", "12345"); + data.put("resource-model-uuid", "45678"); + + data.put("relationship-list.relationship[0].related-to", "service-instance"); + + data.put("relationship-list.relationship[0].relationship-data[0].relationship-key", "customer.global-customer-id"); + data.put("relationship-list.relationship[0].relationship-data[0].relationship-value", "$global-customer-id"); + + data.put("relationship-list.relationship[0].relationship-data[1].relationship-key", "service-subscription.service-type"); + data.put("relationship-list.relationship[0].relationship-data[1].relationship-value", "$service-type"); + + data.put("relationship-list.relationship[0].relationship-data[2].relationship-key", "service-instance.service-instance-id"); + data.put("relationship-list.relationship[0].relationship-data[2].relationship-value", "$serviceInstanceID"); + + + + //(String resource, boolean force, boolean localOnly, String key, Map<String, String> parms, String prefix, SvcLogicContext ctx) + QueryStatus resp = client.save("connector", false, false, "resource-instance-id = '12345'", data, "aaidata", ctx); + + LOG.info("AAIResponse: " + resp.toString()); + assertNotNull(ctx); + } + catch (Exception e) + { + assert(true); + } + } + + + @Test + public void R1604TestWanConnectorSave02Request() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + Map<String, String> data = new HashMap<String, String>(); + data.put("resource-instance-id", "11012345"); + data.put("widget-model-id", "45678"); + data.put("persona-model-version", "0.1"); + data.put("persona-model-id", "dc700a83-c507-47d9-b775-1fdfcdd5f9eb"); + data.put("relationship-list.relationship[0].relationship-data[0].relationship-key", "customer.global-customer-id"); + data.put("metadata.metadatum[0].meta-value", "100640"); + data.put("metadata.metadatum[0].meta-key", "vni"); + data.put("relationship-list.relationship[0].relationship-data[1].relationship-value", "ATT-COLLABORATE"); + data.put("relationship-list.relationship[0].relationship-data[0].relationship-value", "ds828e091614l"); + data.put("relationship-list.relationship[0].relationship-data[2].relationship-key", "service-instance.service-instance-id"); + data.put("relationship-list.relationship[0].relationship-data[1].relationship-key", "service-subscription.service-type"); + data.put("relationship-list.relationship[0].related-to", "service-instance"); + data.put("relationship-list.relationship[0].relationship-data[2].relationship-value", "1990e84d-546d-4b61-8069-e0db1318ade2"); + + + //(String resource, boolean force, boolean localOnly, String key, Map<String, String> parms, String prefix, SvcLogicContext ctx) + QueryStatus resp = client.save("connector", false, false, "resource-instance-id = '11012345'", data, "aaidata", ctx); + + LOG.info("AAIResponse: " + resp.toString()); + assertNotNull(ctx); + } + catch (Exception e) + { + assert(true); + } + } + + + @Test + public void R1604TestLogicalLinkSaveRequest() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + Map<String, String> data = new HashMap<String, String>(); + data.put("link-name" , "1252541"); + data.put("link-type" , "L2 Bridge between IPE and BorderElement"); + data.put("speed-value" , "1000"); + + data.put("speed-units" , "MBPS"); + data.put("ip-version" , "IP-V6"); + data.put("routing-protocol" , "BGP"); + data.put("resource-version" , "1.0.0"); + data.put("resource-model-uuid" , "TEST01"); + + data.put("relationship-list.relationship[0].related-to" , "virtual-data-center"); + data.put("relationship-list.relationship[0].relationship-data[0].relationship-key", "virtual-data-center.vdc-id"); + data.put("relationship-list.relationship[0].relationship-data[0].relationship-value", "dpa2_cci_att_com-1068"); + + data.put("relationship-list.relationship[1].related-to" , "generic-vnf"); + data.put("relationship-list.relationship[1].relationship-data[0].relationship-key", "generic-vnf.vnf-id"); + data.put("relationship-list.relationship[1].relationship-data[0].relationship-value" , "basx0001v-1189"); + + data.put("relationship-list.relationship[2].related-to" , "l-interface"); + data.put("relationship-list.relationship[2].relationship-data[0].relationship-key", "pserver.hostname"); + data.put("relationship-list.relationship[2].relationship-data[0].relationship-value" , "ptpbe101snd"); + + data.put("relationship-list.relationship[2].relationship-data[1].relationship-key", "lag-interface.interface-name"); + data.put("relationship-list.relationship[2].relationship-data[1].relationship-value" , "$name"); + + data.put("relationship-list.relationship[2].relationship-data[2].relationship-key", "l-interface.interface-name"); + data.put("relationship-list.relationship[2].relationship-data[2].relationship-value" , "$hostname"); + + + + //(String resource, boolean force, boolean localOnly, String key, Map<String, String> parms, String prefix, SvcLogicContext ctx) + QueryStatus resp = client.save("logical-link", false, false, "link-name = '1252541'", data, "aaidata", ctx); + + LOG.info("AAIResponse: " + resp.toString()); + assertNotNull(data); + } + catch (Exception e) + { + assert(true); + } + } + + @Test + public void R1604TestVDCISaveRequest() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + Map<String, String> data = new HashMap<String, String>(); + data.put("vdc-id" , "1252541"); + data.put("vdc-name" , "put.the.variable.of.your.data.here"); + + data.put("relationship-list.relationship[0].related-to" , "connector"); + + data.put("relationship-list.relationship[0].relationship-data[0].relationship-key" , "connector.resource-instance-id"); + data.put("relationship-list.relationship[0].relationship-data[0].relationship-value" , "$resource-instance-id"); + + + + //(String resource, boolean force, boolean localOnly, String key, Map<String, String> parms, String prefix, SvcLogicContext ctx) + QueryStatus resp = client.save("virtual-data-center", false, false, "vdc-id = '1252541'", data, "aaidata", ctx); + + LOG.info("AAIResponse: " + resp.toString()); + assertNotNull(data); + } + catch (Exception e) + { + assert(true); + } + } + +// @Test + public void R1510Test03RequestGenericVnfDataRequest() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + + QueryStatus response = client.query("generic-vnf:relationship-list", false, null, "vnf-id = '34e94596-bdfa-411d-a664-16dea8583139' AND related-to = 'l3-network' ", "aaiTest", null, ctx); +// QueryStatus response = client.delete("generic-vnf:relationship-list", "vnf-id = '34e94596-bdfa-411d-a664-16dea8583139' AND related-to = 'pserver' ", ctx); + + assertTrue(response == QueryStatus.SUCCESS); + LOG.info("AAIResponse: " + response.toString()); + } + catch (Exception e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + @Test + public void R1510Test03RequestVserverDataRequest() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + QueryStatus response = client.query("vserver", false, null, + "vserver.vserver-id = 'FRNKGEFF1' AND depth = 'all' AND cloud-region.cloud-owner = 'att-aic' AND tenant.tenant-id = '1710vPEPROJECTS::297135PROJECT' AND cloud-region.cloud-region-id = 'FRN1'" + , "aaiTest", null, ctx); + + assertNotNull(response); + } + catch (Exception e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + +// @Test + public void R1510Test03UpdateVserverDataRequest() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + Properties prop = new Properties(); + String propFileName = "vserver-issue.txt"; + + InputStream inputStream = getClass().getClassLoader().getResourceAsStream(propFileName); + + if (inputStream != null) { + prop.load(inputStream); + } else { + throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath"); + } + + + SvcLogicContext ctx = new SvcLogicContext(); + + Map<String, String> data = new HashMap<String, String>(); + + Enumeration keys = prop.keys(); + while(keys.hasMoreElements()) { + String key = keys.nextElement().toString(); + String value = prop.getProperty(key); + data.put(key, value); + } + + QueryStatus response = client.update("vserver", "vserver-id = '59567c27-706e-4f41-953f-b5d3a525812f' AND tenant-id = 'USITUCAB3NJ0101UJZZ01::uCPE-VMS'", data, "aaiTest", ctx); + + assertTrue(response == QueryStatus.SUCCESS); + LOG.info("AAIResponse: " + response.toString()); + } + catch (Exception e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + +// @Test + public void R1510Test03RequestVCloudRegionDataRequest() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); +// QueryStatus response = client.query("vserver", false, null, "tenant-id = '3220171995171220' AND vserver-id = '4b491df8-cf0e-4f08-88a2-133e82b63432'", "aaiTest", null, ctx); +// QueryStatus response = client.query("vserver", false, null, "vserver-name = 'bpsx0001vm001bps001'", "aaiTest", null, ctx); + QueryStatus response = client.query("cloud-region", false, null, + "depth = '0' AND cloud-region.cloud-owner = 'att-aic' AND cloud-region.cloud-region-id = 'mtn6'" + , "aaiTest", null, ctx); + + assertTrue(response == QueryStatus.SUCCESS); + LOG.info("AAIResponse: " + response.toString()); + } + catch (Exception e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + +// @Test + public void R1510Test03RequestVCloudRegionData1Request() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + List<String> data = new LinkedList<String>(); + data.add("depth = 0"); + data.add("cloud-region.cloud-owner = 'att-aic'"); + data.add("cloud-region.cloud-region-id = 'mtn6'"); + + + SvcLogicContext ctx = new SvcLogicContext(); + QueryStatus response = client.query("cloud-region", false, null, StringUtils.join(data, " AND ") +// "depth = '0' AND cloud-region.cloud-owner = 'att-aic' AND cloud-region.cloud-region-id = 'mtn6'" + , "aaiTest", null, ctx); + + assertTrue(response == QueryStatus.SUCCESS); + LOG.info("AAIResponse: " + response.toString()); + } + catch (Exception e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + @Test + public void R1510Test03RequestVCloudRegionData2Request() + { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try + { + Map<String, String> nameValues = new HashMap<String, String>(); + nameValues.put("depth","0"); + nameValues.put("cloud-region.cloud-owner", "att-aic"); + nameValues.put("cloud-region.cloud-region-id","mtn6"); + + AAIRequest request = AAIRequest.createRequest("cloud-region", nameValues); + + for(String key : nameValues.keySet()) { + request.addRequestProperty(key, nameValues.get(key).toString()); + } + + String response = client.query(request); + AAIDatum datum = request.jsonStringToObject(response); + +// assertTrue(response == QueryStatus.SUCCESS); + LOG.info("AAIResponse: " + datum.toString()); + assertNotNull(nameValues); + } + catch (Exception e) + { + LOG.error("Caught exception", e); + } + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/RelationshipRequestTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/RelationshipRequestTest.java new file mode 100644 index 000000000..858c9c599 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/RelationshipRequestTest.java @@ -0,0 +1,118 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertNotNull; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class RelationshipRequestTest { + + private static final Logger LOG = LoggerFactory.getLogger(RelationshipRequestTest.class); + + private static AAIRequest request; + private static AAIService aaiService; + + @BeforeClass + public static void setUp() throws Exception { + aaiService = new AAIService(AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES)); + Map<String, String> nameValues = new HashMap<>(); + nameValues.put("generic-vnf.vnf-id", "vnf-001"); + AAIRequest tmpReq = AAIRequest.createRequest("generic-vnf", nameValues); + request = new RelationshipRequest(tmpReq); + LOG.info("\nEchoRequestTest.setUp\n"); + } + + @AfterClass + public static void tearDown() throws Exception { + request = null; + LOG.info("----------------------- EchoRequestTest.tearDown -----------------------"); + } + + @Test + public void runGetRequestUrlTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + URL url; + try { + url = request.getRequestUrl("GET", null); + assertNotNull(url); + } catch (UnsupportedEncodingException | MalformedURLException | URISyntaxException exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runToJSONStringTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String json = request.toJSONString(); + assertNotNull(json); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetArgsListTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + String[] args = request.getArgsList(); + assertNotNull(args); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } + + @Test + public void runGetModelTest() { + LOG.info("----------------------- Test: " + new Object(){}.getClass().getEnclosingMethod().getName() + " -----------------------"); + + try { + Class<? extends AAIDatum> clazz = request.getModelClass(); + assertNotNull(clazz); + } catch (Exception exc) { + LOG.error("Failed test", exc); + } + + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/RequestPathTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/RequestPathTest.java new file mode 100755 index 000000000..5ee35c647 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/RequestPathTest.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 - 2018 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.onap.ccsdk.sli.adaptors.aai; + +import static org.junit.Assert.assertNotNull; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class RequestPathTest { + + private static final Logger LOG = LoggerFactory.getLogger(RequestPathTest.class); + + protected static AAIClient client; + + @BeforeClass + public static void setUp() throws Exception { + URL url = AAIService.class.getResource(AAIService.AAICLIENT_PROPERTIES); + client = new AAIService(url); + LOG.info("\nTaicAAIResourceTest.setUp\n"); + } + + @AfterClass + public static void tearDown() throws Exception { + client = null; + LOG.info("----------------------- AAIResourceTest.tearDown -----------------------"); + } + + @Test + public void getRequestUrl() { + try { + Map<String, String> nameValues = new HashMap<String, String> (); + nameValues.put("generic-vnf.vnf-id","AABBCCDDEEFFGG0123"); + + AAIRequest request = AAIRequest.createRequest("service-instances", nameValues); + request.addRequestProperty("generic-vnf.vnf-id","AABBCCDDEEFFGG0123"); + + URL url = request.getRequestUrl("GET", null); + assertNotNull(url); + url.getPath(); + LOG.info("Received response"); + } catch(Exception exc) { + LOG.info("Caught exception", exc); + } + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ErrorResponseTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ErrorResponseTest.java new file mode 100644 index 000000000..6232ae34a --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ErrorResponseTest.java @@ -0,0 +1,51 @@ +package org.onap.ccsdk.sli.adaptors.aai.data; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ErrorResponseTest { + + ErrorResponse _erInstance; + protected RequestError _requestError; + protected Map<String, Object> _additionalProperties; + + @Before + public void setUp() throws Exception { + _erInstance = new ErrorResponse(); + _requestError = mock(RequestError.class); + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _erInstance = null; + _requestError = null; + _additionalProperties = null; + } + + @Test + public void testSetRequestError() { + _erInstance.setRequestError(_requestError); + assertEquals(_erInstance.getRequestError(), _requestError); + } + + @Test + public void testSetAdditionalProperty() { + _erInstance.setAdditionalProperty("prop1", "propvalue1"); + _erInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_erInstance.getAdditionalProperties(), _additionalProperties); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/RequestErrorTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/RequestErrorTest.java new file mode 100644 index 000000000..c752c7656 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/RequestErrorTest.java @@ -0,0 +1,51 @@ +package org.onap.ccsdk.sli.adaptors.aai.data; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class RequestErrorTest { + + RequestError _reInstance; + protected ServiceException _serviceException; + protected Map<String, Object> _additionalProperties; + + @Before + public void setUp() throws Exception { + _reInstance = new RequestError(); + _serviceException = mock(ServiceException.class); + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _reInstance = null; + _serviceException = null; + _additionalProperties = null; + } + + @Test + public void testSetServiceException() { + _reInstance.setServiceException(_serviceException); + assertEquals(_reInstance.getServiceException(), _serviceException); + } + + @Test + public void testSetAdditionalProperty() { + _reInstance.setAdditionalProperty("prop1", "propvalue1"); + _reInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_reInstance.getAdditionalProperties(), _additionalProperties); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessageTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessageTest.java new file mode 100644 index 000000000..daf95b02d --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessageTest.java @@ -0,0 +1,68 @@ +package org.onap.ccsdk.sli.adaptors.aai.data; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ResponseMessageTest { + + ResponseMessage _rmInstance; + protected String _messageId; + protected String _text; + protected Variables _variables; + protected Map<String, Object> _additionalProperties; + + @Before + public void setUp() throws Exception { + _rmInstance = new ResponseMessage(); + _messageId = "messageId"; + _text = "text"; + _variables = mock(Variables.class); + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _rmInstance = null; + _messageId = null; + _text = null; + _variables = null; + _additionalProperties = null; + } + + @Test + public void testSetMessageId() { + _rmInstance.setMessageId(_messageId); + assertTrue(_rmInstance.getMessageId().equals(_messageId)); + } + + @Test + public void testSetText() { + _rmInstance.setText(_text); + assertTrue(_rmInstance.getText().equals(_text)); + } + + @Test + public void testSetVariables() { + _rmInstance.setVariables(_variables); + assertEquals(_rmInstance.getVariables(), _variables); + } + + @Test + public void testSetAdditionalProperty() { + _rmInstance.setAdditionalProperty("prop1", "propvalue1"); + _rmInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_rmInstance.getAdditionalProperties(), _additionalProperties); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessagesTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessagesTest.java new file mode 100644 index 000000000..f21e969dd --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ResponseMessagesTest.java @@ -0,0 +1,55 @@ +package org.onap.ccsdk.sli.adaptors.aai.data; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ResponseMessagesTest { + + ResponseMessages _rmsInstance; + protected List<ResponseMessage> _responseMessage; + protected Map<String, Object> _additionalProperties; + + @Before + public void setUp() throws Exception { + _rmsInstance = new ResponseMessages(); + _responseMessage = new ArrayList<>(); + ResponseMessage rm1 = mock(ResponseMessage.class); + ResponseMessage rm2 = mock(ResponseMessage.class); + _responseMessage.add(rm1); + _responseMessage.add(rm2); + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _rmsInstance = null; + _responseMessage = null; + _additionalProperties = null; + } + + @Test + public void testSetResponseMessage() { + _rmsInstance.setResponseMessage(_responseMessage); + assertEquals(_rmsInstance.getResponseMessage(), _responseMessage); + } + + @Test + public void testSetAdditionalProperty() { + _rmsInstance.setAdditionalProperty("prop1", "propvalue1"); + _rmsInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_rmsInstance.getAdditionalProperties(), _additionalProperties); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ServiceExceptionTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ServiceExceptionTest.java new file mode 100644 index 000000000..f44d9b366 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/ServiceExceptionTest.java @@ -0,0 +1,71 @@ +package org.onap.ccsdk.sli.adaptors.aai.data;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ServiceExceptionTest {
+
+ ServiceException _seInstance;
+ protected String _messageId;
+ protected String _text;
+ protected List<String> _variables;
+ protected Map<String, Object> _additionalProperties;
+
+ @Before
+ public void setUp() throws Exception {
+ _seInstance = new ServiceException();
+ _messageId = "messageId";
+ _text = "text";
+ _variables = new ArrayList<>(Arrays.asList("var1", "var2", "var3"));
+ _additionalProperties = new HashMap<String, Object>() {{
+ put("prop1", "propvalue1");
+ put("prop2", "propvalue2");
+ }};
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ _seInstance = null;
+ _messageId = null;
+ _text = null;
+ _variables = null;
+ _additionalProperties = null;
+ }
+
+ @Test
+ public void testSetMessageId() {
+ _seInstance.setMessageId(_messageId);
+ assertTrue(_seInstance.getMessageId().equals(_messageId));
+ }
+
+ @Test
+ public void testSetText() {
+ _seInstance.setText(_text);
+ assertTrue(_seInstance.getText().equals(_text));
+ }
+
+ @Test
+ public void testSetVariables() {
+ _seInstance.setVariables(_variables);
+ assertEquals(_seInstance.getVariables(), _variables);
+ }
+
+ @Test
+ public void testSetAdditionalProperties() {
+ _seInstance.setAdditionalProperty("prop1", "propvalue1");
+ _seInstance.setAdditionalProperty("prop2", "propvalue2");
+ assertEquals(_seInstance.getAdditionalProperties(), _additionalProperties);
+ }
+
+
+}
diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/SubInterfaceTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/SubInterfaceTest.java new file mode 100644 index 000000000..7975372be --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/SubInterfaceTest.java @@ -0,0 +1,94 @@ +package org.onap.ccsdk.sli.adaptors.aai.data; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.aai.inventory.v21.RelationshipList; +import org.onap.aai.inventory.v21.Vlans; + +public class SubInterfaceTest { + + SubInterface _siInstance; + protected String _interfaceName; + protected String _interfaceRole; + protected String _resourceVersion; + protected Vlans _vlans; + protected RelationshipList _relationshipList; + protected Map<String, Object> _additionalProperties; + + @Before + public void setUp() throws Exception { + _siInstance = new SubInterface(); + _interfaceName = "interfaceName"; + _interfaceRole = "interfaceRole"; + _resourceVersion = "resourceVersion"; + _vlans = mock(Vlans.class); + _relationshipList = mock(RelationshipList.class); + + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + + } + + @After + public void tearDown() throws Exception { + _siInstance = null; + _interfaceName = null; + _interfaceRole = null; + _resourceVersion = null; + _vlans = null; + _relationshipList = null; + _additionalProperties = null; + } + + @Test + public void testSetInterfaceName() { + _siInstance.setInterfaceName(_interfaceName); + assertTrue(_siInstance.getInterfaceName().equals(_interfaceName)); + } + + + @Test + public void testSetInterfaceRole() { + _siInstance.setInterfaceRole(_interfaceRole); + assertTrue(_siInstance.getInterfaceRole().equals(_interfaceRole)); + } + + + @Test + public void testSetResourceVersion() { + _siInstance.setResourceVersion(_resourceVersion); + assertTrue(_siInstance.getResourceVersion().equals(_resourceVersion)); + } + + + @Test + public void testSetVlans() { + _siInstance.setVlans(_vlans); + assertTrue(_siInstance.getVlans().equals(_vlans)); + } + + + @Test + public void testSetRelationshipList() { + _siInstance.setRelationshipList(_relationshipList); + assertTrue(_siInstance.getRelationshipList().equals(_relationshipList)); + } + + @Test + public void testSetAdditionalProperties() { + _siInstance.setAdditionalProperty("prop1", "propvalue1"); + _siInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_siInstance.getAdditionalProperties(), _additionalProperties); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/VariablesTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/VariablesTest.java new file mode 100644 index 000000000..1f72f7e67 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/VariablesTest.java @@ -0,0 +1,56 @@ +package org.onap.ccsdk.sli.adaptors.aai.data;
+
+import static org.junit.Assert.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import java.util.ArrayList;
+
+public class VariablesTest {
+ Variables _variablesInstance;
+ protected List<String> _variable;
+ protected Map<String, Object> _additionalProperties;
+
+ public VariablesTest() {
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ _variablesInstance = new Variables();
+ _variable = new ArrayList<>(Arrays.asList("var1", "var2", "var3"));
+ _additionalProperties = new HashMap<String, Object>() {{
+ put("prop1", "propvalue1");
+ put("prop2", "propvalue2");
+ }};
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ _variablesInstance = null;
+ _variable = null;
+ _additionalProperties = null;
+ }
+
+
+ @Test
+ public void testSetVariable() {
+ _variablesInstance.setVariable(_variable);
+ assertEquals(_variablesInstance.getVariable(), _variable);
+ }
+
+ @Test
+ public void testSetAdditionalProperties() {
+ _variablesInstance.setAdditionalProperty("prop1", "propvalue1");
+ _variablesInstance.setAdditionalProperty("prop2", "propvalue2");
+ assertEquals(_variablesInstance.getAdditionalProperties(), _additionalProperties);
+ }
+
+}
diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/KeyDatumTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/KeyDatumTest.java new file mode 100644 index 000000000..2ea915213 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/KeyDatumTest.java @@ -0,0 +1,38 @@ +package org.onap.ccsdk.sli.adaptors.aai.data.notify; + +import static org.junit.Assert.*; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class KeyDatumTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Test + public void testSetKeyName() { + String testString = "test-value"; + KeyDatum event = new KeyDatum(); + event.setKeyName(testString); + assertEquals(event.getKeyName(), testString); + } + + @Test + public void testSetKeyValue() { + String testString = "test-value"; + KeyDatum event = new KeyDatum(); + event.setKeyValue(testString); + assertEquals(event.getKeyValue(), testString); + } + + @Test + public void testSetAdditionalProperty() { + String testString = "test-value"; + KeyDatum event = new KeyDatum(); + event.setAdditionalProperty("test-key", testString); + assertEquals(event.getAdditionalProperties().get("test-key"), testString); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/NotifyEventTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/NotifyEventTest.java new file mode 100644 index 000000000..cb026c001 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/data/notify/NotifyEventTest.java @@ -0,0 +1,53 @@ +package org.onap.ccsdk.sli.adaptors.aai.data.notify; + +import static org.junit.Assert.*; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class NotifyEventTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Test + public void test01() { + String testString = "test-value"; + NotifyEvent event = new NotifyEvent(); + event.setAdditionalProperty("test-key", testString); + assertEquals(event.getAdditionalProperties().get("test-key"), testString); + } + + @Test + public void test02() { + String testString = "test-value"; + NotifyEvent event = new NotifyEvent(); + event.setSelflink(testString); + assertEquals(event.getSelflink(), testString); + } + + @Test + public void test03() { + String testString = "test-value"; + NotifyEvent event = new NotifyEvent(); + event.setEventId(testString); + assertEquals(event.getEventId(), testString); + } + + @Test + public void test04() { + String testString = "test-value"; + NotifyEvent event = new NotifyEvent(); + event.setEventTrigger(testString); + assertEquals(event.getEventTrigger(), testString); + } + + @Test + public void test05() { + String testString = "test-value"; + NotifyEvent event = new NotifyEvent(); + event.setNodeType(testString); + assertEquals(event.getNodeType(), testString); + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryRequestDataTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryRequestDataTest.java new file mode 100644 index 000000000..a89dbded6 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryRequestDataTest.java @@ -0,0 +1,53 @@ +package org.onap.ccsdk.sli.adaptors.aai.query; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.aai.data.Variables; + +public class FormattedQueryRequestDataTest { + + FormattedQueryRequestData _fqrdInstance; + protected List<String> _start; + protected String _query; + + @Before + public void setUp() throws Exception { + _fqrdInstance = new FormattedQueryRequestData(); + _start = new ArrayList<>(Arrays.asList("start1", "start2", "start3")); + _query = "query"; + } + + @After + public void tearDown() throws Exception { + _fqrdInstance = null; + _start = null; + _query = null; + } + + @Test + public void testSetStart() { + _fqrdInstance.setStart(_start); + assertEquals(_fqrdInstance.getStart(), _start); + } + + @Test + public void testSetQuery() { + _fqrdInstance.setQuery(_query); + assertEquals(_fqrdInstance.getQuery(), _query); + } + + @Test + public void testToString() { + _fqrdInstance.setStart(_start); + _fqrdInstance.setQuery(_query); + assertNotNull(_fqrdInstance.toString()); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryResultListTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryResultListTest.java new file mode 100644 index 000000000..f26051917 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/FormattedQueryResultListTest.java @@ -0,0 +1,49 @@ +package org.onap.ccsdk.sli.adaptors.aai.query; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import java.util.ArrayList;
+
+public class FormattedQueryResultListTest {
+ FormattedQueryResultList _fqrlInstance;
+ protected List<Result> _results;
+
+ @Before
+ public void setUp() throws Exception {
+ _fqrlInstance = new FormattedQueryResultList(); + _results = new ArrayList<>(); + Result r1 = mock(Result.class); + Result r2 = mock(Result.class); + _results.add(r1); + _results.add(r2);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ _fqrlInstance = null;
+ _results = null;
+ }
+
+
+ @Test
+ public void testSetResults() {
+ _fqrlInstance.setResults(_results);
+ assertEquals(_fqrlInstance.getResults(), _results);
+ }
+
+ @Test
+ public void testToString() { + _fqrlInstance.setResults(_results); + assertTrue(_fqrlInstance.toString() != null);
+ }
+
+}
diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFilterTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFilterTest.java new file mode 100644 index 000000000..7a81f72cb --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFilterTest.java @@ -0,0 +1,124 @@ +package org.onap.ccsdk.sli.adaptors.aai.query; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.aai.inventory.v21.CloudRegion; +import org.onap.aai.inventory.v21.GenericVnf; +import org.onap.aai.inventory.v21.L3Network; +import org.onap.aai.inventory.v21.LogicalLink; +import org.onap.aai.inventory.v21.PInterface; +import org.onap.aai.inventory.v21.Pnf; +import org.onap.aai.inventory.v21.ServiceInstance; +import org.onap.aai.inventory.v21.Tenant; +import org.onap.aai.inventory.v21.Vnf; +import org.onap.aai.inventory.v21.Vserver; + +public class InstanceFilterTest { + + InstanceFilter _ifInstance; + protected LogicalLink _logicalLink; + protected Pnf _pnf; + protected L3Network _l3Network; + protected PInterface _pInterface; + protected GenericVnf _genericVnf; + protected Vserver _vserver; + protected Tenant _tenant; + protected CloudRegion _cloudRegion; + protected ServiceInstance _serviceInstance; + protected Vnf _vnfc; + protected Map<String, Object> _additionalProperties; + + @Before + public void setUp() throws Exception { + _ifInstance = new InstanceFilter(); + LogicalLink _logicalLink = mock(LogicalLink.class); + Pnf _pnf = mock(Pnf.class); + L3Network _l3Network = mock(L3Network.class); + PInterface _pInterface = mock(PInterface.class); + GenericVnf _genericVnf = mock(GenericVnf.class); + Vserver _vserver = mock(Vserver.class); + Tenant _tenant = mock(Tenant.class); + CloudRegion _cloudRegion = mock(CloudRegion.class); + ServiceInstance _serviceInstance = mock(ServiceInstance.class); + // as per class + Vnf _vnfc = mock(Vnf.class); + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _ifInstance = null; + _additionalProperties = null; + } + + @Test + public void testSetLogicalLink() { + _ifInstance.setLogicalLink(_logicalLink); + assertEquals(_ifInstance.getLogicalLink(), _logicalLink); + } + + @Test + public void testSetPnf() { + _ifInstance.setPnf(_pnf); + assertEquals(_ifInstance.getPnf(), _pnf); + } + + @Test + public void testSetL3Network() { + _ifInstance.setL3Network(_l3Network); + assertEquals(_ifInstance.getL3Network(), _l3Network); + } + + @Test + public void testSetServiceInstance() { + _ifInstance.setServiceInstance(_serviceInstance); + assertEquals(_ifInstance.getServiceInstance(), _serviceInstance); + } + + @Test + public void testSetGenericVnf() { + _ifInstance.setGenericVnf(_genericVnf); + assertEquals(_ifInstance.getGenericVnf(), _genericVnf); + } + + @Test + public void testSetVserver() { + _ifInstance.setVserver(_vserver); + assertEquals(_ifInstance.getVserver(), _vserver); + } + + @Test + public void testSetTenant() { + _ifInstance.setTenant(_tenant); + assertEquals(_ifInstance.getTenant(), _tenant); + } + + @Test + public void testSetCloudRegion() { + _ifInstance.setCloudRegion(_cloudRegion); + assertEquals(_ifInstance.getCloudRegion(), _cloudRegion); + } + + @Test + public void testSetVnfc() { + _ifInstance.setVnfc(_vnfc); + assertEquals(_ifInstance.getVnfc(), _vnfc); + } + + @Test + public void testSetAdditionalProperty() { + _ifInstance.setAdditionalProperty("prop1", "propvalue1"); + _ifInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_ifInstance.getAdditionalProperties(), _additionalProperties); + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFiltersTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFiltersTest.java new file mode 100644 index 000000000..6131e13e0 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/InstanceFiltersTest.java @@ -0,0 +1,55 @@ +package org.onap.ccsdk.sli.adaptors.aai.query; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class InstanceFiltersTest { + + InstanceFilters _ifsInstance; + protected List<InstanceFilter> _instanceFilter; + protected Map<String, Object> _additionalProperties; + + @Before + public void setUp() throws Exception { + _ifsInstance = new InstanceFilters(); + _instanceFilter = new ArrayList<>(); + InstanceFilter if1 = mock(InstanceFilter.class); + InstanceFilter if2 = mock(InstanceFilter.class); + _instanceFilter.add(if1); + _instanceFilter.add(if2); + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _ifsInstance = null; + _instanceFilter = null; + _additionalProperties = null; + } + + @Test + public void testSetInstanceFilter() { + _ifsInstance.setInstanceFilter(_instanceFilter); + assertEquals(_ifsInstance.getInstanceFilter(), _instanceFilter); + + } + + @Test + public void testSetAdditionalProperty() { + _ifsInstance.setAdditionalProperty("prop1", "propvalue1"); + _ifsInstance.setAdditionalProperty("prop2", "propvalue2"); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/ResultTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/ResultTest.java new file mode 100644 index 000000000..14c17a563 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/query/ResultTest.java @@ -0,0 +1,159 @@ +package org.onap.ccsdk.sli.adaptors.aai.query; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import org.onap.aai.inventory.v21.CloudRegion; +import org.onap.aai.inventory.v21.Complex; +import org.onap.aai.inventory.v21.Configuration; +import org.onap.aai.inventory.v21.GenericVnf; +import org.onap.aai.inventory.v21.L3InterfaceIpv4AddressList; +import org.onap.aai.inventory.v21.L3InterfaceIpv6AddressList; +import org.onap.aai.inventory.v21.L3Network; +import org.onap.aai.inventory.v21.LInterface; +//import org.onap.aai.inventory.v21.OwningEntity; +import org.onap.aai.inventory.v21.Pserver; +import org.onap.aai.inventory.v21.ServiceInstance; +import org.onap.aai.inventory.v21.Vnfc; +import org.onap.aai.inventory.v21.Vserver; + +public class ResultTest { + + Result _rInstance; + + protected CloudRegion _cloudRegion; + protected Complex _complex; + protected Configuration _configuration; + protected GenericVnf _genericVnf; + protected L3InterfaceIpv4AddressList _l3InterfaceIpv4AddressList; + protected L3InterfaceIpv6AddressList _l3InterfaceIpv6AddressList; + protected L3Network _l3Network; + protected LInterface _lInterface; + protected Pserver _pserver; + protected ServiceInstance _serviceInstance; + protected Vnfc _vnfc; + protected Vserver _vserver; + + protected Map<String, Object> _additionalProperties; + + @Before + public void setUp() throws Exception { + _rInstance = new Result(); + + CloudRegion _cloudRegion = mock(CloudRegion.class); + Complex _complex = mock(Complex.class); + Configuration _configuration = mock(Configuration.class); + L3InterfaceIpv4AddressList _l3InterfaceIpv4AddressList = mock(L3InterfaceIpv4AddressList.class); + L3InterfaceIpv6AddressList _l3InterfaceIpv6AddressList = mock(L3InterfaceIpv6AddressList.class); + L3Network _l3Network = mock(L3Network.class); + LInterface _pInterface = mock(LInterface.class); + GenericVnf _genericVnf = mock(GenericVnf.class); + Vserver _vserver = mock(Vserver.class); + Pserver _pserver = mock(Pserver.class); + Vnfc _vnfc = mock(Vnfc.class); + ServiceInstance _serviceInstance = mock(ServiceInstance.class); + + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _rInstance = null; + _additionalProperties = null; + } + + @Test + public void testSetComplex() { + _rInstance.setComplex(_complex); + assertEquals(_rInstance.getComplex(), _complex); + } + + @Test + public void testSetConfiguration() { + _rInstance.setConfiguration(_configuration); + assertEquals(_rInstance.getConfiguration(), _configuration); + } + + @Test + public void testSetL3InterfaceIpv4AddressList() { + _rInstance.setL3InterfaceIpv4AddressList(_l3InterfaceIpv4AddressList); + assertEquals(_rInstance.getL3InterfaceIpv4AddressList(), _l3InterfaceIpv4AddressList); + } + + @Test + public void testSetL3InterfaceIpv6AddressList() { + _rInstance.setL3InterfaceIpv6AddressList(_l3InterfaceIpv6AddressList); + assertEquals(_rInstance.getL3InterfaceIpv6AddressList(), _l3InterfaceIpv6AddressList); + } + + @Test + public void testSetL3Network() { + _rInstance.setL3Network(_l3Network); + assertEquals(_rInstance.getL3Network(), _l3Network); + } + + @Test + public void testSetServiceInstance() { + _rInstance.setServiceInstance(_serviceInstance); + assertEquals(_rInstance.getServiceInstance(), _serviceInstance); + } + + @Test + public void testSetGenericVnf() { + _rInstance.setGenericVnf(_genericVnf); + assertEquals(_rInstance.getGenericVnf(), _genericVnf); + } + + @Test + public void testSetVserver() { + _rInstance.setVserver(_vserver); + assertEquals(_rInstance.getVserver(), _vserver); + } + + @Test + public void testSetCloudRegion() { + _rInstance.setCloudRegion(_cloudRegion); + assertEquals(_rInstance.getCloudRegion(), _cloudRegion); + } + + @Test + public void testSetVnfc() { + _rInstance.setVnfc(_vnfc); + assertEquals(_rInstance.getVnfc(), _vnfc); + } + + @Test + public void testSetLInterface() { + _rInstance.setLInterface(_lInterface); + assertEquals(_rInstance.getLInterface(), _lInterface); + } + + @Test + public void testSetPserver() { + _rInstance.setPserver(_pserver); + assertEquals(_rInstance.getPserver(), _pserver); + } + + @Test + public void testSetAdditionalProperty() { + _rInstance.setAdditionalProperty("prop1", "propvalue1"); + _rInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_rInstance.getAdditionalProperties(), _additionalProperties); + } + + @Test + public void testToString() { + assertNotNull(_rInstance.toString()); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/ActionDatumTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/ActionDatumTest.java new file mode 100644 index 000000000..7b858ea65 --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/ActionDatumTest.java @@ -0,0 +1,58 @@ +package org.onap.ccsdk.sli.adaptors.aai.update; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ActionDatumTest { + + ActionDatum _oInstance; + protected Map<String, Object> _additionalProperties; + protected String _propertyName; + protected String _propertyValue; + + @Before + public void setUp() throws Exception { + _oInstance = new ActionDatum(); + _propertyName = "propertyName"; + _propertyValue = "propertyValue"; + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _oInstance = null; + _additionalProperties = null; + } + + @Test + public void testSetPropertyName() { + _oInstance.setPropertyName(_propertyName); + assertEquals(_oInstance.getPropertyName(), _propertyName); + } + + @Test + public void testSetPropertyValue() { + _oInstance.setPropertyValue(_propertyValue); + assertEquals(_oInstance.getPropertyValue(), _propertyValue); + } + + @Test + public void testSetAdditionalProperty() { + _oInstance.setAdditionalProperty("prop1", "propvalue1"); + _oInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_oInstance.getAdditionalProperties(), _additionalProperties); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/ActionTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/ActionTest.java new file mode 100644 index 000000000..459396c1c --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/ActionTest.java @@ -0,0 +1,64 @@ +package org.onap.ccsdk.sli.adaptors.aai.update; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.aai.query.Result; + +public class ActionTest { + + Action _oInstance; + protected Map<String, Object> _additionalProperties; + protected String _actionType; + protected List<ActionDatum> _actionData; + + @Before + public void setUp() throws Exception { + _oInstance = new Action(); + _actionType = "actionType"; + _actionData = new ArrayList<>(); + ActionDatum a1 = mock(ActionDatum.class); + ActionDatum a2 = mock(ActionDatum.class); + _actionData.add(a1); + _actionData.add(a2); + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _oInstance = null; + _actionData = null; + _additionalProperties = null; + } + + @Test + public void testSetActionData() { + _oInstance.setActionData(_actionData); + assertEquals(_oInstance.getActionData(), _actionData); + } + + @Test + public void testSetActionType() { + _oInstance.setActionType(_actionType); + assertEquals(_oInstance.getActionType(), _actionType); + } + + @Test + public void testSetAdditionalProperty() { + _oInstance.setAdditionalProperty("prop1", "propvalue1"); + _oInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_oInstance.getAdditionalProperties(), _additionalProperties); + } +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/UpdateNodeKeyTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/UpdateNodeKeyTest.java new file mode 100644 index 000000000..360a0948f --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/UpdateNodeKeyTest.java @@ -0,0 +1,53 @@ +package org.onap.ccsdk.sli.adaptors.aai.update; + +import static org.junit.Assert.*; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class UpdateNodeKeyTest { + UpdateNodeKey _oInstance; + protected Map<String, Object> _additionalProperties; + protected String _keyName; + protected String _keyValue; + @Before + public void setUp() throws Exception { + _oInstance = new UpdateNodeKey(); + _keyName = "keyName"; + _keyValue = "keyValue"; + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _oInstance = null; + _additionalProperties = null; + } + + @Test + public void testSetKeyName() { + _oInstance.setKeyName(_keyName); + assertEquals(_oInstance.getKeyName(), _keyName); + } + + @Test + public void testSetKeyValue() { + _oInstance.setKeyName(_keyName); + assertEquals(_oInstance.getKeyName(), _keyName); + } + + @Test + public void testSetAdditionalProperty() { + _oInstance.setAdditionalProperty("prop1", "propvalue1"); + _oInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_oInstance.getAdditionalProperties(), _additionalProperties); + } + +} diff --git a/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/UpdateTest.java b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/UpdateTest.java new file mode 100644 index 000000000..8f8a06eac --- /dev/null +++ b/aai-service/provider/src/test/java/org/onap/ccsdk/sli/adaptors/aai/update/UpdateTest.java @@ -0,0 +1,75 @@ +package org.onap.ccsdk.sli.adaptors.aai.update; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class UpdateTest { + + Update _oInstance; + protected Map<String, Object> _additionalProperties; + protected String _updateNodeType; + protected List<UpdateNodeKey> _updateNodeKey; + protected List<Action> _action; + + @Before + public void setUp() throws Exception { + _oInstance = new Update(); + _updateNodeType = "updateNodeType"; + _action = new ArrayList<>(); + Action a1 = mock(Action.class); + Action a2 = mock(Action.class); + _action.add(a1); + _action.add(a2); + _updateNodeKey = new ArrayList<>(); + UpdateNodeKey k1 = mock(UpdateNodeKey.class); + UpdateNodeKey k2 = mock(UpdateNodeKey.class); + _updateNodeKey.add(k1); + _updateNodeKey.add(k2); + _additionalProperties = new HashMap<String, Object>() {{ + put("prop1", "propvalue1"); + put("prop2", "propvalue2"); + }}; + } + + @After + public void tearDown() throws Exception { + _oInstance = null; + _action = null; + _additionalProperties = null; + } + + @Test + public void testSetUpdateNodeType() { + _oInstance.setUpdateNodeType(_updateNodeType); + assertEquals(_oInstance.getUpdateNodeType(), _updateNodeType); + } + + @Test + public void testSetAction() { + _oInstance.setAction(_action); + assertEquals(_oInstance.getAction(), _action); + } + + @Test + public void testSetUpdateNodeKey() { + _oInstance.setUpdateNodeKey(_updateNodeKey); + assertEquals(_oInstance.getUpdateNodeKey(), _updateNodeKey); + } + + + @Test + public void testSetAdditionalProperty() { + _oInstance.setAdditionalProperty("prop1", "propvalue1"); + _oInstance.setAdditionalProperty("prop2", "propvalue2"); + assertEquals(_oInstance.getAdditionalProperties(), _additionalProperties); + } +} diff --git a/aai-service/provider/src/test/resources/aaiclient.properties b/aai-service/provider/src/test/resources/aaiclient.properties new file mode 100755 index 000000000..571280b81 --- /dev/null +++ b/aai-service/provider/src/test/resources/aaiclient.properties @@ -0,0 +1,80 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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 file for A&AI Client +# + +# +# Certificate keystore and truststore +# +org.onap.ccsdk.sli.adaptors.aai.ssl.trust=/opt/onap/ccsdk/data/stores/truststore.onap.client.jks +org.onap.ccsdk.sli.adaptors.aai.ssl.trust.psswd=adminadmin +org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore=true + +org.onap.ccsdk.sli.adaptors.aai.client.name=SDNC +org.onap.ccsdk.sli.adaptors.aai.client.psswd=SDNC + +org.onap.ccsdk.sli.adaptors.aai.application=CCSDK +# +# Configuration file for A&AI Client +# +org.onap.ccsdk.sli.adaptors.aai.uri=https://aai.api.simpledemo.onap.org:8443 +connection.timeout=60000 +read.timeout=60000 + +# aai version +org.onap.ccsdk.sli.adaptors.aai.version=/v21/ + +# query +org.onap.ccsdk.sli.adaptors.aai.path.query=/aai/v21/search/sdn-zone-query +org.onap.ccsdk.sli.adaptors.aai.query.nodes=/aai/v21/search/nodes-query?search-node-type={node-type}&filter={entity-identifier}:EQUALS:{entity-name} +org.onap.ccsdk.sli.adaptors.aai.query.generic=/aai/v21/search/generic-query?key={identifier}:{value}&start-node-type={start-node-type}&include=complex&depth=3 + +#update +org.onap.ccsdk.sli.adaptors.aai.update=/aai/v21/actions/update + +# UBB Notify +org.onap.ccsdk.sli.adaptors.aai.path.notify=/aai/v21/actions/notify +org.onap.ccsdk.sli.adaptors.aai.notify.selflink.fqdn=<%= @ubbUri %>/restconf/config/L3SDN-API:services/layer3-service-list/{service-instance-id} +org.onap.ccsdk.sli.adaptors.aai.notify.selflink.avpn=<%= @ubbUri %>/restconf/config/L3AVPN-EVC-API:services/service-list/{service-instance-id}/service-data/avpn-logicalchannel-information + +# P-Interfaces +org.onap.ccsdk.sli.adaptors.aai.path.pserver.pinterfaces=/aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces +org.onap.ccsdk.sli.adaptors.aai.path.pserver.pinterface=/aai/v21/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces/p-interface/{interface-name} + +# VNF IMAGES +org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query=/aai/v21/service-design-and-creation/vnf-images/vnf-image?application={application_model}&application-vendor={application_vendor} + +# service instance +org.onap.ccsdk.sli.adaptors.aai.path.svcinst.query=/aai/v21/search/generic-query?key=service-instance.service-instance-id:{svc-instance-id}&start-node-type=service-instance&include=service-instance +org.onap.ccsdk.sli.adaptors.aai.path.service.instance=/aai/v21/business/customers/customer/{global-customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances/service-instance/{service-instance-id} + +# VNF IMAGES QUERY +org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query=/aai/v21/service-design-and-creation/vnf-images/vnf-image?application={application_model}&application-vendor={application_vendor} + +# +# Formatting +# +org.onap.ccsdk.sli.adaptors.aai.param.format=filter=%s:%s +org.onap.ccsdk.sli.adaptors.aai.param.vnf_type=vnf-type +org.onap.ccsdk.sli.adaptors.aai.param.physical.location.id=physical-location-id +org.onap.ccsdk.sli.adaptors.aai.param.service.type=service-type diff --git a/aai-service/provider/src/test/resources/json/linterfaceJson.txt b/aai-service/provider/src/test/resources/json/linterfaceJson.txt new file mode 100755 index 000000000..22c8db1ee --- /dev/null +++ b/aai-service/provider/src/test/resources/json/linterfaceJson.txt @@ -0,0 +1,43 @@ + { + "interface-name": "example-interface-name-val-1600", + "interface-role": "example-interface-role-val-1600", + "v6-wan-link-ip": "example-v6-wan-link-ip-val-1600", + "resource-version": "1450729537", + "vlans": { + "vlan": [ + { + "vlan-interface": "example-vlan-interface-val-7133", + "vlan-id-inner": 1318, + "vlan-id-outer": 244, + "resource-version": "1450729537", + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-9533", + "l3-interface-ipv4-prefix-length": 3013, + "vlan-id-inner": 7150, + "vlan-id-outer": 1027, + "resource-version": "1450729537", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-7149", + "l3-interface-ipv6-prefix-length": 4538, + "vlan-id-inner": 8271, + "vlan-id-outer": 8990, + "resource-version": "1450729537", + "relationship-list": { + + } + } + ] + } + ] + } + }
\ No newline at end of file diff --git a/aai-service/provider/src/test/resources/json/pserverJson.txt b/aai-service/provider/src/test/resources/json/pserverJson.txt new file mode 100755 index 000000000..4b7f97d37 --- /dev/null +++ b/aai-service/provider/src/test/resources/json/pserverJson.txt @@ -0,0 +1,97 @@ +{ + "selflink": "https://mtinjvmsdn30.cip.att.com:8443/aai/v4/network/pservers/pserver/chcil129snd", + "hostname": "chcil129snd", + "ptnii-equip-name": "chcil129snd", + "equip-type": "server1", + "equip-vendor": "HP", + "equip-model": "DL380p-nd", + "fqdn": "chcilrsv129.chcil.sbcglobal.net", + "ipv4-oam-address": "12.80.1.83", + "serial-number": "n02kvcBczBI", + "in-maint":false, + "resource-version": "1455988020", + "purpose": "Gamma-VCE", + "relationship-list": { + "relationship": [ + { + "related-to": "complex", + "related-link": "https://aai.infra.aic.att.net:8443/aai/v5/cloud-infrastructure/complexes/complex/CHCGILCL73W/", + "relationship-data": [ + { + "relationship-key": "complex.physical-location-id", + "relationship-value": "CHCGILCL73W" + } + ] + } + ] + }, + "p-interfaces": { + "p-interface": [ + { + "interface-name": "p6p2-6/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1455988020", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://aai.infra.aic.att.net:8443/aai/v5/network/physical-links/physical-link/chcil129snd%3Ap6p2-6%2F2%7Cchciltax102%3Axe-1%2F0%2F29/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "chcil129snd:p6p2-6/2|chciltax102:xe-1/0/29" + } + ] + } + ] + }, + "l-interfaces": { + + } + }, + { + "interface-name": "p6p1-6/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1455988020", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://aai.infra.aic.att.net:8443/aai/v5/network/physical-links/physical-link/chcil129snd%3Ap6p1-6%2F1%7Cchciltax101%3Axe-0%2F0%2F29/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "chcil129snd:p6p1-6/1|chciltax101:xe-0/0/29" + } + ] + } + ] + }, + "l-interfaces": { + + } + }, + { + "interface-name": "em0-0/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1455988020", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://aai.infra.aic.att.net:8443/aai/v5/network/physical-links/physical-link/chcil129snd%3Aem0-0%2F1%7Cchciltax101%3Axe-0%2F0%2F59/", + "relationship-data": [ + { + + } + ] + } + ] + } + } + ] + } +}
\ No newline at end of file diff --git a/aai-service/provider/src/test/resources/testCommands.txt b/aai-service/provider/src/test/resources/testCommands.txt new file mode 100644 index 000000000..d19b8d306 --- /dev/null +++ b/aai-service/provider/src/test/resources/testCommands.txt @@ -0,0 +1 @@ +query|generic-vnf|generic-vnf.vnf-id:assign:value:adb28ac0-a260-4b7d-9ce5-adf15733c458
\ No newline at end of file diff --git a/ansible-adapter/.pydevproject b/ansible-adapter/.pydevproject new file mode 100644 index 000000000..d001f0aea --- /dev/null +++ b/ansible-adapter/.pydevproject @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?eclipse-pydev version="1.0"?><pydev_project> +<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property> +<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python interpreter</pydev_property> +</pydev_project> diff --git a/ansible-adapter/ansible-adapter-bundle/.gitignore b/ansible-adapter/ansible-adapter-bundle/.gitignore new file mode 100644 index 000000000..255b54097 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/.gitignore @@ -0,0 +1,25 @@ +# ============LICENSE_START========================================== +# ONAP : APPC +# =================================================================== +# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the License); +# you may not use this software 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. +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# ============LICENSE_END============================================ +/bin/ +/target/ +/target-ide/ +/.settings/ diff --git a/ansible-adapter/ansible-adapter-bundle/pom.xml b/ansible-adapter/ansible-adapter-bundle/pom.xml new file mode 100644 index 000000000..605c64421 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/pom.xml @@ -0,0 +1,131 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============LICENSE_START======================================================= + ONAP : APPC ================================================================================ + Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Copyright (C) 2017 Amdocs ============================================================================= + Licensed under the Apache License, Version 2.0 (the "License"); you may not + use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required + by applicable law or agreed to in writing, software distributed under the + License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. See the License for the specific + language governing permissions and limitations under the License. ECOMP is + a trademark and service mark of AT&T Intellectual Property. ============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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ansible-adapter-bundle</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-adaptors :: ansible-adapter :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-core-artifacts</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + + + <!-- Needed to run test cases --> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-jaxrs</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + + + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + + + </dependencies> +</project> diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/AnsibleAdapter.java b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/AnsibleAdapter.java new file mode 100644 index 000000000..e43d3e3c3 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/AnsibleAdapter.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ansible; + +import java.util.Map; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; + +/** + * This interface defines the operations that the Ansible adapter exposes. + * + */ +public interface AnsibleAdapter extends SvcLogicJavaPlugin { + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + */ + String getAdapterName(); + + /* Method to post request for execution of Playbook */ + void reqExec(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException; + + /* Method to get result of a playbook execution request */ + void reqExecResult(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException; + + /* Method to get log of a playbook execution request */ + void reqExecLog(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException; + + /* Method to get output of a playbook execution request */ + void reqExecOutput(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException; +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/AnsibleAdapterPropertiesProvider.java b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/AnsibleAdapterPropertiesProvider.java new file mode 100755 index 000000000..6d9f4f12c --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/AnsibleAdapterPropertiesProvider.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2016 - 2017 ONAP + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ansible; + +import java.util.Properties; + +public interface AnsibleAdapterPropertiesProvider { + + public Properties getProperties(); +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/impl/AnsibleAdapterImpl.java b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/impl/AnsibleAdapterImpl.java new file mode 100644 index 000000000..2361feebd --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/impl/AnsibleAdapterImpl.java @@ -0,0 +1,460 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ansible.impl; + +import java.util.Map; +import java.util.Properties; +import org.apache.commons.lang.StringUtils; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.ccsdk.sli.adaptors.ansible.AnsibleAdapter; +import org.onap.ccsdk.sli.adaptors.ansible.AnsibleAdapterPropertiesProvider; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleMessageParser; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleResult; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleResultCodes; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleServerEmulator; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +/** + * This class implements the {@link AnsibleAdapter} interface. This interface defines the behaviors + * that our service provides. + */ +public class AnsibleAdapterImpl implements AnsibleAdapter { + + + /** + * The constant used to define the service name in the mapped diagnostic context + */ + @SuppressWarnings("nls") + public static final String MDC_SERVICE = "service"; + + /** + * The constant for the status code for a failed outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_FAILURE = "failure"; + + /** + * The constant for the status code for a successful outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_SUCCESS = "success"; + + /** + * Adapter Name + */ + private static final String ADAPTER_NAME = "Ansible Adapter"; + private static final String APPC_EXCEPTION_CAUGHT = "APPCException caught"; + + private static final String RESULT_CODE_ATTRIBUTE_NAME = "org.onap.appc.adapter.ansible.result.code"; + private static final String MESSAGE_ATTRIBUTE_NAME = "org.onap.appc.adapter.ansible.message"; + private static final String RESULTS_ATTRIBUTE_NAME = "org.onap.appc.adapter.ansible.results"; + private static final String ID_ATTRIBUTE_NAME = "org.onap.appc.adapter.ansible.Id"; + private static final String LOG_ATTRIBUTE_NAME = "org.onap.appc.adapter.ansible.log"; + private static final String OUTPUT_ATTRIBUTE_NAME = "org.onap.appc.adapter.ansible.output"; + + private static final String CLIENT_TYPE_PROPERTY_NAME = "org.onap.appc.adapter.ansible.clientType"; + private static final String TRUSTSTORE_PROPERTY_NAME = "org.onap.appc.adapter.ansible.trustStore"; + private static final String TRUSTPASSD_PROPERTY_NAME = "org.onap.appc.adapter.ansible.trustStore.trustPasswd"; + + private static final String PASSD = "Password"; + + /** + * The logger to be used + */ + private static final EELFLogger logger = EELFManager.getInstance().getLogger(AnsibleAdapterImpl.class); + + + /** + * Connection object + **/ + private ConnectionBuilder httpClient; + + /** + * Ansible API Message Handlers + **/ + private AnsibleMessageParser messageProcessor; + + /** + * indicator whether in test mode + **/ + private boolean testMode = false; + + /** + * server emulator object to be used if in test mode + **/ + private AnsibleServerEmulator testServer; + + /** + * This default constructor is used as a work around because the activator wasn't getting called + */ + public AnsibleAdapterImpl() { + initialize(new AnsibleAdapterPropertiesProviderImpl()); + } + public AnsibleAdapterImpl(AnsibleAdapterPropertiesProvider propProvider) { + initialize(propProvider); + } + + /** + * Used for jUnit test and testing interface + */ + public AnsibleAdapterImpl(boolean mode) { + testMode = mode; + testServer = new AnsibleServerEmulator(); + messageProcessor = new AnsibleMessageParser(); + } + + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + * @see org.onap.appc.adapter.rest.AnsibleAdapter#getAdapterName() + */ + @Override + public String getAdapterName() { + return ADAPTER_NAME; + } + + /** + * @param rc Method posts info to Context memory in case of an error and throws a + * SvcLogicException causing SLI to register this as a failure + */ + @SuppressWarnings("static-method") + private void doFailure(SvcLogicContext svcLogic, int code, String message) throws SvcLogicException { + + svcLogic.setStatus(OUTCOME_FAILURE); + svcLogic.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(code)); + svcLogic.setAttribute(MESSAGE_ATTRIBUTE_NAME, message); + + throw new SvcLogicException("Ansible Adapter Error = " + message); + } + + /** + * initialize the Ansible adapter based on default and over-ride configuration data + */ + private void initialize(AnsibleAdapterPropertiesProvider propProvider) { + + + Properties props = propProvider.getProperties(); + + // Create the message processor instance + messageProcessor = new AnsibleMessageParser(); + + // Create the http client instance + // type of client is extracted from the property file parameter + // org.onap.appc.adapter.ansible.clientType + // It can be : + // 1. TRUST_ALL (trust all SSL certs). To be used ONLY in dev + // 2. TRUST_CERT (trust only those whose certificates have been stored in the trustStore file) + // 3. DEFAULT (trust only well known certificates). This is standard behavior to which it will + // revert. To be used in PROD + + try { + String clientType = props.getProperty(CLIENT_TYPE_PROPERTY_NAME); + logger.info("Ansible http client type set to " + clientType); + + if ("TRUST_ALL".equals(clientType)) { + logger.info( + "Creating http client to trust ALL ssl certificates. WARNING. This should be done only in dev environments"); + httpClient = new ConnectionBuilder(1); + } else if ("TRUST_CERT".equals(clientType)) { + // set path to keystore file + String trustStoreFile = props.getProperty(TRUSTSTORE_PROPERTY_NAME); + String key = props.getProperty(TRUSTPASSD_PROPERTY_NAME); + char[] trustStorePasswd = key.toCharArray(); + logger.info("Creating http client with trustmanager from " + trustStoreFile); + httpClient = new ConnectionBuilder(trustStoreFile, trustStorePasswd); + } else { + logger.info("Creating http client with default behaviour"); + httpClient = new ConnectionBuilder(0); + } + } catch (Exception e) { + logger.error("Error Initializing Ansible Adapter due to Unknown Exception", e); + } + + logger.info("Initialized Ansible Adapter"); + } + + // Public Method to post request to execute playbook. Posts the following back + // to Svc context memory + // org.onap.appc.adapter.ansible.req.code : 100 if successful + // org.onap.appc.adapter.ansible.req.messge : any message + // org.onap.appc.adapter.ansible.req.Id : a unique uuid to reference the request + @Override + public void reqExec(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + + String playbookName = StringUtils.EMPTY; + String payload = StringUtils.EMPTY; + String agentUrl = StringUtils.EMPTY; + String user = StringUtils.EMPTY; + String password = StringUtils.EMPTY; + String id = StringUtils.EMPTY; + + JSONObject jsonPayload; + + try { + // create json object to send request + jsonPayload = messageProcessor.reqMessage(params); + + agentUrl = (String) jsonPayload.remove("AgentUrl"); + user = (String) jsonPayload.remove("User"); + password = (String) jsonPayload.remove(PASSD); + id = jsonPayload.getString("Id"); + payload = jsonPayload.toString(); + logger.info("Updated Payload = " + payload); + } catch (SvcLogicException e) { + logger.error(APPC_EXCEPTION_CAUGHT, e); + doFailure(ctx, AnsibleResultCodes.INVALID_PAYLOAD.getValue(), + "Error constructing request for execution of playbook due to missing mandatory parameters. Reason = " + + e.getMessage()); + } catch (JSONException e) { + logger.error("JSONException caught", e); + doFailure(ctx, AnsibleResultCodes.INVALID_PAYLOAD.getValue(), + "Error constructing request for execution of playbook due to invalid JSON block. Reason = " + + e.getMessage()); + } catch (NumberFormatException e) { + logger.error("NumberFormatException caught", e); + doFailure(ctx, AnsibleResultCodes.INVALID_PAYLOAD.getValue(), + "Error constructing request for execution of playbook due to invalid parameter values. Reason = " + + e.getMessage()); + } + + int code = -1; + String message = StringUtils.EMPTY; + + try { + // post the test request + logger.info("Posting request = " + payload + " to url = " + agentUrl); + AnsibleResult testResult = postExecRequest(agentUrl, payload, user, password); + + // Process if HTTP was successful + if (testResult.getStatusCode() == 200) { + testResult = messageProcessor.parsePostResponse(testResult.getStatusMessage()); + } else { + doFailure(ctx, testResult.getStatusCode(), + "Error posting request. Reason = " + testResult.getStatusMessage()); + } + + code = testResult.getStatusCode(); + message = testResult.getStatusMessage(); + + // Check status of test request returned by Agent + if (code == AnsibleResultCodes.PENDING.getValue()) { + logger.info(String.format("Submission of Test %s successful.", playbookName)); + // test request accepted. We are in asynchronous case + } else { + doFailure(ctx, code, "Request for execution of playbook rejected. Reason = " + message); + } + } catch (SvcLogicException e) { + logger.error(APPC_EXCEPTION_CAUGHT, e); + doFailure(ctx, AnsibleResultCodes.UNKNOWN_EXCEPTION.getValue(), + "Exception encountered when posting request for execution of playbook. Reason = " + e.getMessage()); + } + + ctx.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(code)); + ctx.setAttribute(MESSAGE_ATTRIBUTE_NAME, message); + ctx.setAttribute(ID_ATTRIBUTE_NAME, id); + } + + /** + * Public method to query status of a specific request It blocks till the Ansible Server + * responds or the session times out (non-Javadoc) + * + * @see org.onap.ccsdk.sli.adaptors.ansible.AnsibleAdapter#reqExecResult(java.util.Map, + * org.onap.ccsdk.sli.core.sli.SvcLogicContext) + */ + @Override + public void reqExecResult(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + + // Get URI + String reqUri = StringUtils.EMPTY; + + try { + reqUri = messageProcessor.reqUriResult(params); + logger.info("Got uri ", reqUri ); + } catch (SvcLogicException e) { + logger.error(APPC_EXCEPTION_CAUGHT, e); + doFailure(ctx, AnsibleResultCodes.INVALID_PAYLOAD.getValue(), + "Error constructing request to retrieve result due to missing parameters. Reason = " + + e.getMessage()); + return; + } catch (NumberFormatException e) { + logger.error("NumberFormatException caught", e); + doFailure(ctx, AnsibleResultCodes.INVALID_PAYLOAD.getValue(), + "Error constructing request to retrieve result due to invalid parameters value. Reason = " + + e.getMessage()); + return; + } + + int code = -1; + String message = StringUtils.EMPTY; + String results = StringUtils.EMPTY; + + try { + // Try to retrieve the test results (modify the URL for that) + AnsibleResult testResult = queryServer(reqUri, params.get("User"), params.get(PASSD)); + code = testResult.getStatusCode(); + message = testResult.getStatusMessage(); + + if (code == 200) { + logger.info("Parsing response from Server = " + message); + // Valid HTTP. process the Ansible message + testResult = messageProcessor.parseGetResponse(message); + code = testResult.getStatusCode(); + message = testResult.getStatusMessage(); + results = testResult.getResults(); + } + + logger.info("Request response = " + message); + } catch (SvcLogicException e) { + logger.error(APPC_EXCEPTION_CAUGHT, e); + doFailure(ctx, AnsibleResultCodes.UNKNOWN_EXCEPTION.getValue(), + "Exception encountered retrieving result : " + e.getMessage()); + return; + } + + // We were able to get and process the results. Determine if playbook succeeded + + if (code == AnsibleResultCodes.FINAL_SUCCESS.getValue()) { + message = String.format("Ansible Request %s finished with Result = %s, Message = %s", params.get("Id"), + OUTCOME_SUCCESS, message); + logger.info(message); + } else { + logger.info(String.format("Ansible Request %s finished with Result %s, Message = %s", params.get("Id"), + OUTCOME_FAILURE, message)); + ctx.setAttribute(RESULTS_ATTRIBUTE_NAME, results); + doFailure(ctx, code, message); + return; + } + + ctx.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(400)); + ctx.setAttribute(MESSAGE_ATTRIBUTE_NAME, message); + ctx.setAttribute(RESULTS_ATTRIBUTE_NAME, results); + ctx.setStatus(OUTCOME_SUCCESS); + } + + /** + * Public method to get logs from playbook execution for a specific request + * + * It blocks till the Ansible Server responds or the session times out very similar to + * reqExecResult logs are returned in the DG context variable org.onap.appc.adapter.ansible.log + */ + @Override + public void reqExecLog(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + + String reqUri = StringUtils.EMPTY; + try { + reqUri = messageProcessor.reqUriLog(params); + logger.info("Retrieving results from " + reqUri); + } catch (Exception e) { + logger.error("Exception caught", e); + doFailure(ctx, AnsibleResultCodes.INVALID_PAYLOAD.getValue(), e.getMessage()); + } + + String message = StringUtils.EMPTY; + try { + // Try to retrieve the test results (modify the url for that) + AnsibleResult testResult = queryServer(reqUri, params.get("User"), params.get(PASSD)); + message = testResult.getStatusMessage(); + logger.info("Request output = " + message); + ctx.setAttribute(LOG_ATTRIBUTE_NAME, message); + ctx.setStatus(OUTCOME_SUCCESS); + } catch (Exception e) { + logger.error("Exception caught", e); + doFailure(ctx, AnsibleResultCodes.UNKNOWN_EXCEPTION.getValue(), + "Exception encountered retreiving output : " + e.getMessage()); + } + } + + /** + * Public method to get output from playbook execution for a specific request + * + * It blocks till the Ansible Server responds or the session times out very similar to + * reqExecResult and output is returned in the DG context variable org.onap.appc.adapter.ansible.output + */ + @Override + public void reqExecOutput(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + + String reqUri = StringUtils.EMPTY; + try { + reqUri = messageProcessor.reqUriOutput(params); + logger.info("Retrieving results from " + reqUri); + } catch (Exception e) { + logger.error("Exception caught", e); + doFailure(ctx, AnsibleResultCodes.INVALID_PAYLOAD.getValue(), e.getMessage()); + } + + String message = StringUtils.EMPTY; + try { + // Try to retrieve the test results (modify the url for that) + AnsibleResult testResult = queryServer(reqUri, params.get("User"), params.get(PASSD)); + message = testResult.getStatusMessage(); + logger.info("Request output = " + message); + ctx.setAttribute(OUTPUT_ATTRIBUTE_NAME, message); + ctx.setStatus(OUTCOME_SUCCESS); + } catch (Exception e) { + logger.error("Exception caught", e); + doFailure(ctx, AnsibleResultCodes.UNKNOWN_EXCEPTION.getValue(), + "Exception encountered retreiving output : " + e.getMessage()); + } + } + + /** + * Method that posts the request + */ + private AnsibleResult postExecRequest(String agentUrl, String payload, String user, String password) { + + AnsibleResult testResult; + + if (!testMode) { + httpClient.setHttpContext(user, password); + testResult = httpClient.post(agentUrl, payload); + } else { + testResult = testServer.Post(agentUrl, payload); + } + return testResult; + } + + /** + * Method to query Ansible server + */ + private AnsibleResult queryServer(String agentUrl, String user, String password) { + + AnsibleResult testResult; + + logger.info("Querying url = " + agentUrl); + + if (!testMode) { + testResult = httpClient.get(agentUrl); + } else { + testResult = testServer.Get(agentUrl); + } + + return testResult; + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/impl/AnsibleAdapterPropertiesProviderImpl.java b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/impl/AnsibleAdapterPropertiesProviderImpl.java new file mode 100755 index 000000000..482aaf8e5 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/impl/AnsibleAdapterPropertiesProviderImpl.java @@ -0,0 +1,191 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2016 - 2017 ONAP + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ansible.impl; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; +import java.util.Properties; +import java.util.Vector; +import org.onap.ccsdk.sli.adaptors.ansible.AnsibleAdapterPropertiesProvider; +import org.onap.ccsdk.sli.core.sli.ConfigurationException; +import org.onap.ccsdk.sli.core.utils.JREFileResolver; +import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver; +import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver; +import org.onap.ccsdk.sli.core.utils.common.CoreDefaultFileResolver; +import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Responsible for determining the properties file to use and instantiating the + * <code>SqlResource</code> Service. The priority for properties file + * resolution is as follows: + * + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>sql-resource.properties</code></li> + * <li>A <code>sql-resource.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ +public class AnsibleAdapterPropertiesProviderImpl implements AnsibleAdapterPropertiesProvider { + + private static final Logger LOG = LoggerFactory.getLogger(AnsibleAdapterPropertiesProviderImpl.class); + + /** + * The name of the properties file for database configuration + */ + private static final String ANSIBLEADAPTER_PROP_FILE_NAME = "ansible-adapter.properties"; + + /** + * A prioritized list of strategies for resolving sql-resource properties files. + */ + private Vector<PropertiesFileResolver> ansibleAdapterPropertiesFileResolvers = new Vector<>(); + + /** + * The configuration properties for the db connection. + */ + private Properties properties; + + /** + * Set up the prioritized list of strategies for resolving dblib properties + * files. + */ + public AnsibleAdapterPropertiesProviderImpl() { + ansibleAdapterPropertiesFileResolvers + .add(new SdncConfigEnvVarFileResolver("Using property file (1) from environment variable")); + ansibleAdapterPropertiesFileResolvers.add(new CoreDefaultFileResolver("Using property file (2) from default directory")); + + ansibleAdapterPropertiesFileResolvers.add( + new JREFileResolver("Using property file (3) from JRE argument", AnsibleAdapterPropertiesProviderImpl.class)); + ansibleAdapterPropertiesFileResolvers.add(new KarafRootFileResolver("Using property file (4) from karaf root", this)); + + // determines properties file as according to the priority described in the + // class header comment + final File propertiesFile = determinePropertiesFile(this); + if (propertiesFile != null) { + try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) { + properties = new Properties(); + properties.load(fileInputStream); + } catch (final IOException e) { + LOG.error("Failed to load properties for file: {}", propertiesFile.toString(), + new ConfigurationException("Failed to load properties for file: " + propertiesFile.toString(), + e)); + } + } else { + // Try to read properties as resource + + InputStream propStr = getClass().getResourceAsStream("/" + ANSIBLEADAPTER_PROP_FILE_NAME); + if (propStr != null) { + properties = new Properties(); + try { + properties.load(propStr); + propStr.close(); + } catch (IOException e) { + properties = null; + } + } + + } + + if (properties == null) { + reportFailure("Missing configuration properties resource(3)", new ConfigurationException( + "Missing configuration properties resource(3): " + ANSIBLEADAPTER_PROP_FILE_NAME)); + + LOG.info("Defaulting org.onap.appc.adapter.ansible.clientType to TRUST_ALL"); + + properties = new Properties(); + properties.setProperty("org.onap.appc.adapter.ansible.clientType", "TRUST_ALL"); + } + } + + /** + * Extract svclogic config properties. + * + * @return the svclogic config properties + */ + public Properties getProperties() { + return properties; + } + + /** + * Reports the method chosen for properties resolution to the + * <code>Logger</code>. + * + * @param message + * Some user friendly message + * @param fileOptional + * The file location of the chosen properties file + * @return the file location of the chosen properties file + */ + private static File reportSuccess(final String message, final Optional<File> fileOptional) { + if (fileOptional.isPresent()) { + final File file = fileOptional.get(); + LOG.info("{} {}", message, file.getPath()); + return file; + } + return null; + } + + /** + * Reports fatal errors. This is the case in which no properties file could be + * found. + * + * @param message + * An appropriate fatal error message + * @param configurationException + * An exception describing what went wrong during resolution + */ + private static void reportFailure(final String message, final ConfigurationException configurationException) { + + LOG.error("{}", message, configurationException); + } + + /** + * Determines the sql-resource properties file to use based on the following priority: + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>sql-resource.properties</code></li> + * <li>A <code>sql-resource.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ + File determinePropertiesFile(final AnsibleAdapterPropertiesProviderImpl resourceProvider) { + + for (final PropertiesFileResolver sliPropertiesFileResolver : ansibleAdapterPropertiesFileResolvers) { + final Optional<File> fileOptional = sliPropertiesFileResolver.resolveFile(ANSIBLEADAPTER_PROP_FILE_NAME); + if (fileOptional.isPresent()) { + return reportSuccess(sliPropertiesFileResolver.getSuccessfulResolutionMessage(), fileOptional); + } + } + + return null; + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/impl/ConnectionBuilder.java b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/impl/ConnectionBuilder.java new file mode 100644 index 000000000..672e0df67 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/impl/ConnectionBuilder.java @@ -0,0 +1,205 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ================================================================================ + * Modifications Copyright © 2018 IBM. + * ============================================================================= + * 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. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ansible.impl; + +import java.io.FileInputStream; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import javax.net.ssl.SSLContext; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLContexts; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleResult; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleResultCodes; +import org.onap.ccsdk.sli.core.utils.PathValidator; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +/** + * Returns a custom http client + * - based on options + * - can create one with ssl using an X509 certificate that does NOT have a known CA + * - create one which trusts ALL SSL certificates + * - return default httpclient (which only trusts known CAs from default cacerts file for process) this is the default + * option + **/ + +public class ConnectionBuilder { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ConnectionBuilder.class); + + private CloseableHttpClient httpClient = null; + private HttpClientContext httpContext = new HttpClientContext(); + + /** + * Constructor that initializes an http client based on certificate + **/ + public ConnectionBuilder(String certFile) throws KeyStoreException, CertificateException, IOException, + KeyManagementException, NoSuchAlgorithmException { + + /* Point to the certificate */ + try(FileInputStream fs = new FileInputStream(certFile)){ + /* Generate a certificate from the X509 */ + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(fs); + + /* Create a keystore object and load the certificate there */ + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + keystore.load(null, null); + keystore.setCertificateEntry("cacert", cert); + + SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build(); + SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, + SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + + httpClient = HttpClients.custom().setSSLSocketFactory(factory).build(); + } + } + + /** + * Constructor which trusts all certificates in a specific java keystore file (assumes a JKS + * file) + **/ + public ConnectionBuilder(String trustStoreFile, char[] trustStorePasswd) throws KeyStoreException, IOException, + KeyManagementException, NoSuchAlgorithmException, CertificateException { + + if (!PathValidator.isValidFilePath(trustStoreFile)) { + throw new IOException("Invalid trust store file path"); + } + + /* Load the specified trustStore */ + KeyStore keystore = KeyStore.getInstance("JKS"); + FileInputStream readStream = new FileInputStream(trustStoreFile); + keystore.load(readStream, trustStorePasswd); + + SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore).build(); + SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, + SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + + httpClient = HttpClients.custom().setSSLSocketFactory(factory).build(); + } + + /** + * Constructor that trusts ALL SSl certificates (NOTE : ONLY FOR DEV TESTING) if Mode == 1 or + * Default if Mode == 0 + */ + public ConnectionBuilder(int mode) + throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { + if (mode == 1) { + SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(); + SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, + SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + + httpClient = HttpClients.custom().setSSLSocketFactory(factory).build(); + } else { + httpClient = HttpClients.createDefault(); + } + } + + // Use to create an http context with auth headers + public void setHttpContext(String user, String myPassword) { + + // Are credential provided ? If so, set the context to be used + if (user != null && !user.isEmpty() && myPassword != null && !myPassword.isEmpty()) { + UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user, myPassword); + AuthScope authscope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT); + BasicCredentialsProvider credsprovider = new BasicCredentialsProvider(); + credsprovider.setCredentials(authscope, credentials); + httpContext.setCredentialsProvider(credsprovider); + } + } + + // Method posts to the ansible server and writes out response to + // Ansible result object + public AnsibleResult post(String agentUrl, String payload) { + + AnsibleResult result = new AnsibleResult(); + try { + + HttpPost postObj = new HttpPost(agentUrl); + StringEntity bodyParams = new StringEntity(payload, "UTF-8"); + postObj.setEntity(bodyParams); + postObj.addHeader("Content-type", "application/json"); + + HttpResponse response = httpClient.execute(postObj, httpContext); + + HttpEntity entity = response.getEntity(); + String responseOutput = entity != null ? EntityUtils.toString(entity) : null; + int responseCode = response.getStatusLine().getStatusCode(); + result.setStatusCode(responseCode); + result.setStatusMessage(responseOutput); + } catch (IOException io) { + logger.error("Caught IOException", io); + result.setStatusCode(AnsibleResultCodes.IO_EXCEPTION.getValue()); + result.setStatusMessage(io.getMessage()); + } + return result; + } + + // Method gets information from an Ansible server and writes out response to + // Ansible result object + + public AnsibleResult get(String agentUrl) { + + AnsibleResult result = new AnsibleResult(); + + try { + HttpGet getObj = new HttpGet(agentUrl); + HttpResponse response = httpClient.execute(getObj, httpContext); + + HttpEntity entity = response.getEntity(); + String responseOutput = entity != null ? EntityUtils.toString(entity) : null; + int responseCode = response.getStatusLine().getStatusCode(); + result.setStatusCode(responseCode); + result.setStatusMessage(responseOutput); + } catch (IOException io) { + result.setStatusCode(AnsibleResultCodes.IO_EXCEPTION.getValue()); + result.setStatusMessage(io.getMessage()); + logger.error("Caught IOException", io); + } + return result; + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleMessageParser.java b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleMessageParser.java new file mode 100644 index 000000000..5f6342d94 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleMessageParser.java @@ -0,0 +1,332 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * 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. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ansible.model; + +/** + * This module implements the APP-C/Ansible Server interface + * based on the REST API specifications + */ +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import com.google.common.base.Strings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class that validates and constructs requests sent/received from + * Ansible Server + */ +public class AnsibleMessageParser { + + private static final String STATUS_MESSAGE_KEY = "StatusMessage"; + private static final String STATUS_CODE_KEY = "StatusCode"; + + private static final String PLAYBOOK_NAME_KEY = "PlaybookName"; + private static final String AGENT_URL_KEY = "AgentUrl"; + private static final String PASS_KEY = "Password"; + private static final String USER_KEY = "User"; + private static final String ID_KEY = "Id"; + + private static final String LOCAL_PARAMETERS_OPT_KEY = "LocalParameters"; + private static final String FILE_PARAMETERS_OPT_KEY = "FileParameters"; + private static final String ENV_PARAMETERS_OPT_KEY = "EnvParameters"; + private static final String NODE_LIST_OPT_KEY = "NodeList"; + private static final String TIMEOUT_OPT_KEY = "Timeout"; + private static final String VERSION_OPT_KEY = "Version"; + private static final String ACTION_OPT_KEY = "Action"; + + private String jsonException = "JSON exception"; + private static final Logger LOGGER = LoggerFactory.getLogger(AnsibleMessageParser.class); + + /** + * Accepts a map of strings and + * a) validates if all parameters are appropriate (else, throws an exception) and + * b) if correct returns a JSON object with appropriate key-value pairs to send to the server. + * + * Mandatory parameters, that must be in the supplied information to the Ansible Adapter + * 1. URL to connect to + * 2. credentials for URL (assume username password for now) + * 3. Playbook name + * + */ + public JSONObject reqMessage(Map<String, String> params) throws SvcLogicException { + final String[] mandatoryTestParams = {AGENT_URL_KEY, PLAYBOOK_NAME_KEY, USER_KEY, PASS_KEY}; + final String[] optionalTestParams = {ENV_PARAMETERS_OPT_KEY, NODE_LIST_OPT_KEY, LOCAL_PARAMETERS_OPT_KEY, + TIMEOUT_OPT_KEY, VERSION_OPT_KEY, FILE_PARAMETERS_OPT_KEY, ACTION_OPT_KEY}; + + JSONObject jsonPayload = new JSONObject(); + + for (String key : mandatoryTestParams) { + throwIfMissingMandatoryParam(params, key); + jsonPayload.put(key, params.get(key)); + } + + parseOptionalParams(params, optionalTestParams, jsonPayload); + + // Generate a unique uuid for the test + String reqId = UUID.randomUUID().toString(); + jsonPayload.put(ID_KEY, reqId); + + return jsonPayload; + } + + /** + * Method that validates that the Map has enough information + * to query Ansible server for a result. If so, it returns + * the appropriate url, else an empty string. + */ + public String reqUriResult(Map<String, String> params) throws SvcLogicException { + + final String[] mandatoryTestParams = {AGENT_URL_KEY, ID_KEY, USER_KEY, PASS_KEY}; + + for (String key : mandatoryTestParams) { + throwIfMissingMandatoryParam(params, key); + } + return params.get(AGENT_URL_KEY) + "?Id=" + params.get(ID_KEY) + "&Type=GetResult"; + } + + /** + * Method that validates that the Map has enough information + * to query Ansible server for logs. If so, it populates the appropriate + * returns the appropriate url, else an empty string. + */ + public String reqUriLog(Map<String, String> params) throws SvcLogicException { + + final String[] mandatoryTestParams = {AGENT_URL_KEY, ID_KEY, USER_KEY, PASS_KEY}; + + for (String mandatoryParam : mandatoryTestParams) { + throwIfMissingMandatoryParam(params, mandatoryParam); + } + return params.get(AGENT_URL_KEY) + "?Id=" + params.get(ID_KEY) + "&Type=GetLog"; + } + + /** + * Method that validates that the Map has enough information + * to query Ansible server for an output. If so, it returns + * the appropriate url, else an empty string. + */ + public String reqUriOutput(Map<String, String> params) throws SvcLogicException { + + final String[] mandatoryTestParams = {AGENT_URL_KEY, ID_KEY, USER_KEY, PASS_KEY}; + + for (String mandatoryParam : mandatoryTestParams) { + throwIfMissingMandatoryParam(params, mandatoryParam); + } + return params.get(AGENT_URL_KEY) + "?Id=" + params.get(ID_KEY) + "&Type=GetOutput"; + } + + /** + * This method parses response from the Ansible Server when we do a post + * and returns an AnsibleResult object. + */ + public AnsibleResult parsePostResponse(String input) throws SvcLogicException { + AnsibleResult ansibleResult; + try { + JSONObject postResponse = new JSONObject(input); + + int code = postResponse.getInt(STATUS_CODE_KEY); + String msg = postResponse.getString(STATUS_MESSAGE_KEY); + + int initResponseValue = AnsibleResultCodes.INITRESPONSE.getValue(); + boolean validCode = AnsibleResultCodes.CODE.checkValidCode(initResponseValue, code); + if (!validCode) { + throw new SvcLogicException("Invalid InitResponse code = " + code + " received. MUST be one of " + + AnsibleResultCodes.CODE.getValidCodes(initResponseValue)); + } + + ansibleResult = new AnsibleResult(code, msg); + + } catch (JSONException e) { + LOGGER.error(jsonException, e); + ansibleResult = new AnsibleResult(600, "Error parsing response = " + input + ". Error = " + e.getMessage()); + } + return ansibleResult; + } + + /** + * This method parses response from an Ansible server when we do a GET for a result + * and returns an AnsibleResult object. + **/ + public AnsibleResult parseGetResponse(String input) throws SvcLogicException { + + AnsibleResult ansibleResult = new AnsibleResult(); + + try { + JSONObject postResponse = new JSONObject(input); + ansibleResult = parseGetResponseNested(ansibleResult, postResponse); + } catch (JSONException e) { + LOGGER.error(jsonException, e); + ansibleResult = new AnsibleResult(AnsibleResultCodes.INVALID_PAYLOAD.getValue(), + "Error parsing response = " + input + ". Error = " + e.getMessage(), ""); + } + return ansibleResult; + } + + private AnsibleResult parseGetResponseNested(AnsibleResult ansibleResult, JSONObject postRsp) throws SvcLogicException { + + int codeStatus = postRsp.getInt(STATUS_CODE_KEY); + String messageStatus = postRsp.getString(STATUS_MESSAGE_KEY); + int finalCode = AnsibleResultCodes.FINAL_SUCCESS.getValue(); + + boolean valCode = + AnsibleResultCodes.CODE.checkValidCode(AnsibleResultCodes.FINALRESPONSE.getValue(), codeStatus); + + if (!valCode) { + throw new SvcLogicException("Invalid FinalResponse code = " + codeStatus + " received. MUST be one of " + + AnsibleResultCodes.CODE.getValidCodes(AnsibleResultCodes.FINALRESPONSE.getValue())); + } + + ansibleResult.setStatusCode(codeStatus); + ansibleResult.setStatusMessage(messageStatus); + LOGGER.info("Received response with code = {}, Message = {}", codeStatus, messageStatus); + + if (!postRsp.isNull("Results")) { + + // Results are available. process them + // Results is a dictionary of the form + + LOGGER.info("Processing results in response"); + JSONObject results = postRsp.getJSONObject("Results"); + LOGGER.info("Get JSON dictionary from Results .."); + Iterator<String> hosts = results.keys(); + LOGGER.info("Iterating through hosts"); + + while (hosts.hasNext()) { + String host = hosts.next(); + LOGGER.info("Processing host = {}", host); + + try { + JSONObject hostResponse = results.getJSONObject(host); + int subCode = hostResponse.getInt(STATUS_CODE_KEY); + String message = hostResponse.getString(STATUS_MESSAGE_KEY); + + LOGGER.info("Code = {}, Message = {}", subCode, message); + + if (subCode != 200 || !("SUCCESS").equals(message)) { + finalCode = AnsibleResultCodes.REQ_FAILURE.getValue(); + } + } catch (JSONException e) { + LOGGER.error(jsonException, e); + ansibleResult.setStatusCode(AnsibleResultCodes.INVALID_RESPONSE.getValue()); + ansibleResult.setStatusMessage(String.format( + "Error processing response message = %s from host %s", results.getString(host), host)); + break; + } + } + + ansibleResult.setStatusCode(finalCode); + + // We return entire Results object as message + ansibleResult.setResults(results.toString()); + + } else { + ansibleResult.setStatusCode(AnsibleResultCodes.INVALID_RESPONSE.getValue()); + ansibleResult.setStatusMessage("Results not found in GET for response"); + } + return ansibleResult; + } + + private void parseOptionalParams(Map<String, String> params, String[] optionalTestParams, JSONObject jsonPayload) { + + Set<String> optionalParamsSet = new HashSet<>(); + Collections.addAll(optionalParamsSet, optionalTestParams); + + //@formatter:off + params.entrySet() + .stream() + .filter(entry -> optionalParamsSet.contains(entry.getKey())) + .filter(entry -> !Strings.isNullOrEmpty(entry.getValue())) + .forEach(entry -> parseOptionalParam(entry, jsonPayload)); + //@formatter:on + } + + private void parseOptionalParam(Map.Entry<String, String> params, JSONObject jsonPayload) { + String key = params.getKey(); + String payload = params.getValue(); + + switch (key) { + case TIMEOUT_OPT_KEY: + int timeout = Integer.parseInt(payload); + if (timeout < 0) { + throw new NumberFormatException(" : specified negative integer for timeout = " + payload); + } + jsonPayload.put(key, payload); + break; + + case VERSION_OPT_KEY: + jsonPayload.put(key, payload); + break; + + case LOCAL_PARAMETERS_OPT_KEY: + case ENV_PARAMETERS_OPT_KEY: + JSONObject paramsJson = new JSONObject(payload); + jsonPayload.put(key, paramsJson); + break; + + case NODE_LIST_OPT_KEY: + JSONArray paramsArray = new JSONArray(payload); + jsonPayload.put(key, paramsArray); + break; + + case FILE_PARAMETERS_OPT_KEY: + jsonPayload.put(key, getFilePayload(payload)); + break; + + default: + break; + } + } + + /** + * Return payload with escaped newlines + */ + private JSONObject getFilePayload(String payload) { + String formattedPayload = payload.replace("\n", "\\n").replace("\r", "\\r"); + return new JSONObject(formattedPayload); + } + + private void throwIfMissingMandatoryParam(Map<String, String> params, String key) throws SvcLogicException { + if (!params.containsKey(key)) { + throw new SvcLogicException(String.format( + "Ansible: Mandatory AnsibleAdapter key %s not found in parameters provided by calling agent !", + key)); + } + if (Strings.isNullOrEmpty(params.get(key))) { + throw new SvcLogicException(String.format( + "Ansible: Mandatory AnsibleAdapter key %s not found in parameters provided by calling agent !", + key)); + } + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleResult.java b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleResult.java new file mode 100644 index 000000000..3d1b3cfab --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleResult.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ansible.model; + +/** + * Simple class to store code and message returned by POST/GET to an Ansible Server + */ +public class AnsibleResult { + + private static final String EMPTY_VALUE = "UNKNOWN"; + + private int statusCode; + private String statusMessage; + private String results; + + public AnsibleResult() { + this(-1, EMPTY_VALUE, EMPTY_VALUE); + } + + public AnsibleResult(int code, String message) { + this(code, message, EMPTY_VALUE); + } + + public AnsibleResult(int code, String message, String result) { + statusCode = code; + statusMessage = message; + results = result; + } + + public void setStatusCode(int code) { + this.statusCode = code; + } + + public void setStatusMessage(String message) { + this.statusMessage = message; + } + + public void setResults(String results) { + this.results = results; + } + + void set(int code, String message, String results) { + this.statusCode = code; + this.statusMessage = message; + this.results = results; + } + + public int getStatusCode() { + return this.statusCode; + } + + public String getStatusMessage() { + return this.statusMessage; + } + + public String getResults() { + return this.results; + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleResultCodes.java b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleResultCodes.java new file mode 100644 index 000000000..a529e4a0c --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleResultCodes.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ansible.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * enum of the various codes that APP-C uses to resolve different + * status of response from Ansible Server + **/ + +public enum AnsibleResultCodes { + + // @formatter:off + SUCCESS(400), + KEYSTORE_EXCEPTION(622), + CERTIFICATE_ERROR(610), + IO_EXCEPTION(611), + HOST_UNKNOWN(625), + USER_UNAUTHORIZED(613), + UNKNOWN_EXCEPTION(699), + SSL_EXCEPTION(697), + INVALID_PAYLOAD(698), + INVALID_RESPONSE(601), + PENDING(100), + REJECTED(101), + FINAL_SUCCESS(200), + REQ_FAILURE(401), + MESSAGE(1), + CODE(0), + INITRESPONSE(0), + FINALRESPONSE(1); + // @formatter:on + + private final Set<Integer> initCodes = new HashSet<>(Arrays.asList(100, 101)); + private final Set<Integer> finalCodes = new HashSet<>(Arrays.asList(200, 500)); + private final ArrayList<Set<Integer>> codeSets = new ArrayList<>(Arrays.asList(initCodes, finalCodes)); + private final Set<String> messageSet = new HashSet<>(Arrays.asList("PENDING", "FINISHED", "TERMINATED")); + private final int value; + + AnsibleResultCodes(int value) { + this.value = value; + }; + + public int getValue() { + return value; + } + + public boolean checkValidCode(int type, int code) { + return codeSets.get(type).contains(code); + } + + public String getValidCodes(int type) { + StringBuilder sb = new StringBuilder("[ "); + codeSets.get(type).stream().forEach(s -> sb.append(s).append(",")); + return sb.append("]").toString(); + } + + public boolean checkValidMessage(String message) { + return messageSet.contains(message); + } + + public String getValidMessages() { + StringBuilder sb = new StringBuilder("[ "); + messageSet.stream().forEach(s -> sb.append(s).append(",")); + return sb.append("]").toString(); + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleServerEmulator.java b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleServerEmulator.java new file mode 100644 index 000000000..993c70062 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/ansible/model/AnsibleServerEmulator.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + + + +/* + * Class to emulate responses from the Ansible Server that is compliant with the APP-C Ansible Server + * Interface. Used for jUnit tests to verify code is working. In tests it can be used + * as a replacement for methods from ConnectionBuilder class + */ + +package org.onap.ccsdk.sli.adaptors.ansible.model; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.lang.StringUtils; +import org.json.JSONException; +import org.json.JSONObject; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class AnsibleServerEmulator { + + private final EELFLogger logger = EELFManager.getInstance().getLogger(AnsibleServerEmulator.class); + + private static final String PLAYBOOK_NAME = "PlaybookName"; + private static final String STATUS_CODE = "StatusCode"; + private static final String STATUS_MESSAGE = "StatusMessage"; + + private String playbookName = "test_playbook.yaml"; + + /** + * Method that emulates the response from an Ansible Server + * when presented with a request to execute a playbook + * Returns an ansible object result. The response code is always the http code 200 (i.e connection successful) + * payload is json string as would be sent back by Ansible Server + **/ + public AnsibleResult Post(String agentUrl, String payload) { + AnsibleResult result = new AnsibleResult(); + + try { + // Request must be a JSON object + + JSONObject message = new JSONObject(payload); + if (message.isNull("Id")) { + rejectRequest(result, "Must provide a valid Id"); + } else if (message.isNull(PLAYBOOK_NAME)) { + rejectRequest(result, "Must provide a playbook Name"); + } else if (!message.getString(PLAYBOOK_NAME).equals(playbookName)) { + rejectRequest(result, "Playbook " + message.getString(PLAYBOOK_NAME) + " not found in catalog"); + } else { + acceptRequest(result); + } + } catch (JSONException e) { + logger.error("JSONException caught", e); + rejectRequest(result, e.getMessage()); + } + return result; + } + + /** + * Method to emulate response from an Ansible + * Server when presented with a GET request + * Returns an ansibl object result. The response code is always the http code 200 (i.e connection successful) + * payload is json string as would be sent back by Ansible Server + * + **/ + public AnsibleResult Get(String agentUrl) { + + Pattern pattern = Pattern.compile(".*?\\?Id=(.*?)&Type.*"); + Matcher matcher = pattern.matcher(agentUrl); + String id = StringUtils.EMPTY; + String vmAddress = "192.168.1.10"; + + if (matcher.find()) { + id = matcher.group(1); + } + + AnsibleResult getResult = new AnsibleResult(); + + JSONObject response = new JSONObject(); + response.put(STATUS_CODE, 200); + response.put(STATUS_MESSAGE, "FINISHED"); + + JSONObject results = new JSONObject(); + + JSONObject vmResults = new JSONObject(); + vmResults.put(STATUS_CODE, 200); + vmResults.put(STATUS_MESSAGE, "SUCCESS"); + vmResults.put("Id", id); + results.put(vmAddress, vmResults); + + response.put("Results", results); + + getResult.setStatusCode(200); + getResult.setStatusMessage(response.toString()); + + return getResult; + } + + private void rejectRequest(AnsibleResult result, String Message) { + result.setStatusCode(200); + JSONObject response = new JSONObject(); + response.put(STATUS_CODE, AnsibleResultCodes.REJECTED.getValue()); + response.put(STATUS_MESSAGE, Message); + result.setStatusMessage(response.toString()); + } + + private void acceptRequest(AnsibleResult result) { + result.setStatusCode(200); + JSONObject response = new JSONObject(); + response.put(STATUS_CODE, AnsibleResultCodes.PENDING.getValue()); + response.put(STATUS_MESSAGE, "PENDING"); + result.setStatusMessage(response.toString()); + } +}
\ No newline at end of file diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/resources/OSGI-INF/blueprint/ansible-adapter-blueprint.xml b/ansible-adapter/ansible-adapter-bundle/src/main/resources/OSGI-INF/blueprint/ansible-adapter-blueprint.xml new file mode 100755 index 000000000..d7be01e9d --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/resources/OSGI-INF/blueprint/ansible-adapter-blueprint.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 - 2018 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" class="org.onap.ccsdk.sli.adaptors.ansible.impl.AnsibleAdapterPropertiesProviderImpl" /> + + <bean id="ansibleAdapterInstance" class="org.onap.ccsdk.sli.adaptors.ansible.impl.AnsibleAdapterImpl"> + <argument ref="propProvider"/> + </bean> + + <service ref="ansibleAdapterInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.ansible.AnsibleAdapter</value> + </interfaces> + </service> + +</blueprint> diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/resources/ansible-adapter.properties b/ansible-adapter/ansible-adapter-bundle/src/main/resources/ansible-adapter.properties new file mode 100644 index 000000000..761758bbb --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/resources/ansible-adapter.properties @@ -0,0 +1,48 @@ +### +# ============LICENSE_START======================================================= +# ONAP : APPC +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Copyright (C) 2017 Amdocs +# ============================================================================= +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# ============LICENSE_END========================================================= +### + +# +# Default properties for the APP-C TestService Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.onap.appc.bootstrap.file=appc.properties +org.onap.appc.bootstrap.path=${user.home},/opt/opendaylight/current/properties + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.onap.appc.resources=org.onap/appc/i18n/MessageResources +# +# The name of the adapter. +org.onap.appc.provider.adaptor.name=org.onap.appc.appc_ansible_adapter + + +# Default truststore path and password +org.onap.appc.adapter.ansible.trustStore=/opt/opendaylight/tls-client/mykeystore.js +org.onap.appc.adapter.ansible.trustStore.trustPasswd=changeit +org.onap.appc.adapter.ansible.clientType=TRUST_ALL diff --git a/ansible-adapter/ansible-adapter-bundle/src/main/resources/org/opendaylight/blueprint/ansible-adapter-blueprint.xml b/ansible-adapter/ansible-adapter-bundle/src/main/resources/org/opendaylight/blueprint/ansible-adapter-blueprint.xml new file mode 100755 index 000000000..d7be01e9d --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/main/resources/org/opendaylight/blueprint/ansible-adapter-blueprint.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 - 2018 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" class="org.onap.ccsdk.sli.adaptors.ansible.impl.AnsibleAdapterPropertiesProviderImpl" /> + + <bean id="ansibleAdapterInstance" class="org.onap.ccsdk.sli.adaptors.ansible.impl.AnsibleAdapterImpl"> + <argument ref="propProvider"/> + </bean> + + <service ref="ansibleAdapterInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.ansible.AnsibleAdapter</value> + </interfaces> + </service> + +</blueprint> diff --git a/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/impl/TestAnsibleAdapterImpl.java b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/impl/TestAnsibleAdapterImpl.java new file mode 100644 index 000000000..4636d2450 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/impl/TestAnsibleAdapterImpl.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.adapter.ansible.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.ansible.impl.AnsibleAdapterImpl; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + + +public class TestAnsibleAdapterImpl { + + private final String PENDING = "100"; + private final String SUCCESS = "400"; + private String message = "{\"Results\":{\"192.168.1.10\":{\"Id\":\"101\",\"StatusCode\":200,\"StatusMessage\":\"SUCCESS\"}},\"StatusCode\":200,\"StatusMessage\":\"FINISHED\"}"; + + private AnsibleAdapterImpl adapter; + private String TestId; + private boolean testMode = true; + private Map<String, String> params; + private SvcLogicContext svcContext; + + + @Before + public void setup() throws IllegalArgumentException { + testMode = true; + svcContext = new SvcLogicContext(); + adapter = new AnsibleAdapterImpl(testMode); + + params = new HashMap<>(); + params.put("AgentUrl", "https://192.168.1.1"); + params.put("User", "test"); + params.put("Password", "test"); + } + + @After + public void tearDown() { + testMode = false; + adapter = null; + params = null; + svcContext = null; + } + + @Test + public void reqExec_shouldSetPending() throws IllegalStateException, IllegalArgumentException { + + params.put("PlaybookName", "test_playbook.yaml"); + + try { + adapter.reqExec(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.ansible.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.ansible.result.Id"); + System.out.println("Comparing " + PENDING + " and " + status); + assertEquals(PENDING, status); + } catch (SvcLogicException e) { + String status = svcContext.getAttribute("org.onap.appc.adapter.ansible.result.code"); + fail(e.getMessage() + " Code = " + status); + } catch (Exception e) { + fail(e.getMessage() + " Unknown exception encountered "); + } + } + + @Test + public void reqExecResult_shouldSetSuccess() throws IllegalStateException, IllegalArgumentException { + + params.put("Id", "100"); + + for (String ukey : params.keySet()) { + System.out.println(String.format("Ansible Parameter %s = %s", ukey, params.get(ukey))); + } + + try { + adapter.reqExecResult(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.ansible.result.code"); + assertEquals(SUCCESS, status); + } catch (SvcLogicException e) { + String status = svcContext.getAttribute("org.onap.appc.adapter.ansible.result.code"); + fail(e.getMessage() + " Code = " + status); + } catch (Exception e) { + fail(e.getMessage() + " Unknown exception encountered "); + } + } + + @Test + public void reqExecLog_shouldSetMessage() throws IllegalStateException, IllegalArgumentException { + + params.put("Id", "101"); + + try { + adapter.reqExecLog(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.ansible.log"); + assertEquals(message, status); + } catch (SvcLogicException e) { + String status = svcContext.getAttribute("org.onap.appc.adapter.ansible.log"); + fail(e.getMessage() + " Code = " + status); + } catch (Exception e) { + fail(e.getMessage() + " Unknown exception encountered "); + } + } + + @Test + public void reqExecOutput_shouldSetMessage() throws IllegalStateException, IllegalArgumentException { + + params.put("Id", "101"); + + try { + adapter.reqExecOutput(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.ansible.output"); + assertEquals(message, status); + } catch (SvcLogicException e) { + String status = svcContext.getAttribute("org.onap.appc.adapter.ansible.output"); + fail(e.getMessage() + " Code = " + status); + } catch (Exception e) { + fail(e.getMessage() + " Unknown exception encountered "); + } + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/impl/TestAnsibleAdapterPropertiesProviderImpl.java b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/impl/TestAnsibleAdapterPropertiesProviderImpl.java new file mode 100644 index 000000000..b3c01e9bd --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/impl/TestAnsibleAdapterPropertiesProviderImpl.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2018 Samsung + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.adapter.ansible.impl; + +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.ansible.impl.AnsibleAdapterPropertiesProviderImpl; + +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +public class TestAnsibleAdapterPropertiesProviderImpl { + AnsibleAdapterPropertiesProviderImpl adaptor; + @Before + public void setup() throws IllegalArgumentException { + adaptor = new AnsibleAdapterPropertiesProviderImpl(); + } + + + @Test + public void testGetProperties() throws IllegalStateException, IllegalArgumentException { + Properties prop = adaptor.getProperties(); + + System.out.println("All Property params : " + prop); + assertEquals("TRUST_ALL", prop.getProperty("org.onap.appc.adapter.ansible.clientType")); + assertEquals("org.onap.appc.appc_ansible_adapter", prop.getProperty("org.onap.appc.provider.adaptor.name")); + assertEquals("changeit", prop.getProperty("org.onap.appc.adapter.ansible.trustStore.trustPasswd")); + assertEquals("${user.home},/opt/opendaylight/current/properties", prop.getProperty("org.onap.appc.bootstrap.path")); + assertEquals("APPC", prop.getProperty("appc.application.name")); + assertEquals("appc.properties", prop.getProperty("org.onap.appc.bootstrap.file")); + assertEquals("org.onap/appc/i18n/MessageResources", prop.getProperty("org.onap.appc.resources")); + assertEquals("/opt/opendaylight/tls-client/mykeystore.js", prop.getProperty("org.onap.appc.adapter.ansible.trustStore")); + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/impl/TestConnectionBuilder.java b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/impl/TestConnectionBuilder.java new file mode 100644 index 000000000..c94655f56 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/impl/TestConnectionBuilder.java @@ -0,0 +1,155 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2018 Samsung + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.adapter.ansible.impl; + +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.ansible.impl.ConnectionBuilder; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleResult; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +import javax.net.ssl.SSLException; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +import static org.junit.Assert.assertEquals; + +public class TestConnectionBuilder { + ConnectionBuilder builder; + @Before + public void setup() + throws SSLException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { + builder = new ConnectionBuilder(1); + } + + + @Test + public void testSetHttpContext() throws IllegalStateException, IllegalArgumentException { + String user = "testUser"; + String pass = "testPassword"; + + builder.setHttpContext(user, pass); + } + + @Test + public void testPost() throws IllegalStateException, IllegalArgumentException { + String user = "testUser"; + String pass = "testPassword"; + String agentUrl = "test/server.com"; + String payload = "testPayload"; + + builder.setHttpContext(user, pass); + AnsibleResult result = builder.post(agentUrl, payload); + + assertEquals(611, result.getStatusCode()); + assertEquals(null, result.getStatusMessage()); + assertEquals("UNKNOWN", result.getResults()); + } + + @Test + public void testGet() throws IllegalStateException, IllegalArgumentException { + String user = "testUser"; + String pass = "testPassword"; + String agentUrl = "test/server.com"; + + builder.setHttpContext(user, pass); + AnsibleResult result = builder.get(agentUrl); + + assertEquals(611, result.getStatusCode()); + assertEquals(null, result.getStatusMessage()); + assertEquals("UNKNOWN", result.getResults()); + } + + @Test + public void testGetMode() + throws SSLException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { + String user = "testUser"; + String pass = "testPassword"; + String agentUrl = "test/server.com"; + + builder = new ConnectionBuilder(2); + builder.setHttpContext(user, pass); + AnsibleResult result = builder.get(agentUrl); + + assertEquals(611, result.getStatusCode()); + assertEquals(null, result.getStatusMessage()); + assertEquals("UNKNOWN", result.getResults()); + } + + @Test (expected = FileNotFoundException.class) + public void testGetModeNoCert() + throws KeyStoreException, CertificateException, IOException, + KeyManagementException, NoSuchAlgorithmException, SvcLogicException { + String user = "testUser"; + String pass = "testPassword"; + String agentUrl = "test/server.com"; + String certFile = "testCert"; + + builder = new ConnectionBuilder(certFile); + builder.setHttpContext(user, pass); + AnsibleResult result = builder.get(agentUrl); + + assertEquals(611, result.getStatusCode()); + assertEquals(null, result.getStatusMessage()); + assertEquals("UNKNOWN", result.getResults()); + } + + @Test + public void testGetModeCert() + throws KeyStoreException, CertificateException, IOException, + KeyManagementException, NoSuchAlgorithmException, SvcLogicException { + String user = "testUser"; + String pass = "testPassword"; + String agentUrl = "test/server.com"; + String certFile = "src/test/resources/cert"; + + builder = new ConnectionBuilder(certFile); + builder.setHttpContext(user, pass); + AnsibleResult result = builder.get(agentUrl); + + assertEquals(611, result.getStatusCode()); + assertEquals(null, result.getStatusMessage()); + assertEquals("UNKNOWN", result.getResults()); + } + + @Test (expected = IOException.class) + public void testGetModeStore() + throws KeyStoreException, CertificateException, IOException, + KeyManagementException, NoSuchAlgorithmException, SvcLogicException { + String user = "testUser"; + String pass = "testPassword"; + String agentUrl = "test/server.com"; + String store = "src/test/resources/cert"; + + builder = new ConnectionBuilder(store, new char['t'] ); + builder.setHttpContext(user, pass); + AnsibleResult result = builder.get(agentUrl); + + assertEquals(611, result.getStatusCode()); + assertEquals(null, result.getStatusMessage()); + assertEquals("UNKNOWN", result.getResults()); + } + +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/model/TestAnsibleAdapter.java b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/model/TestAnsibleAdapter.java new file mode 100644 index 000000000..6fc90d012 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/adapter/ansible/model/TestAnsibleAdapter.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ +package org.onap.ccsdk.adapter.ansible.model; + +import static org.junit.Assert.assertNotNull; + +import java.util.HashMap; +import java.util.Map; +import java.lang.reflect.*; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleMessageParser; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleResult; +import org.onap.ccsdk.sli.adaptors.ansible.model.AnsibleServerEmulator; + +public class TestAnsibleAdapter { + + private Class[] parameterTypes; + private AnsibleMessageParser ansibleMessageParser; + private Method m; + private String name; + + @Test + public void callPrivateConstructorsMethodsForCodeCoverage() throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { + + /* test constructors */ + Class<?>[] classesOne = {AnsibleMessageParser.class}; + for(Class<?> clazz : classesOne) { + Constructor<?> constructor = clazz.getDeclaredConstructor(); + name = constructor.getName(); + constructor.setAccessible(true); + assertNotNull(constructor.newInstance()); + } + Class<?>[] classesTwo = {AnsibleServerEmulator.class}; + for(Class<?> clazz : classesTwo) { + Constructor<?> constructor = clazz.getDeclaredConstructor(); + name = constructor.getName(); + constructor.setAccessible(true); + assertNotNull(constructor.newInstance()); + } + Class<?>[] classesThree = {AnsibleResult.class}; + for(Class<?> clazz : classesThree) { + Constructor<?> constructor = clazz.getDeclaredConstructor(); + name = constructor.getName(); + constructor.setAccessible(true); + assertNotNull(constructor.newInstance()); + } + + /* test methods */ + ansibleMessageParser = new AnsibleMessageParser(); + parameterTypes = new Class[1]; + parameterTypes[0] = java.lang.String.class; + + m = ansibleMessageParser.getClass().getDeclaredMethod("getFilePayload", parameterTypes); + m.setAccessible(true); + assertNotNull(m.invoke(ansibleMessageParser,"{\"test\": test}")); + + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/test/ExecutorHarness.java b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/test/ExecutorHarness.java new file mode 100644 index 000000000..3555d7dfe --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/test/ExecutorHarness.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + + +package org.onap.ccsdk.test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; + +/** + * This class is used as a test harness to wrap the call to an executor node. + */ + +public class ExecutorHarness { + + /** + * The executor to be tested + */ + private SvcLogicJavaPlugin executor; + + /** + * The collection of all exec methods found on the class + */ + private Map<String, Method> methods; + + /** + * The field of the class being tested that contains the reference to the logger to be used. This is modified to + * point to our interception logger for the test. + */ + private Field contextLogger; + + /** + * The interception logger that buffers all messages logged and allows us to look at them as part of the test case. + */ + private InterceptLogger logger; + + /** + * Create the harness and initialize it + * + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + @SuppressWarnings("nls") + public ExecutorHarness() throws NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException { + methods = new HashMap<>(); + new SvcLogicContext(); + + Class<?> contextClass = SvcLogicContext.class; + contextLogger = contextClass.getDeclaredField("LOG"); + contextLogger.setAccessible(true); + logger = new InterceptLogger(); + contextLogger.set(null, logger); + } + + /** + * Convenience constructor + * + * @param executor + * The executor to be tested by the harness + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + public ExecutorHarness(SvcLogicJavaPlugin executor) throws NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + this(); + setExecutor(executor); + } + + /** + * @param executor + * The java plugin class to be executed + */ + public void setExecutor(SvcLogicJavaPlugin executor) { + this.executor = executor; + scanExecutor(); + } + + /** + * @return The java plugin class to be executed + */ + public SvcLogicJavaPlugin getExecutor() { + return executor; + } + + /** + * @return The set of all methods that meet the signature requirements + */ + public List<String> getExecMethodNames() { + List<String> names = new ArrayList<>(); + names.addAll(methods.keySet()); + return names; + } + + /** + * Returns an indication if the named method is a valid executor method that could be called from a DG execute node + * + * @param methodName + * The method name to be validated + * @return True if the method name meets the signature requirements, false if the method either does not exist or + * does not meet the requirements. + */ + public boolean isExecMethod(String methodName) { + return methods.containsKey(methodName); + } + + /** + * This method scans the executor class hierarchy to locate all methods that match the required signature of the + * executor and records these methods in a map. + */ + private void scanExecutor() { + methods.clear(); + Class<?> executorClass = executor.getClass(); + Method[] publicMethods = executorClass.getMethods(); + for (Method method : publicMethods) { + if (method.getReturnType().equals(Void.class)) { + Class<?>[] paramTypes = method.getParameterTypes(); + if (paramTypes.length == 2) { + if (Map.class.isAssignableFrom(paramTypes[0]) + && SvcLogicContext.class.isAssignableFrom(paramTypes[1])) { + methods.put(method.getName(), method); + } + } + } + } + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/test/InterceptLogger.java b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/test/InterceptLogger.java new file mode 100644 index 000000000..92235cb39 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/test/java/org/onap/ccsdk/test/InterceptLogger.java @@ -0,0 +1,454 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + + +package org.onap.ccsdk.test; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; + +/** + * This class is used as an intercept logger that can be used in testing to intercept and record all messages that are + * logged, thus allowing a junit test case to examine the log output and make assertions. + */ +public class InterceptLogger implements org.slf4j.Logger { + + /** + * This inner class represents an intercepted log event + */ + public class LogRecord { + private Level level; + private String message; + private long timestamp; + private Throwable t; + + public LogRecord(Level level, String message) { + setLevel(level); + setTimestamp(System.currentTimeMillis()); + setMessage(message); + } + + public LogRecord(Level level, String message, Throwable t) { + this(level, message); + setThrowable(t); + } + + /** + * @return the value of level + */ + public Level getLevel() { + return level; + } + + /** + * @return the value of message + */ + public String getMessage() { + return message; + } + + /** + * @return the value of timestamp + */ + public long getTimestamp() { + return timestamp; + } + + /** + * @param level + * the value for level + */ + public void setLevel(Level level) { + this.level = level; + } + + /** + * @param message + * the value for message + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * @param timestamp + * the value for timestamp + */ + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + /** + * @return the value of t + */ + public Throwable getThrowable() { + return t; + } + + /** + * @param t + * the value for t + */ + public void setThrowable(Throwable t) { + this.t = t; + } + + } + + /** + * The list of all intercepted log events + */ + private List<LogRecord> events; + + /** + * Create the intercept logger + */ + public InterceptLogger() { + events = new ArrayList<LogRecord>(1000); + } + + /** + * @return Returns all intercepted log events + */ + public List<LogRecord> getLogRecords() { + return events; + } + + /** + * Clears all log events + */ + public void clear() { + events.clear(); + } + + @Override + public void debug(Marker marker, String msg) { + debug(msg); + } + + @Override + public void debug(Marker marker, String format, Object arg) { + debug(MessageFormat.format(format, arg)); + } + + @Override + public void debug(Marker marker, String format, Object... arguments) { + debug(MessageFormat.format(format, arguments)); + } + + @Override + public void debug(Marker marker, String format, Object arg1, Object arg2) { + debug(MessageFormat.format(format, arg1, arg2)); + } + + @Override + public void debug(Marker marker, String msg, Throwable t) { + debug(msg, t); + } + + @Override + public void debug(String msg) { + events.add(new LogRecord(Level.DEBUG, msg)); + } + + @Override + public void debug(String format, Object arg) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg))); + } + + @Override + public void debug(String format, Object... arguments) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arguments))); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void debug(String msg, Throwable t) { + events.add(new LogRecord(Level.DEBUG, msg, t)); + } + + @Override + public void error(Marker marker, String msg) { + error(msg); + } + + @Override + public void error(Marker marker, String format, Object arg) { + error(format, arg); + } + + @Override + public void error(Marker marker, String format, Object... arguments) { + error(format, arguments); + } + + @Override + public void error(Marker marker, String format, Object arg1, Object arg2) { + error(format, arg1, arg2); + } + + @Override + public void error(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public void error(String msg) { + events.add(new LogRecord(Level.ERROR, msg)); + } + + @Override + public void error(String format, Object arg) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg))); + } + + @Override + public void error(String format, Object... arguments) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arguments))); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void error(String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public String getName() { + return null; + } + + @Override + public void info(Marker marker, String msg) { + info(msg); + } + + @Override + public void info(Marker marker, String format, Object arg) { + info(format, arg); + } + + @Override + public void info(Marker marker, String format, Object... arguments) { + info(format, arguments); + } + + @Override + public void info(Marker marker, String format, Object arg1, Object arg2) { + info(format, arg1, arg2); + } + + @Override + public void info(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public void info(String msg) { + events.add(new LogRecord(Level.INFO, msg)); + } + + @Override + public void info(String format, Object arg) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg))); + } + + @Override + public void info(String format, Object... arguments) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arguments))); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void info(String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public boolean isDebugEnabled() { + return true; + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return true; + } + + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return true; + } + + @Override + public boolean isInfoEnabled() { + return true; + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return true; + } + + @Override + public boolean isTraceEnabled() { + return true; + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return true; + } + + @Override + public boolean isWarnEnabled() { + return true; + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return true; + } + + @Override + public void trace(Marker marker, String msg) { + trace(msg); + } + + @Override + public void trace(Marker marker, String format, Object arg) { + trace(format, arg); + } + + @Override + public void trace(Marker marker, String format, Object... argArray) { + trace(format, argArray); + } + + @Override + public void trace(Marker marker, String format, Object arg1, Object arg2) { + trace(format, arg1, arg2); + } + + @Override + public void trace(Marker marker, String msg, Throwable t) { + trace(msg, t); + } + + @Override + public void trace(String msg) { + events.add(new LogRecord(Level.TRACE, msg)); + } + + @Override + public void trace(String format, Object arg) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg))); + } + + @Override + public void trace(String format, Object... arguments) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arguments))); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void trace(String msg, Throwable t) { + events.add(new LogRecord(Level.TRACE, msg, t)); + } + + @Override + public void warn(Marker marker, String msg) { + warn(msg); + } + + @Override + public void warn(Marker marker, String format, Object arg) { + warn(format, arg); + } + + @Override + public void warn(Marker marker, String format, Object... arguments) { + warn(format, arguments); + } + + @Override + public void warn(Marker marker, String format, Object arg1, Object arg2) { + warn(format, arg1, arg2); + } + + @Override + public void warn(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } + + @Override + public void warn(String msg) { + events.add(new LogRecord(Level.WARN, msg)); + } + + @Override + public void warn(String format, Object arg) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg))); + } + + @Override + public void warn(String format, Object... arguments) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arguments))); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void warn(String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } +} diff --git a/ansible-adapter/ansible-adapter-bundle/src/test/resources/cert b/ansible-adapter/ansible-adapter-bundle/src/test/resources/cert new file mode 100644 index 000000000..cc2921c4b --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/test/resources/cert @@ -0,0 +1,125 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=FR, ST=Alsace, L=Strasbourg, O=www.freelan.org, OU=freelan, CN=Freelan Sample Certificate Authority/emailAddress=contact@freelan.org + Validity + Not Before: Apr 27 10:31:18 2012 GMT + Not After : Apr 25 10:31:18 2022 GMT + Subject: C=FR, ST=Alsace, O=www.freelan.org, OU=freelan, CN=alice/emailAddress=contact@freelan.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:dd:6d:bd:f8:80:fa:d7:de:1b:1f:a7:a3:2e:b2: + 02:e2:16:f6:52:0a:3c:bf:a6:42:f8:ca:dc:93:67: + 4d:60:c3:4f:8d:c3:8a:00:1b:f1:c4:4b:41:6a:69: + d2:69:e5:3f:21:8e:c5:0b:f8:22:37:ad:b6:2c:4b: + 55:ff:7a:03:72:bb:9a:d3:ec:96:b9:56:9f:cb:19: + 99:c9:32:94:6f:8f:c6:52:06:9f:45:03:df:fd:e8: + 97:f6:ea:d6:ba:bb:48:2b:b5:e0:34:61:4d:52:36: + 0f:ab:87:52:25:03:cf:87:00:87:13:f2:ca:03:29: + 16:9d:90:57:46:b5:f4:0e:ae:17:c8:0a:4d:92:ed: + 08:a6:32:23:11:71:fe:f2:2c:44:d7:6c:07:f3:0b: + 7b:0c:4b:dd:3b:b4:f7:37:70:9f:51:b6:88:4e:5d: + 6a:05:7f:8d:9b:66:7a:ab:80:20:fe:ee:6b:97:c3: + 49:7d:78:3b:d5:99:97:03:75:ce:8f:bc:c5:be:9c: + 9a:a5:12:19:70:f9:a4:bd:96:27:ed:23:02:a7:c7: + 57:c9:71:cf:76:94:a2:21:62:f6:b8:1d:ca:88:ee: + 09:ad:46:2f:b7:61:b3:2c:15:13:86:9f:a5:35:26: + 5a:67:f4:37:c8:e6:80:01:49:0e:c7:ed:61:d3:cd: + bc:e4:f8:be:3f:c9:4e:f8:7d:97:89:ce:12:bc:ca: + b5:c6:d2:e0:d9:b3:68:3c:2e:4a:9d:b4:5f:b8:53: + ee:50:3d:bf:dd:d4:a2:8a:b6:a0:27:ab:98:0c:b3: + b2:58:90:e2:bc:a1:ad:ff:bd:8e:55:31:0f:00:bf: + 68:e9:3d:a9:19:9a:f0:6d:0b:a2:14:6a:c6:4c:c6: + 4e:bd:63:12:a5:0b:4d:97:eb:42:09:79:53:e2:65: + aa:24:34:70:b8:c1:ab:23:80:e7:9c:6c:ed:dc:82: + aa:37:04:b8:43:2a:3d:2a:a8:cc:20:fc:27:5d:90: + 26:58:f9:b7:14:e2:9e:e2:c1:70:73:97:e9:6b:02: + 8e:d3:52:59:7b:00:ec:61:30:f1:56:3f:9c:c1:7c: + 05:c5:b1:36:c8:18:85:cf:61:40:1f:07:e8:a7:06: + 87:df:9a:77:0b:a9:64:72:03:f6:93:fc:e0:02:59: + c1:96:ec:c0:09:42:3e:30:a2:7f:1b:48:2f:fe:e0: + 21:8f:53:87:25:0d:cb:ea:49:f5:4a:9b:d0:e3:5f: + ee:78:18:e5:ba:71:31:a9:04:98:0f:b1:ad:67:52: + a0:f2:e3:9c:ab:6a:fe:58:84:84:dd:07:3d:32:94: + 05:16:45:15:96:59:a0:58:6c:18:0e:e3:77:66:c7: + b3:f7:99 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 59:5F:C9:13:BA:1B:CC:B9:A8:41:4A:8A:49:79:6A:36:F6:7D:3E:D7 + X509v3 Authority Key Identifier: + keyid:23:6C:2D:3D:3E:29:5D:78:B8:6C:3E:AA:E2:BB:2E:1E:6C:87:F2:53 + + Signature Algorithm: sha1WithRSAEncryption + 13:e7:02:45:3e:a7:ab:bd:b8:da:e7:ef:74:88:ac:62:d5:dd: + 10:56:d5:46:07:ec:fa:6a:80:0c:b9:62:be:aa:08:b4:be:0b: + eb:9a:ef:68:b7:69:6f:4d:20:92:9d:18:63:7a:23:f4:48:87: + 6a:14:c3:91:98:1b:4e:08:59:3f:91:80:e9:f4:cf:fd:d5:bf: + af:4b:e4:bd:78:09:71:ac:d0:81:e5:53:9f:3e:ac:44:3e:9f: + f0:bf:5a:c1:70:4e:06:04:ef:dc:e8:77:05:a2:7d:c5:fa:80: + 58:0a:c5:10:6d:90:ca:49:26:71:84:39:b7:9a:3e:e9:6f:ae: + c5:35:b6:5b:24:8c:c9:ef:41:c3:b1:17:b6:3b:4e:28:89:3c: + 7e:87:a8:3a:a5:6d:dc:39:03:20:20:0b:c5:80:a3:79:13:1e: + f6:ec:ae:36:df:40:74:34:87:46:93:3b:a3:e0:a4:8c:2f:43: + 4c:b2:54:80:71:76:78:d4:ea:12:28:d8:f2:e3:80:55:11:9b: + f4:65:dc:53:0e:b4:4c:e0:4c:09:b4:dc:a0:80:5c:e6:b5:3b: + 95:d3:69:e4:52:3d:5b:61:86:02:e5:fd:0b:00:3a:fa:b3:45: + cc:c9:a3:64:f2:dc:25:59:89:58:0d:9e:6e:28:3a:55:45:50: + 5f:88:67:2a:d2:e2:48:cc:8b:de:9a:1b:93:ae:87:e1:f2:90: + 50:40:d9:0f:44:31:53:46:ad:62:4e:8d:48:86:19:77:fc:59: + 75:91:79:35:59:1d:e3:4e:33:5b:e2:31:d7:ee:52:28:5f:0a: + 70:a7:be:bb:1c:03:ca:1a:18:d0:f5:c1:5b:9c:73:04:b6:4a: + e8:46:52:58:76:d4:6a:e6:67:1c:0e:dc:13:d0:61:72:a0:92: + cb:05:97:47:1c:c1:c9:cf:41:7d:1f:b1:4d:93:6b:53:41:03: + 21:2b:93:15:63:08:3e:2c:86:9e:7b:9f:3a:09:05:6a:7d:bb: + 1c:a7:b7:af:96:08:cb:5b:df:07:fb:9c:f2:95:11:c0:82:81: + f6:1b:bf:5a:1e:58:cd:28:ca:7d:04:eb:aa:e9:29:c4:82:51: + 2c:89:61:95:b6:ed:a5:86:7c:7c:48:1d:ec:54:96:47:79:ea: + fc:7f:f5:10:43:0a:9b:00:ef:8a:77:2e:f4:36:66:d2:6a:a6: + 95:b6:9f:23:3b:12:e2:89:d5:a4:c1:2c:91:4e:cb:94:e8:3f: + 22:0e:21:f9:b8:4a:81:5c:4c:63:ae:3d:05:b2:5c:5c:54:a7: + 55:8f:98:25:55:c4:a6:90:bc:19:29:b1:14:d4:e2:b0:95:e4: + ff:89:71:61:be:8a:16:85 +-----BEGIN CERTIFICATE----- +MIIGJzCCBA+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBsjELMAkGA1UEBhMCRlIx +DzANBgNVBAgMBkFsc2FjZTETMBEGA1UEBwwKU3RyYXNib3VyZzEYMBYGA1UECgwP +d3d3LmZyZWVsYW4ub3JnMRAwDgYDVQQLDAdmcmVlbGFuMS0wKwYDVQQDDCRGcmVl +bGFuIFNhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxIjAgBgkqhkiG9w0BCQEW +E2NvbnRhY3RAZnJlZWxhbi5vcmcwHhcNMTIwNDI3MTAzMTE4WhcNMjIwNDI1MTAz +MTE4WjB+MQswCQYDVQQGEwJGUjEPMA0GA1UECAwGQWxzYWNlMRgwFgYDVQQKDA93 +d3cuZnJlZWxhbi5vcmcxEDAOBgNVBAsMB2ZyZWVsYW4xDjAMBgNVBAMMBWFsaWNl +MSIwIAYJKoZIhvcNAQkBFhNjb250YWN0QGZyZWVsYW4ub3JnMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEA3W29+ID6194bH6ejLrIC4hb2Ugo8v6ZC+Mrc +k2dNYMNPjcOKABvxxEtBamnSaeU/IY7FC/giN622LEtV/3oDcrua0+yWuVafyxmZ +yTKUb4/GUgafRQPf/eiX9urWurtIK7XgNGFNUjYPq4dSJQPPhwCHE/LKAykWnZBX +RrX0Dq4XyApNku0IpjIjEXH+8ixE12wH8wt7DEvdO7T3N3CfUbaITl1qBX+Nm2Z6 +q4Ag/u5rl8NJfXg71ZmXA3XOj7zFvpyapRIZcPmkvZYn7SMCp8dXyXHPdpSiIWL2 +uB3KiO4JrUYvt2GzLBUThp+lNSZaZ/Q3yOaAAUkOx+1h08285Pi+P8lO+H2Xic4S +vMq1xtLg2bNoPC5KnbRfuFPuUD2/3dSiiragJ6uYDLOyWJDivKGt/72OVTEPAL9o +6T2pGZrwbQuiFGrGTMZOvWMSpQtNl+tCCXlT4mWqJDRwuMGrI4DnnGzt3IKqNwS4 +Qyo9KqjMIPwnXZAmWPm3FOKe4sFwc5fpawKO01JZewDsYTDxVj+cwXwFxbE2yBiF +z2FAHwfopwaH35p3C6lkcgP2k/zgAlnBluzACUI+MKJ/G0gv/uAhj1OHJQ3L6kn1 +SpvQ41/ueBjlunExqQSYD7GtZ1Kg8uOcq2r+WISE3Qc9MpQFFkUVllmgWGwYDuN3 +Zsez95kCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT +TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFFlfyRO6G8y5qEFKikl5 +ajb2fT7XMB8GA1UdIwQYMBaAFCNsLT0+KV14uGw+quK7Lh5sh/JTMA0GCSqGSIb3 +DQEBBQUAA4ICAQAT5wJFPqervbja5+90iKxi1d0QVtVGB+z6aoAMuWK+qgi0vgvr +mu9ot2lvTSCSnRhjeiP0SIdqFMORmBtOCFk/kYDp9M/91b+vS+S9eAlxrNCB5VOf +PqxEPp/wv1rBcE4GBO/c6HcFon3F+oBYCsUQbZDKSSZxhDm3mj7pb67FNbZbJIzJ +70HDsRe2O04oiTx+h6g6pW3cOQMgIAvFgKN5Ex727K4230B0NIdGkzuj4KSML0NM +slSAcXZ41OoSKNjy44BVEZv0ZdxTDrRM4EwJtNyggFzmtTuV02nkUj1bYYYC5f0L +ADr6s0XMyaNk8twlWYlYDZ5uKDpVRVBfiGcq0uJIzIvemhuTrofh8pBQQNkPRDFT +Rq1iTo1Ihhl3/Fl1kXk1WR3jTjNb4jHX7lIoXwpwp767HAPKGhjQ9cFbnHMEtkro +RlJYdtRq5mccDtwT0GFyoJLLBZdHHMHJz0F9H7FNk2tTQQMhK5MVYwg+LIaee586 +CQVqfbscp7evlgjLW98H+5zylRHAgoH2G79aHljNKMp9BOuq6SnEglEsiWGVtu2l +hnx8SB3sVJZHeer8f/UQQwqbAO+Kdy70NmbSaqaVtp8jOxLiidWkwSyRTsuU6D8i +DiH5uEqBXExjrj0FslxcVKdVj5glVcSmkLwZKbEU1OKwleT/iXFhvooWhQ== +-----END CERTIFICATE----- diff --git a/ansible-adapter/ansible-adapter-bundle/src/test/resources/org/onap/ccsdk/default.properties b/ansible-adapter/ansible-adapter-bundle/src/test/resources/org/onap/ccsdk/default.properties new file mode 100644 index 000000000..2f8fb4585 --- /dev/null +++ b/ansible-adapter/ansible-adapter-bundle/src/test/resources/org/onap/ccsdk/default.properties @@ -0,0 +1,111 @@ +### +# ============LICENSE_START======================================================= +# ONAP : APPC +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Copyright (C) 2017 Amdocs +# ============================================================================= +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# ============LICENSE_END========================================================= +### + +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.onap.appc.bootstrap.file=appc.properties +org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},. + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.onap.appc.resources=org/onap/appc/i18n/MessageResources +# +# The name of the adapter. +org.onap.appc.provider.adaptor.name=org.onap.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.onap.appc.logging.file=org/onap/appc/logback.xml +org.onap.appc.logging.path=${user.home};etc;../etc +org.onap.appc.logger=org.onap.appc +org.onap.appc.security.logger=org.onap.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.onap.appc.provider.min.pool=1 +org.onap.appc.provider.max.pool=0 + +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.onap.appc.provider.retry.delay = 30 +org.onap.appc.provider.retry.limit = 10 + +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.onap.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.onap.appc.openstack.poll.interval=20 +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# + +# Don't change these 2 right now since they are hard coded in the DG +#provider1.type=appc +#provider1.name=appc + +#These you can change +#provider1.identity=appc +#provider1.tenant1.name=appc +#provider1.tenant1.userid=appc +#provider1.tenant1.password=appc + +# After a change to the provider make sure to recheck these values with an api call to provider1.identity/tokens +test.expected-regions=1 +test.expected-endpoints=1 + +#Your OpenStack IP +#test.ip=192.168.1.2 +# Your OpenStack Platform's Keystone Port (default is 5000) +#test.port=5000 +#test.tenantid=abcde12345fghijk6789lmnopq123rst +#test.vmid=abc12345-1234-5678-890a-abcdefg12345 +# Port 8774 below is default port for OpenStack's Nova API Service +#test.url=http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345 + diff --git a/ansible-adapter/ansible-adapter-installer/pom.xml b/ansible-adapter/ansible-adapter-installer/pom.xml new file mode 100644 index 000000000..af02a8c5c --- /dev/null +++ b/ansible-adapter/ansible-adapter-installer/pom.xml @@ -0,0 +1,151 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : APPC + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Copyright (C) 2017 Amdocs + ============================================================================= + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + ECOMP is a trademark and service mark of AT&T Intellectual Property. + ============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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ansible-adapter-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: ansible-adapter :: ${project.artifactId}</name> + + <properties> + <application.name>ccsdk-ansible-adapter</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ansible-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>true</appendAssemblyId> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>org.onap.ccsdk.sli.adaptors</includeGroupIds> + + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/ansible-adapter/ansible-adapter-installer/src/assembly/assemble_installer_zip.xml b/ansible-adapter/ansible-adapter-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..322fa76eb --- /dev/null +++ b/ansible-adapter/ansible-adapter-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,62 @@ +<!-- + ============LICENSE_START======================================================= + ONAP : APPC + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Copyright (C) 2017 Amdocs + ============================================================================= + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + ECOMP is a trademark and service mark of AT&T Intellectual Property. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/ansible-adapter/ansible-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml b/ansible-adapter/ansible-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..ec65e79e1 --- /dev/null +++ b/ansible-adapter/ansible-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,50 @@ +<!-- + ============LICENSE_START======================================================= + ONAP : APPC + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Copyright (C) 2017 Amdocs + ============================================================================= + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + ECOMP is a trademark and service mark of AT&T Intellectual Property. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/ansible-adapter/ansible-adapter-installer/src/main/resources/scripts/install-feature.sh b/ansible-adapter/ansible-adapter-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..c8214c520 --- /dev/null +++ b/ansible-adapter/ansible-adapter-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,42 @@ +### +# ============LICENSE_START======================================================= +# ONAP : APPC +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Copyright (C) 2017 Amdocs +# ============================================================================= +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/ansible-adapter/pom.xml b/ansible-adapter/pom.xml new file mode 100644 index 000000000..3414e7cf3 --- /dev/null +++ b/ansible-adapter/pom.xml @@ -0,0 +1,191 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : APPC + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Copyright (C) 2017 Amdocs + ============================================================================= + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + ECOMP is a trademark and service mark of AT&T Intellectual Property. + ============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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ansible-adaptor</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: ansible-adapter</name> + <description>Abstractions to interact with Ansible server via REST</description> + + <modules> + <module>ansible-adapter-bundle</module> + <module>ansible-adapter-installer</module> + </modules> + + <dependencyManagement> + <dependencies> + + <dependency> + <groupId>org.onap.appc</groupId> + <artifactId>ansible-adapter-features</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + + <dependency> + <groupId>org.onap.appc</groupId> + <artifactId>ansible-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + + + </dependencies> + + + </dependencyManagement> + + <pluginRepositories> + <!-- Black Duck plugin dependencies --> + <pluginRepository> + <id>JCenter</id> + <name>JCenter Repository</name> + <url>http://jcenter.bintray.com</url> + </pluginRepository> + + </pluginRepositories> + + <build> + <plugins> + + <!-- Black duck plugin Not required for regular builds + <plugin> <groupId>com.blackducksoftware.integration</groupId> <artifactId>hub-maven-plugin</artifactId> + <version>1.4.0</version> <inherited>false</inherited> <configuration> <hubProjectName>${project.name}</hubProjectName> + <outputDirectory>${project.basedir}</outputDirectory> <deployHubBdio>false</deployHubBdio> + </configuration> <extensions>true</extensions> + <executions> + <execution> + <id>create-bdio-file</id> + <phase>package</phase> + <goals> + <goal>createHubOutput</goal> + </goals> + </execution> + </executions> + + </plugin> + --> + + </plugins> + </build> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + + </reporting> +</project> diff --git a/artifacts/pom.xml b/artifacts/pom.xml new file mode 100755 index 000000000..452292304 --- /dev/null +++ b/artifacts/pom.xml @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>parent</artifactId> + <version>2.1.0</version> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>sli-adaptors-artifacts</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: sli-adaptors-artifacts</name> + <description>CCSDK adaptors components Bill of Materials (BOM)</description> + <url>https://wiki.onap.org</url> + <organization> + <name>ONAP</name> + </organization> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-aai-service</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>feature</classifier> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-ansible-adapter</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>feature</classifier> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-mdsal-resource</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>feature</classifier> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-netbox-client</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>feature</classifier> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-resource-management</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>feature</classifier> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-saltstack-adapter</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>feature</classifier> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-sql-resource</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>feature</classifier> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>aai-service-installer</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ansible-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ansible-adapter-installer</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>mdsal-resource-provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>mdsal-resource-installer</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client-provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client-installer</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>resource-assignment-provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>resource-assignment-installer</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>saltstack-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>saltstack-adapter-installer</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>sql-resource-provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>sql-resource-installer</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </dependencyManagement> +</project> diff --git a/base/http/installer/pom.xml b/base/http/installer/pom.xml new file mode 100644 index 000000000..980302ac9 --- /dev/null +++ b/base/http/installer/pom.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>base-http-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: base-http :: ${project.artifactId}</name> + + <properties> + <application.name>ccsdk-base-http</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>base-http-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeArtifactIds>ccsdk-base-http,base-http-provider</includeArtifactIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/base/http/installer/src/assembly/assemble_installer_zip.xml b/base/http/installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..3bed4b5ef --- /dev/null +++ b/base/http/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>installer_zip</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/base/http/installer/src/assembly/assemble_mvnrepo_zip.xml b/base/http/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..35e79db18 --- /dev/null +++ b/base/http/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,49 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/base/http/installer/src/main/resources/scripts/install-feature.sh b/base/http/installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..6e3d4169d --- /dev/null +++ b/base/http/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -nd ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/base/http/pom.xml b/base/http/pom.xml new file mode 100644 index 000000000..05840986d --- /dev/null +++ b/base/http/pom.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors.base</groupId> + <artifactId>http</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <modules> + <module>provider</module> + <module>installer</module> + </modules> +</project> diff --git a/base/http/provider/pom.xml b/base/http/provider/pom.xml new file mode 100644 index 000000000..5a3642fd2 --- /dev/null +++ b/base/http/provider/pom.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>base-http-provider</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-client</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.logging-analytics</groupId> + <artifactId>logging-filter-base</artifactId> + <scope>provided</scope> + </dependency> + </dependencies> +</project> diff --git a/base/http/provider/src/main/java/org/onap/ccsdk/sli/adaptors/base/http/AbstractHttpAdapter.java b/base/http/provider/src/main/java/org/onap/ccsdk/sli/adaptors/base/http/AbstractHttpAdapter.java new file mode 100644 index 000000000..cc6f06a4d --- /dev/null +++ b/base/http/provider/src/main/java/org/onap/ccsdk/sli/adaptors/base/http/AbstractHttpAdapter.java @@ -0,0 +1,114 @@ +package org.onap.ccsdk.sli.adaptors.base.http; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Base64; +import java.util.Properties; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; +import javax.ws.rs.client.ClientBuilder; +import org.onap.logging.filter.base.MetricLogClientFilter; +import org.onap.logging.filter.base.PayloadLoggingClientFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractHttpAdapter { + protected static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR"; + private static final String SDNC_CONFIG_DIR_DEFAULT = "/opt/sdnc/data/properties"; + protected static final int DEFAULT_HTTP_CONNECT_TIMEOUT_MS = 60000; // 1 minute + protected static final int DEFAULT_HTTP_READ_TIMEOUT_MS = 1800000; // 30 minutes + protected ClientBuilder clientBuilder; + + private static final Logger logger = LoggerFactory.getLogger(AbstractHttpAdapter.class); + + public AbstractHttpAdapter() { + clientBuilder = ClientBuilder.newBuilder(); + setTimeouts(); + defaultHostNameVerifier(); + } + + private void defaultHostNameVerifier() { + clientBuilder.hostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + } + + protected void enableMetricLogging() { + clientBuilder.register(new MetricLogClientFilter()); + } + + protected void enablePayloadLogging() { + clientBuilder.register(new PayloadLoggingClientFilter()); + } + + private void setTimeouts() { + Integer httpReadTimeout = readOptionalInteger("HTTP_READ_TIMEOUT_MS", DEFAULT_HTTP_READ_TIMEOUT_MS); + Integer httpConnectTimeout = readOptionalInteger("HTTP_CONNECT_TIMEOUT_MS", DEFAULT_HTTP_CONNECT_TIMEOUT_MS); + + // restore once we migrate to once we migrate to javax.ws.rs-api 2.1 + // clientBuilder.connectTimeout(30, TimeUnit.SECONDS); + // clientBuilder.readTimeout(30, TimeUnit.SECONDS); + + // Setting jersey specific properties is ugly, such behavior should be removed + // once we migrate to javax.ws.rs-api 2.1 + clientBuilder.property("jersey.config.client.readTimeout", httpReadTimeout); + clientBuilder.property("jersey.config.client.connectTimeout", httpConnectTimeout); + } + + public Properties getProperties(String propertiesFileName) throws FileNotFoundException, IOException { + // Check System property, then environment variable then default if null + String propDir = System.getProperty(SDNC_CONFIG_DIR); + if (propDir == null || propDir.length() < 1) { + propDir = System.getenv(SDNC_CONFIG_DIR); + } + if (propDir == null || propDir.length() < 1) { + propDir = SDNC_CONFIG_DIR_DEFAULT; + } + Properties properties = new Properties(); + // forward slash is checked to support path src/test/resources on windows machine + if (!propDir.endsWith(File.separator) && !propDir.endsWith("/")) { + propDir = propDir + File.separator; + } + String path = propDir + propertiesFileName; + properties.load(new FileInputStream(path)); + logger.trace("Initialized properties from ({}) properties ({})", path, properties); + return properties; + } + + protected void addBasicAuthCredentials(String username, String password) { + String basicAuthValue = getBasicAuthValue(username,password); + clientBuilder.register(new BasicAuthFilter(basicAuthValue)); + } + + protected String getBasicAuthValue(String userName, String password) { + String token = userName + ":" + password; + try { + return "Basic " + Base64.getEncoder().encodeToString(token.getBytes()); + } catch (Exception e) { + logger.error("getBasicAuthValue threw an exception, credentials will be null", e); + } + return null; + } + + public ClientBuilder getClientBuilder() { + return clientBuilder; + } + + private Integer readOptionalInteger(String propertyName, Integer defaultValue) { + String stringValue = System.getProperty(propertyName); + if (stringValue != null && stringValue.length() > 0) { + try { + return Integer.valueOf(stringValue); + } catch (NumberFormatException e) { + logger.warn("property " + propertyName + " had the value " + stringValue + " that could not be converted to an Integer, default " + defaultValue + " will be used instead", e); + } + } + return defaultValue; + } + +} diff --git a/base/http/provider/src/main/java/org/onap/ccsdk/sli/adaptors/base/http/BasicAuthFilter.java b/base/http/provider/src/main/java/org/onap/ccsdk/sli/adaptors/base/http/BasicAuthFilter.java new file mode 100644 index 000000000..5d3d463c9 --- /dev/null +++ b/base/http/provider/src/main/java/org/onap/ccsdk/sli/adaptors/base/http/BasicAuthFilter.java @@ -0,0 +1,22 @@ +package org.onap.ccsdk.sli.adaptors.base.http; + +import java.io.IOException; + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientRequestFilter; +import javax.ws.rs.core.MultivaluedMap; + +public class BasicAuthFilter implements ClientRequestFilter { + private final String basicAuthValue; + + public BasicAuthFilter(String basicAuthValue) { + this.basicAuthValue = basicAuthValue; + } + + public void filter(ClientRequestContext requestContext) throws IOException { + MultivaluedMap<String, Object> headers = requestContext.getHeaders(); + headers.add("Authorization", basicAuthValue); + } + + +} diff --git a/base/http/provider/src/test/java/org/onap/ccsdk/sli/adaptors/base/http/AbstractHttpAdapterTest.java b/base/http/provider/src/test/java/org/onap/ccsdk/sli/adaptors/base/http/AbstractHttpAdapterTest.java new file mode 100644 index 000000000..d0973d90e --- /dev/null +++ b/base/http/provider/src/test/java/org/onap/ccsdk/sli/adaptors/base/http/AbstractHttpAdapterTest.java @@ -0,0 +1,44 @@ +package org.onap.ccsdk.sli.adaptors.base.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Properties;
+import java.util.Set;
+
+import javax.ws.rs.client.Client;
+
+import org.junit.Test;
+
+public class AbstractHttpAdapterTest {
+
+ public class TestAdapter extends AbstractHttpAdapter {
+
+ }
+
+ @Test
+ public void checkTimeouts() throws Exception {
+ TestAdapter adapter = new TestAdapter();
+ Client client = adapter.getClientBuilder().build();
+ assertNotNull(client.getConfiguration().getProperty("jersey.config.client.readTimeout"));
+ assertNotNull(client.getConfiguration().getProperty("jersey.config.client.connectTimeout"));
+ }
+
+ @Test
+ public void propertiesTest() throws Exception {
+ System.setProperty(AbstractHttpAdapter.SDNC_CONFIG_DIR, "src/test/resources/");
+ TestAdapter adapter = new TestAdapter();
+ Properties props = adapter.getProperties("testprops.properties");
+ assertNotNull(props);
+ assertEquals("world", props.get("hello"));
+ }
+
+ @Test
+ public void basicAuthFilter() throws Exception {
+ TestAdapter adapter = new TestAdapter();
+ adapter.addBasicAuthCredentials("hello", "world");
+ Set<Object> objs = adapter.getClientBuilder().getConfiguration().getInstances();
+ assertEquals(BasicAuthFilter.class,objs.iterator().next().getClass());
+ }
+
+}
diff --git a/base/http/provider/src/test/java/org/onap/ccsdk/sli/adaptors/base/http/BasicAuthFilterTest.java b/base/http/provider/src/test/java/org/onap/ccsdk/sli/adaptors/base/http/BasicAuthFilterTest.java new file mode 100644 index 000000000..d9d552dac --- /dev/null +++ b/base/http/provider/src/test/java/org/onap/ccsdk/sli/adaptors/base/http/BasicAuthFilterTest.java @@ -0,0 +1,20 @@ +package org.onap.ccsdk.sli.adaptors.base.http; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +public class BasicAuthFilterTest { + + @Test + public void notNullParameters() throws Exception { + BasicAuthFilter myFilter = new BasicAuthFilter("hello"); + assertNotNull(myFilter); + } + + @Test + public void nullParameters() throws Exception { + BasicAuthFilter myFilter = new BasicAuthFilter(null); + assertNotNull(myFilter); + } +} diff --git a/base/http/provider/src/test/resources/testprops.properties b/base/http/provider/src/test/resources/testprops.properties new file mode 100644 index 000000000..3f602680e --- /dev/null +++ b/base/http/provider/src/test/resources/testprops.properties @@ -0,0 +1 @@ +hello = world
\ No newline at end of file diff --git a/base/pom.xml b/base/pom.xml new file mode 100644 index 000000000..a8e6b9193 --- /dev/null +++ b/base/pom.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>base-parent</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <modules> + <module>http</module> + </modules> +</project> diff --git a/features/ccsdk-aai-service/pom.xml b/features/ccsdk-aai-service/pom.xml new file mode 100644 index 000000000..2870ea50f --- /dev/null +++ b/features/ccsdk-aai-service/pom.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-aai-service</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: aai-service :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-sli</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>aai-service-provider</artifactId> + <version>${project.version}</version> + </dependency> + + + </dependencies> +</project> diff --git a/features/ccsdk-ansible-adapter/pom.xml b/features/ccsdk-ansible-adapter/pom.xml new file mode 100644 index 000000000..652a3ee59 --- /dev/null +++ b/features/ccsdk-ansible-adapter/pom.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-ansible-adapter</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: ansible-adapter:: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-sli</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ansible-adapter-bundle</artifactId> + <version>${project.version}</version> + <exclusions> + <exclusion> + <artifactId>powermock-api-mockito</artifactId> + <groupId>org.powermock</groupId> + </exclusion> + </exclusions> + </dependency> + + + </dependencies> +</project> diff --git a/features/ccsdk-base-http/pom.xml b/features/ccsdk-base-http/pom.xml new file mode 100644 index 000000000..4f83f5de1 --- /dev/null +++ b/features/ccsdk-base-http/pom.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-base-http</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: base-http :: ${project.artifactId}</name> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>base-http-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/features/ccsdk-mdsal-resource/pom.xml b/features/ccsdk-mdsal-resource/pom.xml new file mode 100644 index 000000000..fc5b9ae2f --- /dev/null +++ b/features/ccsdk-mdsal-resource/pom.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-mdsal-resource</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: mdsal-resource :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-sli</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>mdsal-resource-provider</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> +</project> diff --git a/features/ccsdk-messagerouter-consumer/pom.xml b/features/ccsdk-messagerouter-consumer/pom.xml new file mode 100755 index 000000000..0030d92c8 --- /dev/null +++ b/features/ccsdk-messagerouter-consumer/pom.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>ccsdk-messagerouter-consumer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>consumer.api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>consumer.provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/features/ccsdk-messagerouter-publisher/pom.xml b/features/ccsdk-messagerouter-publisher/pom.xml new file mode 100755 index 000000000..fcedcace0 --- /dev/null +++ b/features/ccsdk-messagerouter-publisher/pom.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>ccsdk-messagerouter-publisher</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>publisher.api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>publisher.provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/features/ccsdk-netbox-client/pom.xml b/features/ccsdk-netbox-client/pom.xml new file mode 100644 index 000000000..cff225740 --- /dev/null +++ b/features/ccsdk-netbox-client/pom.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 AT&T, Bell Canada + + 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. + --> + +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-netbox-client</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: netbox-client :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-sli</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-dblib</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>netbox-client-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/features/ccsdk-resource-assignment/pom.xml b/features/ccsdk-resource-assignment/pom.xml new file mode 100644 index 000000000..d73a1acda --- /dev/null +++ b/features/ccsdk-resource-assignment/pom.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-resource-assignment</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: resource-assignment :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-sli</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-dblib</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>resource-assignment-provider</artifactId> + <version>${project.version}</version> + </dependency> + + + </dependencies> +</project> diff --git a/features/ccsdk-saltstack-adapter/pom.xml b/features/ccsdk-saltstack-adapter/pom.xml new file mode 100644 index 000000000..3ac7fcf14 --- /dev/null +++ b/features/ccsdk-saltstack-adapter/pom.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-saltstack-adapter</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: saltstack-adapter:: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-sli</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>saltstack-adapter-provider</artifactId> + <version>${project.version}</version> + + <exclusions> + <exclusion> + <artifactId>powermock-api-mockito</artifactId> + <groupId>org.powermock</groupId> + </exclusion> + </exclusions> + </dependency> + </dependencies> +</project> diff --git a/features/ccsdk-sli-adaptors-all/pom.xml b/features/ccsdk-sli-adaptors-all/pom.xml new file mode 100644 index 000000000..821f1cb12 --- /dev/null +++ b/features/ccsdk-sli-adaptors-all/pom.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-sli-adaptors-all</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: features :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ccsdk-aai-service</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ccsdk-ansible-adapter</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + <!-- saltstack-adapter needs to be changed to remove dependency on app-c code + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ccsdk-saltstack-adapter</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + --> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ccsdk-netbox-client</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ccsdk-mdsal-resource</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ccsdk-resource-assignment</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ccsdk-sql-resource</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + <dependency> + <groupId>${project.groupId}.messagerouter</groupId> + <artifactId>ccsdk-messagerouter-publisher</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + </dependencies> +</project> diff --git a/features/ccsdk-sql-resource/pom.xml b/features/ccsdk-sql-resource/pom.xml new file mode 100644 index 000000000..d8ff07047 --- /dev/null +++ b/features/ccsdk-sql-resource/pom.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>single-feature-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-sql-resource</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: sql-resource :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-sli</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-dblib</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>xml</type> + <classifier>features</classifier> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sql-resource-provider</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> +</project> diff --git a/features/features-sli-adaptors/pom.xml b/features/features-sli-adaptors/pom.xml new file mode 100644 index 000000000..5e98da302 --- /dev/null +++ b/features/features-sli-adaptors/pom.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>feature-repo-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>features-sli-adaptors</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>feature</packaging> + + <name>ccsdk-sli-adaptors :: features :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ccsdk-sli-adaptors-all</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + + </dependencies> +</project> diff --git a/features/installer/pom.xml b/features/installer/pom.xml new file mode 100755 index 000000000..fab35b5f0 --- /dev/null +++ b/features/installer/pom.xml @@ -0,0 +1,265 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>sliadaptors-features-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: features :: ${project.artifactId}</name> + + <properties> + <application.name>ccsdk-sli-adaptors-all</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-aai-service</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-ansible-adapter</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-base-http</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-mdsal-resource</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>ccsdk-messagerouter-consumer</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>ccsdk-messagerouter-publisher</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-netbox-client</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-resource-assignment</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-saltstack-adapter</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>ccsdk-sql-resource</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>${application.name}</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>org.onap.ccsdk.sli.adaptors</includeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/features/installer/src/assembly/assemble_installer_zip.xml b/features/installer/src/assembly/assemble_installer_zip.xml new file mode 100755 index 000000000..a6a22a9ba --- /dev/null +++ b/features/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,39 @@ +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>bin</id> + + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/features/installer/src/assembly/assemble_mvnrepo_zip.xml b/features/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100755 index 000000000..86b07f1f3 --- /dev/null +++ b/features/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,29 @@ +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/features/installer/src/main/resources/scripts/install-feature.sh b/features/installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..e16e79a12 --- /dev/null +++ b/features/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/features/pom.xml b/features/pom.xml new file mode 100755 index 000000000..e57a639ac --- /dev/null +++ b/features/pom.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>sliadaptors-feature-aggregator</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: features</name> + + <modules> + <module>ccsdk-aai-service</module> + <module>ccsdk-ansible-adapter</module> + <module>ccsdk-base-http</module> + <module>ccsdk-mdsal-resource</module> + <module>ccsdk-messagerouter-consumer</module> + <module>ccsdk-messagerouter-publisher</module> + <module>ccsdk-netbox-client</module> + <module>ccsdk-resource-assignment</module> + <module>ccsdk-saltstack-adapter</module> + <module>ccsdk-sql-resource</module> + <module>ccsdk-sli-adaptors-all</module> + <module>features-sli-adaptors</module> + <module>installer</module> + </modules> +</project> diff --git a/mdsal-resource/.gitignore b/mdsal-resource/.gitignore new file mode 100755 index 000000000..b73caf31e --- /dev/null +++ b/mdsal-resource/.gitignore @@ -0,0 +1,34 @@ +#####standard .git ignore entries##### + +## IDE Specific Files ## +org.eclipse.core.resources.prefs +.classpath +.project +.settings +.idea +.externalToolBuilders +maven-eclipse.xml +workspace + +## Compilation Files ## +*.class +**/target +target +target-ide +MANIFEST.MF + +## Misc Ignores (OS specific etc) ## +bin/ +dist +*~ +*.ipr +*.iml +*.iws +classes +out/ +.DS_STORE +.metadata + +## Folders which contain auto generated source code ## +yang-gen-config +yang-gen-sal diff --git a/mdsal-resource/installer/pom.xml b/mdsal-resource/installer/pom.xml new file mode 100755 index 000000000..bb92cbff3 --- /dev/null +++ b/mdsal-resource/installer/pom.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>mdsal-resource-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: mdsal-resource :: ${project.artifactId}</name> + + <properties> + <application.name>ccsdk-mdsal-resource</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>mdsal-resource-provider</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>org.onap.ccsdk.sli.adaptors</includeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/mdsal-resource/installer/src/assembly/assemble_installer_zip.xml b/mdsal-resource/installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..b6fd65582 --- /dev/null +++ b/mdsal-resource/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>installer_zip</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/mdsal-resource/installer/src/assembly/assemble_mvnrepo_zip.xml b/mdsal-resource/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..9cdc78879 --- /dev/null +++ b/mdsal-resource/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,49 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/mdsal-resource/installer/src/main/resources/scripts/install-feature.sh b/mdsal-resource/installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..0eab001d5 --- /dev/null +++ b/mdsal-resource/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/mdsal-resource/pom.xml b/mdsal-resource/pom.xml new file mode 100755 index 000000000..e770e504c --- /dev/null +++ b/mdsal-resource/pom.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>mdsal-resource</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: mdsal-resource</name> + <description>The MD-SAL resource adaptor allows service logic to access persistent data from MD-SAL config and operational trees</description> + + <modules> + <module>provider</module> + <module>installer</module> + </modules> +</project> diff --git a/mdsal-resource/provider/pom.xml b/mdsal-resource/provider/pom.xml new file mode 100755 index 000000000..255812b55 --- /dev/null +++ b/mdsal-resource/provider/pom.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>mdsal-resource-provider</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-adaptors :: mdsal-resource :: ${project.artifactId}</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-core-artifacts</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/ConfigResource.java b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/ConfigResource.java new file mode 100644 index 000000000..e2e9bc230 --- /dev/null +++ b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/ConfigResource.java @@ -0,0 +1,153 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.resource.mdsal; + +import java.util.Map; +import java.util.Properties; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; + +public class ConfigResource implements SvcLogicResource { + + private static final Logger LOG = LoggerFactory.getLogger(ConfigResource.class); + + private RestService restService; + + public ConfigResource(MdsalResourcePropertiesProvider propProvider) { + LOG.info("Loading ConfigResource using property provider"); + Properties props = propProvider.getProperties(); + + String sdncUser = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-user", "admin"); + String sdncPasswd = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-passwd", "admin"); + String sdncHost = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-host", "localhost"); + String sdncProtocol = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-protocol", "https"); + String sdncPort = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-port", "8443"); + + restService = new RestService(sdncProtocol, sdncHost, sdncPort, sdncUser, sdncPasswd, "XML", "XML"); + } + + public ConfigResource(String sdncProtocol, String sdncHost, String sdncPort, String sdncUser, String sdncPasswd) + { + restService = new RestService(sdncProtocol, sdncHost, sdncPort, sdncUser, sdncPasswd, "XML", "XML"); + } + + public ConfigResource(RestService restService) { + this.restService = restService; + } + + @Override + public QueryStatus isAvailable(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException + { + return(query(resource, false, null, key, prefix, null, null)); + } + + @Override + public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException + { + return(query(resource, false, null, key, prefix, null, null)); + } + + @Override + public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, + String orderBy, SvcLogicContext ctx) throws SvcLogicException { + String module = resource; + StringBuffer restQuery = new StringBuffer(); + + String[] keyParts = key.split("/"); + for (String keyPart : keyParts) { + if (restQuery.length() > 0) { + restQuery.append("/"); + } + if (keyPart.startsWith("$")) { + restQuery.append(ctx.resolve(keyPart.substring(1))); + } else { + restQuery.append(keyPart); + } + } + + String restQueryStr = restQuery.toString(); + if ((restQueryStr.startsWith("'") && restQueryStr.endsWith("'")) || + (restQueryStr.startsWith("\"") && restQueryStr.endsWith("\""))) { + restQueryStr = restQueryStr.substring(1, restQueryStr.length()-1); + } + + String urlString = "restconf/config/" + module + ":" + restQueryStr; + LOG.info("Querying resource: " + resource + ". At URL: " + urlString); + + Document results = restService.get(urlString); + if (results == null) { + return(QueryStatus.NOT_FOUND); + } else { + if (ctx != null) { + ctx.mergeDocument(prefix, results); + } + return(QueryStatus.SUCCESS); + } + } + + @Override + public QueryStatus reserve(String resource, String select, String key, String prefix, + SvcLogicContext ctx) throws SvcLogicException { + return(QueryStatus.SUCCESS); + + } + + @Override + public QueryStatus release(String resource, String key, SvcLogicContext ctx) throws SvcLogicException { + return(QueryStatus.SUCCESS); + } + + @Override + public QueryStatus delete(String arg0, String arg1, SvcLogicContext arg2) + throws SvcLogicException { + // TODO Auto-generated method stub + return(QueryStatus.SUCCESS); + } + + @Override + public QueryStatus save(String arg0, boolean arg1, boolean localOnly, String arg2, + Map<String, String> arg3, String arg4, SvcLogicContext arg5) + throws SvcLogicException { + // TODO Auto-generated method stub + return(QueryStatus.SUCCESS); + } + + @Override + public QueryStatus notify(String resource, String action, String key, + SvcLogicContext ctx) throws SvcLogicException { + return(QueryStatus.SUCCESS); + } + + + public QueryStatus update(String resource, String key, + Map<String, String> parms, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + return(QueryStatus.SUCCESS); + } + +} diff --git a/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/MdsalResourcePropertiesProvider.java b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/MdsalResourcePropertiesProvider.java new file mode 100755 index 000000000..e433a4c13 --- /dev/null +++ b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/MdsalResourcePropertiesProvider.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2016 - 2017 ONAP + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.resource.mdsal; + +import java.util.Properties; + +public interface MdsalResourcePropertiesProvider { + + public Properties getProperties(); +} diff --git a/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/MdsalResourcePropertiesProviderImpl.java b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/MdsalResourcePropertiesProviderImpl.java new file mode 100755 index 000000000..e9e006f17 --- /dev/null +++ b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/MdsalResourcePropertiesProviderImpl.java @@ -0,0 +1,186 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2016 - 2017 ONAP + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.resource.mdsal; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; +import java.util.Properties; +import java.util.Vector; + +import org.onap.ccsdk.sli.core.sli.ConfigurationException; +import org.onap.ccsdk.sli.core.utils.JREFileResolver; +import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver; +import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver; +import org.onap.ccsdk.sli.core.utils.common.CoreDefaultFileResolver; +import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Responsible for determining the properties file to use and instantiating the + * <code>SqlResource</code> Service. The priority for properties file + * resolution is as follows: + * + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>sql-resource.properties</code></li> + * <li>A <code>sql-resource.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ +public class MdsalResourcePropertiesProviderImpl implements MdsalResourcePropertiesProvider { + + private static final Logger LOG = LoggerFactory.getLogger(MdsalResourcePropertiesProviderImpl.class); + + /** + * The name of the properties file for database configuration + */ + private static final String MDSALRESOURCE_PROP_FILE_NAME = "mdsal-resource.properties"; + + /** + * A prioritized list of strategies for resolving sql-resource properties files. + */ + private Vector<PropertiesFileResolver> mdsalResourcePropertiesFileResolvers = new Vector<>(); + + /** + * The configuration properties for the db connection. + */ + private Properties properties; + + /** + * Set up the prioritized list of strategies for resolving dblib properties + * files. + */ + public MdsalResourcePropertiesProviderImpl() { + mdsalResourcePropertiesFileResolvers + .add(new SdncConfigEnvVarFileResolver("Using property file (1) from environment variable")); + mdsalResourcePropertiesFileResolvers.add(new CoreDefaultFileResolver("Using property file (2) from default directory")); + + mdsalResourcePropertiesFileResolvers.add( + new JREFileResolver("Using property file (3) from JRE argument", MdsalResourcePropertiesProviderImpl.class)); + mdsalResourcePropertiesFileResolvers.add(new KarafRootFileResolver("Using property file (4) from karaf root", this)); + + // determines properties file as according to the priority described in the + // class header comment + final File propertiesFile = determinePropertiesFile(this); + if (propertiesFile != null) { + try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) { + properties = new Properties(); + properties.load(fileInputStream); + } catch (final IOException e) { + LOG.error("Failed to load properties for file: {}", propertiesFile.toString(), + new ConfigurationException("Failed to load properties for file: " + propertiesFile.toString(), + e)); + } + } else { + // Try to read properties as resource + + InputStream propStr = getClass().getResourceAsStream("/" + MDSALRESOURCE_PROP_FILE_NAME); + if (propStr != null) { + properties = new Properties(); + try { + properties.load(propStr); + propStr.close(); + } catch (IOException e) { + properties = null; + } + } + + } + + if (properties == null) { + reportFailure("Missing configuration properties resource(3)", new ConfigurationException( + "Missing configuration properties resource(3): " + MDSALRESOURCE_PROP_FILE_NAME)); + } + } + + /** + * Extract svclogic config properties. + * + * @return the svclogic config properties + */ + public Properties getProperties() { + return properties; + } + + /** + * Reports the method chosen for properties resolution to the + * <code>Logger</code>. + * + * @param message + * Some user friendly message + * @param fileOptional + * The file location of the chosen properties file + * @return the file location of the chosen properties file + */ + private static File reportSuccess(final String message, final Optional<File> fileOptional) { + if (fileOptional.isPresent()) { + final File file = fileOptional.get(); + LOG.info("{} {}", message, file.getPath()); + return file; + } + return null; + } + + /** + * Reports fatal errors. This is the case in which no properties file could be + * found. + * + * @param message + * An appropriate fatal error message + * @param configurationException + * An exception describing what went wrong during resolution + */ + private static void reportFailure(final String message, final ConfigurationException configurationException) { + + LOG.error("{}", message, configurationException); + } + + /** + * Determines the sql-resource properties file to use based on the following priority: + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>mdsal-resource.properties</code></li> + * <li>A <code>sql-resource.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ + File determinePropertiesFile(final MdsalResourcePropertiesProviderImpl resourceProvider) { + + for (final PropertiesFileResolver sliPropertiesFileResolver : mdsalResourcePropertiesFileResolvers) { + final Optional<File> fileOptional = sliPropertiesFileResolver.resolveFile(MDSALRESOURCE_PROP_FILE_NAME); + if (fileOptional.isPresent()) { + return reportSuccess(sliPropertiesFileResolver.getSuccessfulResolutionMessage(), fileOptional); + } + } + + return null; + } +} diff --git a/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/OperationalResource.java b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/OperationalResource.java new file mode 100644 index 000000000..320878126 --- /dev/null +++ b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/OperationalResource.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.resource.mdsal; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; + +import java.util.Map; +import java.util.Properties; + +public class OperationalResource implements SvcLogicResource { + + private static final Logger LOG = LoggerFactory.getLogger(OperationalResource.class); + + private RestService restService; + + public OperationalResource(MdsalResourcePropertiesProvider propProvider) { + Properties props = propProvider.getProperties(); + + String sdncUser = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-user", "admin"); + String sdncPasswd = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-passwd", "admin"); + String sdncHost = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-host", "localhost"); + String sdncProtocol = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-protocol", "https"); + String sdncPort = props.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-port", "8443"); + + restService = new RestService(sdncProtocol, sdncHost, sdncPort, sdncUser, sdncPasswd, "XML", "XML"); + } + + public OperationalResource(String sdncProtocol, String sdncHost, String sdncPort, String sdncUser, String sdncPasswd) { + restService = new RestService(sdncProtocol, sdncHost, sdncPort, sdncUser, sdncPasswd, "XML", "XML"); + } + + public OperationalResource(RestService restService) { + this.restService = restService; + } + + @Override + public QueryStatus isAvailable(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException { + return (query(resource, false, null, key, prefix, null, null)); + } + + @Override + public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException { + return (query(resource, false, null, key, prefix, null, null)); + } + + @Override + public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, + String orderBy, SvcLogicContext ctx) throws SvcLogicException { + String module = resource; + StringBuffer restQuery = new StringBuffer(); + + String[] keyParts = key.split("/"); + for (String keyPart : keyParts) { + if (restQuery.length() > 0) { + restQuery.append("/"); + } + if (keyPart.startsWith("$")) { + restQuery.append(ctx.resolve(keyPart.substring(1))); + } else { + restQuery.append(keyPart); + } + } + + String restQueryStr = restQuery.toString(); + if ((restQueryStr.startsWith("'") && restQueryStr.endsWith("'")) || + (restQueryStr.startsWith("\"") && restQueryStr.endsWith("\""))) { + restQueryStr = restQueryStr.substring(1, restQueryStr.length() - 1); + } + + String urlString = "restconf/operational/" + module + ":" + restQueryStr; + LOG.info("Querying resource: " + resource + ". At URL: " + urlString); + + Document results = restService.get(urlString); + + if (results == null) { + return (QueryStatus.NOT_FOUND); + } else { + if (ctx != null) { + ctx.mergeDocument(prefix, results); + } + return (QueryStatus.SUCCESS); + } + } + + @Override + public QueryStatus reserve(String resource, String select, String key, String prefix, + SvcLogicContext ctx) throws SvcLogicException { + return (QueryStatus.SUCCESS); + } + + @Override + public QueryStatus release(String resource, String key, SvcLogicContext ctx) throws SvcLogicException { + return (QueryStatus.SUCCESS); + } + + @Override + public QueryStatus delete(String arg0, String arg1, SvcLogicContext arg2) + throws SvcLogicException { + // TODO Auto-generated method stub + return (QueryStatus.SUCCESS); + } + + @Override + public QueryStatus save(String arg0, boolean arg1, boolean localOnly, String arg2, + Map<String, String> arg3, String arg4, SvcLogicContext arg5) + throws SvcLogicException { + // TODO Auto-generated method stub + return (QueryStatus.SUCCESS); + } + + @Override + public QueryStatus notify(String resource, String action, String key, + SvcLogicContext ctx) throws SvcLogicException { + return (QueryStatus.SUCCESS); + } + + public QueryStatus update(String resource, String key, + Map<String, String> parms, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + return (QueryStatus.SUCCESS); + } + +} diff --git a/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/RestService.java b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/RestService.java new file mode 100644 index 000000000..ebddc24ae --- /dev/null +++ b/mdsal-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/RestService.java @@ -0,0 +1,184 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.resource.mdsal; + +import org.apache.commons.codec.binary.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.*; +import java.net.Authenticator; +import java.net.HttpURLConnection; +import java.net.PasswordAuthentication; +import java.net.URL; + +public class RestService { + + private static final Logger LOG = LoggerFactory.getLogger(ConfigResource.class); + private String user; + private String passwd; + private String contentType; + private String accept; + private String protocol; + private String host; + private String port; + + public RestService(String protocol, String host, String port, String user, String passwd, String accept, String contentType) { + this.protocol = protocol; + this.host = host; + this.port = port; + this.user = user; + this.passwd = passwd; + this.accept = accept; + this.contentType = contentType; + } + + private HttpURLConnection getRestConnection(String urlString, String method) throws IOException { + URL sdncUrl = new URL(urlString); + Authenticator.setDefault(new SdncAuthenticator(user, passwd)); + + String authStr = user + ":" + passwd; + String encodedAuthStr = new String(Base64.encodeBase64(authStr.getBytes())); + + HttpURLConnection conn = (HttpURLConnection) sdncUrl.openConnection(); + conn.addRequestProperty("Authentication", "Basic " + encodedAuthStr); + conn.setRequestMethod(method); + conn.setDoInput(true); + conn.setDoOutput(true); + conn.setUseCaches(false); + + //Setting Accept header (doesn't dependent on Msg Body if present or not) + if ("XML".equalsIgnoreCase(accept)) { + conn.setRequestProperty("Accept", "application/xml"); + } else { + conn.setRequestProperty("Accept", "application/json"); + } + + return (conn); + } + + private Document send(String urlString, byte[] msgBytes, String method) { + Document response = null; + String fullUrl = protocol + "://" + host + ":" + port + "/" + urlString; + LOG.info("Sending REST {} to {}", method, fullUrl); + + try { + HttpURLConnection conn = getRestConnection(fullUrl, method); + if (conn instanceof HttpsURLConnection) { + HostnameVerifier hostnameVerifier = (hostname, session) -> true; + ((HttpsURLConnection) conn).setHostnameVerifier(hostnameVerifier); + } + + // Write message + if (msgBytes != null) { + LOG.info("Message body:\n{}", msgBytes); + conn.setRequestProperty("Content-Length", "" + msgBytes.length); + + // Setting Content-Type header only if Msg Body is present + if ("XML".equalsIgnoreCase(contentType)) { + conn.setRequestProperty("Content-Type", "application/xml"); + } else { + conn.setRequestProperty("Content-Type", "application/json"); + } + + DataOutputStream outStr = new DataOutputStream(conn.getOutputStream()); + outStr.write(msgBytes); + outStr.close(); + } else { + conn.setRequestProperty("Content-Length", "0"); + } + + // Read response + LOG.info("Response: {} {}", conn.getResponseCode(), conn.getResponseMessage()); + + BufferedReader respRdr; + if (conn.getResponseCode() < 300) { + respRdr = new BufferedReader(new InputStreamReader(conn.getInputStream())); + } else { + respRdr = new BufferedReader(new InputStreamReader(conn.getErrorStream())); + } + + StringBuffer respBuff = new StringBuffer(); + String respLn; + while ((respLn = respRdr.readLine()) != null) { + respBuff.append(respLn + "\n"); + } + respRdr.close(); + + String respString = respBuff.toString(); + LOG.info("Response body :\n{}", respString); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); + dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + DocumentBuilder db = dbf.newDocumentBuilder(); + + response = db.parse(new ByteArrayInputStream(respString.getBytes())); + + } catch (Exception e) { + LOG.error("Caught exception executing REST command", e); + } + + return (response); + } + + public Document get(String urlString) { + return (send(urlString, null, "GET")); + } + + public Document delete(String urlString) { + return (send(urlString, null, "DELETE")); + } + + public Document post(String urlString, byte[] msgBytes) { + return (send(urlString, msgBytes, "POST")); + } + + public Document put(String urlString, byte[] msgBytes) { + return (send(urlString, msgBytes, "PUT")); + } + + + private class SdncAuthenticator extends Authenticator { + private String user; + private String passwd; + + SdncAuthenticator(String user, String passwd) { + this.user = user; + this.passwd = passwd; + } + + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(user, passwd.toCharArray()); + } + + } + +} diff --git a/mdsal-resource/provider/src/main/resources/IPV4_ADDRESS_POOL.csv b/mdsal-resource/provider/src/main/resources/IPV4_ADDRESS_POOL.csv new file mode 100755 index 000000000..30ce117bc --- /dev/null +++ b/mdsal-resource/provider/src/main/resources/IPV4_ADDRESS_POOL.csv @@ -0,0 +1,9 @@ +"192.168.1.2","OAM","AVAILABLE" +"192.168.1.3","OAM","AVAILABLE" +"192.168.1.4","OAM","AVAILABLE" +"192.168.1.5","OAM","AVAILABLE" +"192.168.1.6","OAM","AVAILABLE" +"192.168.1.7","OAM","AVAILABLE" +"192.168.1.8","OAM","AVAILABLE" +"192.168.1.9","OAM","AVAILABLE" +"192.168.1.10","OAM","AVAILABLE" diff --git a/mdsal-resource/provider/src/main/resources/OSGI-INF/blueprint/mdsal-resource-blueprint.xml b/mdsal-resource/provider/src/main/resources/OSGI-INF/blueprint/mdsal-resource-blueprint.xml new file mode 100755 index 000000000..9c691263c --- /dev/null +++ b/mdsal-resource/provider/src/main/resources/OSGI-INF/blueprint/mdsal-resource-blueprint.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 - 2018 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" class="org.onap.ccsdk.sli.adaptors.resource.mdsal.MdsalResourcePropertiesProviderImpl" /> + + + <bean id="configResourceInstance" class="org.onap.ccsdk.sli.adaptors.resource.mdsal.ConfigResource"> + <argument ref="propProvider"/> + </bean> + + <bean id="operResourceInstance" class="org.onap.ccsdk.sli.adaptors.resource.mdsal.OperationalResource"> + <argument ref="propProvider"/> + </bean> + + <service ref="configResourceInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.resource.mdsal.ConfigResource</value> + </interfaces> + </service> + + <service ref="operResourceInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.resource.mdsal.OperationalResource</value> + </interfaces> + </service> +</blueprint> diff --git a/mdsal-resource/provider/src/main/resources/VLAN_ID_POOL.csv b/mdsal-resource/provider/src/main/resources/VLAN_ID_POOL.csv new file mode 100755 index 000000000..6c4b0f775 --- /dev/null +++ b/mdsal-resource/provider/src/main/resources/VLAN_ID_POOL.csv @@ -0,0 +1,22 @@ +"1100","IPAG","AVAILABLE",NULL +"1101","IPAG","AVAILABLE",NULL +"1102","IPAG","AVAILABLE",NULL +"1103","IPAG","AVAILABLE",NULL +"1104","IPAG","AVAILABLE",NULL +"1105","IPAG","AVAILABLE",NULL +"1106","IPAG","AVAILABLE",NULL +"1107","IPAG","AVAILABLE",NULL +"1108","IPAG","AVAILABLE",NULL +"1109","IPAG","AVAILABLE",NULL +"1110","IPAG","AVAILABLE",NULL +"1200","VPE","AVAILABLE",NULL +"1201","VPE","AVAILABLE",NULL +"1202","VPE","AVAILABLE",NULL +"1203","VPE","AVAILABLE",NULL +"1204","VPE","AVAILABLE",NULL +"1205","VPE","AVAILABLE",NULL +"1206","VPE","AVAILABLE",NULL +"1207","VPE","AVAILABLE",NULL +"1208","VPE","AVAILABLE",NULL +"1209","VPE","AVAILABLE",NULL +"1210","VPE","AVAILABLE",NULL diff --git a/mdsal-resource/provider/src/main/resources/crtables.sql b/mdsal-resource/provider/src/main/resources/crtables.sql new file mode 100644 index 000000000..5ee75f4e4 --- /dev/null +++ b/mdsal-resource/provider/src/main/resources/crtables.sql @@ -0,0 +1,70 @@ +--- +-- ============LICENSE_START======================================================= +-- openECOMP : SDN-C +-- ================================================================================ +-- 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========================================================= +--- + +CREATE TABLE sdnctl.VNF ( +vnf_id varchar(80) NOT NULL, +vnf_name varchar(80) NOT NULL, +vnf_type varchar(10) NOT NULL, +orchestration_status varchar(20), +heat_stack_id varchar(80), +mso_catalog_key varchar(80), +availability_zone varchar(80), +aic_site_id varchar(80), +oam_ipv4_address varchar(20), +CONSTRAINT P_VNF PRIMARY KEY(vnf_id)); + +CREATE TABLE sdnctl.VNF_NETWORK_CONNECTION ( +connection_uuid varchar(80) NOT NULL, +vnf_id varchar(80) NOT NULL, +connection_id varchar(80), +connection_type varchar(20), +neutron_network_id varchar(80), +neutron_network_name varchar(80), +orchestration_status varchar(20), +switch_id varchar(40), +heat_stack_id varchar(80), +mso_catalog_key varchar(80), +provider_network varchar(80), +port_group_id varchar(80), +port_group_name varchar(80), +CONSTRAINT P_NETWORK_CONNECTION PRIMARY KEY(connection_uuid)); + +CREATE TABLE sdnctl.VNF_NETWORK_CONNECTION_VLAN ( +vlan_uuid varchar(80) NOT NULL, +vlan_id numeric(4) NOT NULL, +vlan_type varchar(5) NOT NULL, +connection_uuid varchar(80), +CONSTRAINT P_VNF_NETWORK_CONNECTION_VLAN PRIMARY KEY(vlan_uuid)); + +CREATE TABLE sdnctl.VLAN_ID_POOL ( +vlan_id numeric(4) NOT NULL, +universe varchar(40) NOT NULL, +status varchar(40) NOT NULL, +vlan_uuid varchar(80), +CONSTRAINT P_VLAN_ID_POOL PRIMARY KEY(vlan_id,universe)); + +CREATE TABLE sdnctl.IPV4_ADDRESS_POOL ( +ipv4_addr varchar(20) NOT NULL, +universe varchar(40) NOT NULL, +status varchar(40) NOT NULL, +CONSTRAINT P_IPV4_ADDRESS_POOL PRIMARY KEY(ipv4_addr, universe)); + + diff --git a/mdsal-resource/provider/src/main/resources/mdsal-resource.properties b/mdsal-resource/provider/src/main/resources/mdsal-resource.properties new file mode 100644 index 000000000..47c8ebf77 --- /dev/null +++ b/mdsal-resource/provider/src/main/resources/mdsal-resource.properties @@ -0,0 +1,27 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-user=admin +org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-passwd=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U +org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-host=localhost +org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-protocol=http +org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-port=8181 + diff --git a/mdsal-resource/provider/src/main/resources/org/opendaylight/blueprint/mdsal-resource-blueprint.xml b/mdsal-resource/provider/src/main/resources/org/opendaylight/blueprint/mdsal-resource-blueprint.xml new file mode 100755 index 000000000..9c691263c --- /dev/null +++ b/mdsal-resource/provider/src/main/resources/org/opendaylight/blueprint/mdsal-resource-blueprint.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 - 2018 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" class="org.onap.ccsdk.sli.adaptors.resource.mdsal.MdsalResourcePropertiesProviderImpl" /> + + + <bean id="configResourceInstance" class="org.onap.ccsdk.sli.adaptors.resource.mdsal.ConfigResource"> + <argument ref="propProvider"/> + </bean> + + <bean id="operResourceInstance" class="org.onap.ccsdk.sli.adaptors.resource.mdsal.OperationalResource"> + <argument ref="propProvider"/> + </bean> + + <service ref="configResourceInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.resource.mdsal.ConfigResource</value> + </interfaces> + </service> + + <service ref="operResourceInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.resource.mdsal.OperationalResource</value> + </interfaces> + </service> +</blueprint> diff --git a/mdsal-resource/provider/src/main/resources/svclogic.properties b/mdsal-resource/provider/src/main/resources/svclogic.properties new file mode 100644 index 000000000..0abadc5c8 --- /dev/null +++ b/mdsal-resource/provider/src/main/resources/svclogic.properties @@ -0,0 +1,26 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +org.onap.ccsdk.sli.adaptors.dbtype = jdbc +org.onap.ccsdk.sli.adaptors.jdbc.url = jdbc:mysql://dbhost:3306/sdnctl +org.onap.ccsdk.sli.adaptors.jdbc.database = sdnctl +org.onap.ccsdk.sli.adaptors.jdbc.user = sdnctl +org.onap.ccsdk.sli.adaptors.jdbc.password = gamma diff --git a/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/ConfigResourceTest.java b/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/ConfigResourceTest.java new file mode 100644 index 000000000..f5b0bcf0c --- /dev/null +++ b/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/ConfigResourceTest.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.resource.mdsal; + +import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; + +import static org.junit.Assert.assertEquals; + +public class ConfigResourceTest { + ConfigResource configResource = new ConfigResource("http", "local", + "10001", "admin", + "password"); + + @Test + public void isAvailableNegativeTest() throws SvcLogicException { + SvcLogicContext ctx = new SvcLogicContext(); + assertEquals(QueryStatus.NOT_FOUND, configResource.isAvailable + ("xyz", "key", "prefix", ctx)); + } +} + diff --git a/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/TestConfigResource.java b/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/TestConfigResource.java new file mode 100644 index 000000000..80563b96b --- /dev/null +++ b/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/TestConfigResource.java @@ -0,0 +1,31 @@ +package org.onap.ccsdk.sli.adaptors.resource.mdsal; + +import junit.framework.TestCase; + +import static org.mockito.Mockito.mock; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import static org.junit.Assert.assertNotNull; + +public class TestConfigResource extends TestCase { + + public void test() throws Exception { + + RestService restService = mock(RestService.class); + SvcLogicContext ctx = new SvcLogicContext(); + + ConfigResource res = new ConfigResource(restService); + + res.delete("my-resource", null, ctx); + res.notify("my-resource", "action", "key", ctx); + res.query("my-resource", false, "my-select", "mykey", "pfx", null, ctx); + res.release("my-resource", "mykey", ctx); + res.reserve("my-resource", "my-select", "mykey", "pfx", ctx); + res.exists("my-resource", "mykey", "pfx", ctx); + res.isAvailable("my-resource", "mykey", "pfx", ctx); + res.save("resource", false, false, null, null, null, ctx); + res.update("my-resource", "mykey", null, "pfx", ctx); + assertNotNull(res); + } + +} diff --git a/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/TestMdsalResourcePropertiesProviderImpl.java b/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/TestMdsalResourcePropertiesProviderImpl.java new file mode 100644 index 000000000..7f05d1e5f --- /dev/null +++ b/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/TestMdsalResourcePropertiesProviderImpl.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2018 Samsung. 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.onap.ccsdk.sli.adaptors.resource.mdsal; + +import org.junit.Before; +import org.junit.Test; + +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class TestMdsalResourcePropertiesProviderImpl { + + MdsalResourcePropertiesProviderImpl mdsal; + + @Before + public void setup() { + mdsal = new MdsalResourcePropertiesProviderImpl(); + } + + + @Test + public void testGetProperties() { + Properties prop = mdsal.getProperties(); + + System.out.println("All Default Properties : " + prop); + + assertEquals("localhost",prop.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-host")); + assertEquals("Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U",prop.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-passwd")); + assertEquals("http",prop.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-protocol")); + assertEquals("8181",prop.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-port")); + assertEquals("admin",prop.getProperty("org.onap.ccsdk.sli.adaptors.resource.mdsal.sdnc-user")); + } + + + @Test + public void testGetPropertie() throws IllegalStateException, IllegalArgumentException { + MdsalResourcePropertiesProviderImpl test = new MdsalResourcePropertiesProviderImpl(); + + mdsal.determinePropertiesFile(test); + assertNotNull(test); + + } +} diff --git a/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/TestOperationalResource.java b/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/TestOperationalResource.java new file mode 100644 index 000000000..2e9798df1 --- /dev/null +++ b/mdsal-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/mdsal/TestOperationalResource.java @@ -0,0 +1,31 @@ +package org.onap.ccsdk.sli.adaptors.resource.mdsal; + +import static org.mockito.Mockito.mock; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; + +import junit.framework.TestCase; +import static org.junit.Assert.assertNotNull; + +public class TestOperationalResource extends TestCase { + + + public void test() throws Exception { + + RestService restService = mock(RestService.class); + SvcLogicContext ctx = new SvcLogicContext(); + + OperationalResource res = new OperationalResource(restService); + + res.delete("my-resource", null, ctx); + res.notify("my-resource", "action", "key", ctx); + res.query("my-resource", false, "my-select", "mykey", "pfx", null, ctx); + res.release("my-resource", "mykey", ctx); + res.reserve("my-resource", "my-select", "mykey", "pfx", ctx); + res.exists("my-resource", "mykey", "pfx", ctx); + res.isAvailable("my-resource", "mykey", "pfx", ctx); + res.save("resource", false, false, null, null, null, ctx); + res.update("my-resource", "mykey", null, "pfx", ctx); + assertNotNull(restService); + } +} diff --git a/message-router/README.md b/message-router/README.md new file mode 100755 index 000000000..32848252b --- /dev/null +++ b/message-router/README.md @@ -0,0 +1,7 @@ +# CCSDK Message Router Extension
+
+This maven module builds re-usable code that interacts with message router
+
+## High level modules
+- **publisher** used for sending messages to a dmaap message router topic
+- **consumer** not yet created, this will be used for pulling messages from a dmaap message router topic
diff --git a/message-router/consumer/README.md b/message-router/consumer/README.md new file mode 100755 index 000000000..9d01256a7 --- /dev/null +++ b/message-router/consumer/README.md @@ -0,0 +1,7 @@ +# Consumer
+
+## Modules
+- api - exports the consumer interface for clients and providers to import
+- features - used for managing the feature repository for consumer
+- installer - provides a simple install script
+- provider - provides an implementation of the consumer api
\ No newline at end of file diff --git a/message-router/consumer/api/pom.xml b/message-router/consumer/api/pom.xml new file mode 100755 index 000000000..e77eb9793 --- /dev/null +++ b/message-router/consumer/api/pom.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>consumer.aggregate</artifactId> + <version>1.1.1-SNAPSHOT</version> + </parent> + + <artifactId>consumer.api</artifactId> + <packaging>bundle</packaging> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Export-Package>org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/ConsumerApi.java b/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/ConsumerApi.java new file mode 100755 index 000000000..41deade85 --- /dev/null +++ b/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/ConsumerApi.java @@ -0,0 +1,6 @@ +package org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api;
+
+public interface ConsumerApi extends AutoCloseable {
+ //registers a handler to handle a specific topic, should be called only once per client
+ public void registerHandler(String topic, RequestHandler requestHandler);
+}
diff --git a/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/PollingConsumer.java b/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/PollingConsumer.java new file mode 100755 index 000000000..29fc1c764 --- /dev/null +++ b/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/PollingConsumer.java @@ -0,0 +1,7 @@ +package org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api;
+
+public interface PollingConsumer extends ConsumerApi {
+
+ // Starts polling message router for messages, won't stop until close it called
+ void start();
+}
diff --git a/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/PullingConsumer.java b/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/PullingConsumer.java new file mode 100755 index 000000000..1187aaceb --- /dev/null +++ b/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/PullingConsumer.java @@ -0,0 +1,7 @@ +package org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api;
+
+public interface PullingConsumer extends ConsumerApi {
+
+ //Pulls a single batch of messages
+ void pull();
+}
diff --git a/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/RequestHandler.java b/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/RequestHandler.java new file mode 100755 index 000000000..07a117843 --- /dev/null +++ b/message-router/consumer/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/api/RequestHandler.java @@ -0,0 +1,5 @@ +package org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api; + +public interface RequestHandler { + public void handleRequest(String topic, String requestBody); +} diff --git a/message-router/consumer/installer/pom.xml b/message-router/consumer/installer/pom.xml new file mode 100755 index 000000000..2b8eb688e --- /dev/null +++ b/message-router/consumer/installer/pom.xml @@ -0,0 +1,128 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>consumer.aggregate</artifactId> + <version>1.1.1-SNAPSHOT</version> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>consumer.installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <properties> + <application.name>messagerouter-consumer</application.name> + <features.boot>messagerouter-consumer</features.boot> + <features.repositories>mvn:${project.groupId}/consumer.features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>consumer.api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>consumer.provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>${project.groupId}</includeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/message-router/consumer/installer/src/assembly/assemble_installer_zip.xml b/message-router/consumer/installer/src/assembly/assemble_installer_zip.xml new file mode 100755 index 000000000..c6169a879 --- /dev/null +++ b/message-router/consumer/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>installer_zip</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly>
\ No newline at end of file diff --git a/message-router/consumer/installer/src/assembly/assemble_mvnrepo_zip.xml b/message-router/consumer/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100755 index 000000000..409c66224 --- /dev/null +++ b/message-router/consumer/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly>
\ No newline at end of file diff --git a/message-router/consumer/installer/src/main/resources/scripts/install-feature.sh b/message-router/consumer/installer/src/main/resources/scripts/install-feature.sh new file mode 100755 index 000000000..6f2518f64 --- /dev/null +++ b/message-router/consumer/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}-repo.zip + +if [ -f ${REPOZIP} ] +then + unzip -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot}
\ No newline at end of file diff --git a/message-router/consumer/pom.xml b/message-router/consumer/pom.xml new file mode 100755 index 000000000..cad1bbba0 --- /dev/null +++ b/message-router/consumer/pom.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>messagerouter-root</artifactId> + <version>1.1.1-SNAPSHOT</version> + </parent> + + <artifactId>consumer.aggregate</artifactId> + <packaging>pom</packaging> + + <modules> + <module>api</module> + <module>provider</module> + <module>installer</module> + </modules> +</project> diff --git a/message-router/consumer/provider/pom.xml b/message-router/consumer/provider/pom.xml new file mode 100755 index 000000000..d3e568c40 --- /dev/null +++ b/message-router/consumer/provider/pom.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>consumer.aggregate</artifactId> + <version>1.1.1-SNAPSHOT</version> + </parent> + + <artifactId>consumer.provider</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>consumer.api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Export-Package>${project.groupId}.consumer.provider.impl</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/AbstractBaseConsumer.java b/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/AbstractBaseConsumer.java new file mode 100755 index 000000000..8937f7b91 --- /dev/null +++ b/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/AbstractBaseConsumer.java @@ -0,0 +1,207 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 - 2018 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.onap.ccsdk.sli.adaptors.messagerouter.consumer.provider.impl; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Base64; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSession; + +import org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api.ConsumerApi; +import org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api.RequestHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonParseException; + +/* + * java.net based client to build message router consumers + */ +public abstract class AbstractBaseConsumer implements ConsumerApi { + private static final Logger LOG = LoggerFactory.getLogger(AbstractBaseConsumer.class); + private static final String REQUEST_METHOD = "GET"; + + private final String host; + private final Integer connectTimeout; + private final Integer readTimeout; + private final String group; + private final String id; + private final String filter; + private final Integer limit; + private final Integer timeoutQueryParamValue; + private final String authorizationString; + + protected RequestHandler requestHandler; + protected URL url; + protected String topic; + + public AbstractBaseConsumer(String username, String password, String host, String authentication, Integer connectTimeout, Integer readTimeout, String group, String id, String filter, Integer limit, Integer timeoutQueryParamValue) { + this.host = host; + this.connectTimeout = connectTimeout; + this.readTimeout = readTimeout; + this.group = group; + this.id = id; + this.filter = filter; + this.limit = limit; + this.timeoutQueryParamValue = timeoutQueryParamValue; + + if ("basic".equals(authentication)) { + if (username != null && password != null && username.length() > 0 && password.length() > 0) { + authorizationString = buildAuthorizationString(username, password); + } else { + throw new IllegalStateException("Authentication is set to basic but username or password is missing"); + } + } else if ("noauth".equals(authentication)) { + authorizationString = null; + } else { + throw new IllegalStateException("Unknown authentication method: " + authentication); + } + } + + protected void poll() { + String responseBody = performHttpOperation(); + if (responseBody != null && !responseBody.startsWith("[]")) { + LOG.info("New message was fetched from MessageRouter."); + LOG.trace("Fetched message is\n{}", responseBody); + try { + String[] requests = new Gson().fromJson(responseBody, String[].class); + if (requests != null) { + for (String request : requests) { + if (request != null) { + requestHandler.handleRequest(topic,request); + } + } + } else { + LOG.warn("Deserialization of received message results in null array.", responseBody); + } + } catch (JsonParseException e) { + LOG.warn("Received message has bad format. Expected format is JSON."); + } + } else { + LOG.trace("No new message was fetched from MessageRouter."); + } + } + + private String buildlUrlString(String topic) { + StringBuilder sb = new StringBuilder(); + sb.append(host + "/events/" + topic + "/" + group + "/" + id); + sb.append("?timeout=" + timeoutQueryParamValue); + + if (limit != null) { + sb.append("&limit=" + limit); + } + if (filter != null) { + sb.append("&filter=" + filter); + } + return sb.toString(); + } + + private String performHttpOperation() { + HttpURLConnection httpUrlConnection = null; + try { + httpUrlConnection = buildHttpURLConnection(url); + httpUrlConnection.setRequestMethod(REQUEST_METHOD); + httpUrlConnection.connect(); + int status = httpUrlConnection.getResponseCode(); + if (status < 300) { + return readFromStream(httpUrlConnection.getInputStream()); + } else { + String response = readFromStream(httpUrlConnection.getErrorStream()); + LOG.warn("Fetching message from MessageRouter on url {} failed with http status {}. Error message is\n{}.", url, status, response); + } + } catch (Exception e) { + LOG.warn("Exception was thrown during fetching message from MessageRouter on url {}.", url, e); + } finally { + if (httpUrlConnection != null) { + httpUrlConnection.disconnect(); + } + } + return null; + } + + private String buildAuthorizationString(String userName, String password) { + String basicAuthString = userName + ":" + password; + basicAuthString = Base64.getEncoder().encodeToString(basicAuthString.getBytes()); + return "Basic " + basicAuthString; + } + + protected HttpURLConnection buildHttpURLConnection(URL url) throws IOException { + HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection(); + if (authorizationString != null) { + httpUrlConnection.setRequestProperty("Authorization", authorizationString); + } + httpUrlConnection.setRequestProperty("Accept", "application/json"); + httpUrlConnection.setUseCaches(false); + httpUrlConnection.setConnectTimeout(connectTimeout); + httpUrlConnection.setReadTimeout(readTimeout); + + // ignore hostname errors when dealing with HTTPS connections + if (httpUrlConnection instanceof HttpsURLConnection) { + HttpsURLConnection conn = (HttpsURLConnection) httpUrlConnection; + conn.setHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + }); + } + return httpUrlConnection; + } + + protected String readFromStream(InputStream stream) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(stream)); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + sb.append(line); + sb.append("\n"); + } + br.close(); + return sb.toString(); + } + + @Override + public void registerHandler(String topic, RequestHandler requestHandler) { + this.topic = topic; + try { + this.url = new URL(buildlUrlString(topic)); + } catch (MalformedURLException e) { + LOG.error("Topic " + topic + " resulted in MalformedURLException", e); + } + this.requestHandler = requestHandler; + } + + @Override + public void close() throws Exception { + //BaseConsumer doesn't spawn any threads + } + +} diff --git a/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/ConsumerFactory.java b/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/ConsumerFactory.java new file mode 100755 index 000000000..1aa02c70a --- /dev/null +++ b/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/ConsumerFactory.java @@ -0,0 +1,202 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights
+ * reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.ccsdk.sli.adaptors.messagerouter.consumer.provider.impl;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ConsumerFactory {
+ private static final Logger LOG = LoggerFactory.getLogger(ConsumerFactory.class);
+
+ // Default values to minimize required configuration
+ private static final int DEFAULT_FETCH_PAUSE = 5000;
+ private static final int DEFAULT_CONNECT_TIMEOUT = 30000;
+ private static final int DEFAULT_READ_TIMEOUT = 180000;
+ private static final int DEFAULT_LIMIT = 5; // Limits the number of messages pulled in a single GET request
+ private static final int DEFAULT_TIMEOUT_QUERY_PARAM_VALUE = 15000;
+ private static final String DEFAULT_AUTH_METHOD = "basic";
+
+ // Required properties
+ protected final String username;
+ protected final String password;
+ protected final String host;
+ private final String group;
+ private final String id;
+
+ // Optional properties
+ protected Integer connectTimeout;
+ protected Integer readTimeout;
+ private Integer fetchPause;
+ private Integer limit;
+ private Integer timeoutQueryParamValue;
+ private String filter;
+ protected String auth;
+
+ public ConsumerFactory(Properties properties) {
+ // Required properties
+ username = properties.getProperty("username");
+ password = properties.getProperty("password");
+ host = properties.getProperty("host");
+ auth = properties.getProperty("auth");
+ group = properties.getProperty("group");
+ id = properties.getProperty("id");
+
+ // Optional properties
+ connectTimeout = readOptionalInteger(properties, "connectTimeoutSeconds");
+ readTimeout = readOptionalInteger(properties, "readTimeoutMinutes");
+ fetchPause = readOptionalInteger(properties, "fetchPause");
+ limit = readOptionalInteger(properties, "limit");
+ timeoutQueryParamValue = readOptionalInteger(properties, "timeout");
+ processFilter(properties.getProperty("filter"));
+
+ setDefaults();
+ }
+
+ public ConsumerFactory(String username, String password, String host, String group, String id, Integer connectTimeout, Integer readTimeout) {
+ this.username = username;
+ this.password = password;
+ this.host = host;
+ this.group = group;
+ this.id = id;
+ setDefaults();
+ }
+
+
+ public String getAuth() {
+ return auth;
+ }
+
+ public void setAuth(String auth) {
+ this.auth = auth;
+ }
+
+ public Integer getConnectTimeout() {
+ return connectTimeout;
+ }
+
+ public void setConnectTimeout(Integer connectTimeout) {
+ this.connectTimeout = connectTimeout;
+ }
+
+ public Integer getReadTimeout() {
+ return readTimeout;
+ }
+
+ public void setReadTimeout(Integer readTimeout) {
+ this.readTimeout = readTimeout;
+ }
+
+ public Integer getFetchPause() {
+ return fetchPause;
+ }
+
+ public void setFetchPause(Integer fetchPause) {
+ this.fetchPause = fetchPause;
+ }
+
+ public Integer getLimit() {
+ return limit;
+ }
+
+ public void setLimit(Integer limit) {
+ this.limit = limit;
+ }
+
+ public Integer getTimeoutQueryParamValue() {
+ return timeoutQueryParamValue;
+ }
+
+ public void setTimeoutQueryParamValue(Integer timeoutQueryParamValue) {
+ this.timeoutQueryParamValue = timeoutQueryParamValue;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public void setFilter(String filter) {
+ processFilter(filter);
+ }
+
+ private Integer readOptionalInteger(Properties properties, String propertyName) {
+ String stringValue = properties.getProperty(propertyName);
+ if (stringValue != null && stringValue.length() > 0) {
+ try {
+ return Integer.valueOf(stringValue);
+ } catch (NumberFormatException e) {
+ LOG.error("property " + propertyName + " had the value " + stringValue + " that could not be converted to an Integer", e);
+ }
+ }
+ return null;
+ }
+
+ public PollingConsumerImpl createPollingClient() {
+ return new PollingConsumerImpl(username, password, host, auth, connectTimeout, readTimeout, fetchPause, group, id, filter, limit, timeoutQueryParamValue);
+ }
+
+ public PullingConsumerImpl createPullingClient() {
+ return new PullingConsumerImpl(username, password, host, auth, connectTimeout, readTimeout, group, id, filter, limit, timeoutQueryParamValue);
+ }
+
+ private void processFilter(String filterString) {
+ if (filterString != null) {
+ if (filterString.length() > 0) {
+ try {
+ filter = URLEncoder.encode(filterString, StandardCharsets.UTF_8.name());
+ } catch (UnsupportedEncodingException e) {
+ LOG.warn("Couldn't encode filter string. Filter will be ignored.", e);
+ filter = null;
+ }
+ } else {
+ filter = null;
+ }
+ }
+ }
+
+ private void setDefaults() {
+ if (connectTimeout == null) {
+ connectTimeout = DEFAULT_CONNECT_TIMEOUT;
+ }
+ if (readTimeout == null) {
+ readTimeout = DEFAULT_READ_TIMEOUT;
+ }
+ if (fetchPause == null) {
+ fetchPause = DEFAULT_FETCH_PAUSE;
+ }
+ if (limit == null) {
+ limit = DEFAULT_LIMIT;
+ }
+ if (timeoutQueryParamValue == null) {
+ timeoutQueryParamValue = DEFAULT_TIMEOUT_QUERY_PARAM_VALUE;
+ }
+ if (auth == null) {
+ auth = DEFAULT_AUTH_METHOD;
+ }
+ }
+
+}
diff --git a/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/PollingConsumerImpl.java b/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/PollingConsumerImpl.java new file mode 100644 index 000000000..263e94ca9 --- /dev/null +++ b/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/PollingConsumerImpl.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 - 2018 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.onap.ccsdk.sli.adaptors.messagerouter.consumer.provider.impl; + +import org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api.PollingConsumer; +import org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api.RequestHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/* + * java.net based client to build message router consumers + */ +public class PollingConsumerImpl implements PollingConsumer { + + //RunnableConsumer is a private inner class so run cannot be called from other code + private class RunnableConsumer extends AbstractBaseConsumer implements Runnable, PollingConsumer { + private final Logger LOG = LoggerFactory.getLogger(PollingConsumerImpl.class); + private volatile Thread t; + private final Integer fetchPause; + + public RunnableConsumer(String username, String password, String host, String authentication, Integer connectTimeout, Integer readTimeout, Integer fetchPause, String group, String id, String filter, Integer limit, Integer timeoutQueryParamValue) { + super(username, password, host, authentication, connectTimeout, readTimeout, group, id, filter, limit, timeoutQueryParamValue); + this.fetchPause = fetchPause; + } + + public void start() { + t = new Thread(this); + t.start(); + LOG.info("ConsumerImpl started. Fetch period is {} ms.", fetchPause); + } + + public void stop() { + t = null; + LOG.info("ConsumerImpl stopped."); + } + + @Override + public void run() { + if (this.url != null) { + Thread thisThread = Thread.currentThread(); + while (t == thisThread) { + poll(); + try { + LOG.trace("Next fetch from MessageRouter url {} after {} milliseconds.", url, fetchPause); + Thread.sleep(fetchPause); + } catch (InterruptedException e) { + LOG.warn("Thread sleep was interrupted.", e); + } + } + } else { + LOG.error("URL is null, can't listen for messages"); + } + } + + @Override + public void close() throws Exception { + stop(); + } + } + + private RunnableConsumer c; + + public PollingConsumerImpl(String username, String password, String host, String authentication, Integer connectTimeout, Integer readTimeout, Integer fetchPause, String group, String id, String filter, Integer limit, Integer timeoutQueryParamValue) { + c = new RunnableConsumer(username, password, host, authentication, connectTimeout, readTimeout, fetchPause, group, id, filter, limit, timeoutQueryParamValue); + } + + @Override + public void start() { + c.start(); + } + + @Override + public void registerHandler(String topic, RequestHandler requestHandler) { + c.registerHandler(topic, requestHandler); + } + + @Override + public void close() throws Exception { + c.close(); + } +} diff --git a/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/PullingConsumerImpl.java b/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/PullingConsumerImpl.java new file mode 100755 index 000000000..e5a5bc4d8 --- /dev/null +++ b/message-router/consumer/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/PullingConsumerImpl.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights + * reserved. + * + * Modifications Copyright (C) 2019 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.ccsdk.sli.adaptors.messagerouter.consumer.provider.impl; + +import org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api.PullingConsumer; + + +public class PullingConsumerImpl extends AbstractBaseConsumer implements PullingConsumer { + + public PullingConsumerImpl(String username, String password, String host, String authentication, Integer connectTimeout, Integer readTimeout, String group, String id, String filter, Integer limit, Integer timeoutQueryParamValue) { + super(username, password, host, authentication, connectTimeout, readTimeout, group, id, filter, limit, timeoutQueryParamValue); + } + + @Override + public void pull() { + this.poll(); + } + +} diff --git a/message-router/consumer/provider/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/AbstractBaseConsumerTest.java b/message-router/consumer/provider/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/AbstractBaseConsumerTest.java new file mode 100644 index 000000000..75873385b --- /dev/null +++ b/message-router/consumer/provider/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/AbstractBaseConsumerTest.java @@ -0,0 +1,91 @@ +package org.onap.ccsdk.sli.adaptors.messagerouter.consumer.provider.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.messagerouter.consumer.api.RequestHandler;
+
+public class AbstractBaseConsumerTest {
+ private class DummyConsumer extends AbstractBaseConsumer {
+
+ public DummyConsumer(String username, String password, String host, String authentication, Integer connectTimeout, Integer readTimeout, String group, String id, String filter, Integer limit, Integer timeoutQueryParamValue) {
+ super(username, password, host, authentication, connectTimeout, readTimeout, group, id, filter, limit, timeoutQueryParamValue);
+ }
+
+ }
+
+ public DummyConsumer getAuthDummy() {
+ String username = "deadpool";
+ String password = "notSECURE";
+ String host = "http://localhost:7001";
+ String group = "myCluster";
+ String id = "node1";
+ Integer connectTimeout = 10000;
+ Integer readTimeout = 20000;
+ String authentication = "basic";
+ String filter = null;
+ Integer limit = 3;
+ Integer timeoutQueryParamValue = 5000;
+ return new DummyConsumer(username, password, host, authentication, connectTimeout, readTimeout, group, id, filter, limit, timeoutQueryParamValue);
+ }
+
+ @Test
+ public void createDummyWithAuth() {
+ assertNotNull(getAuthDummy());
+ }
+
+ @Test
+ public void createDummyNohAuth() {
+ String username = null;
+ String password = null;
+ String host = "http://localhost:7001";
+ String group = "myCluster";
+ String id = "node1";
+ Integer connectTimeout = 10000;
+ Integer readTimeout = 20000;
+ String authentication = "noauth";
+ String filter = null;
+ Integer limit = 3;
+ Integer timeoutQueryParamValue = 5000;
+ assertNotNull(new DummyConsumer(username, password, host, authentication, connectTimeout, readTimeout, group, id, filter, limit, timeoutQueryParamValue));
+ }
+
+ @Test
+ public void callClose() throws Exception {
+ DummyConsumer dummy = getAuthDummy();
+ dummy.close();
+ assertNotNull(dummy);
+ }
+
+ @Test
+ public void registerDummyHandler() throws Exception {
+ DummyConsumer dummy = getAuthDummy();
+ String topic = "politics";
+ RequestHandler requestHandler = new RequestHandler() {
+
+ @Override
+ public void handleRequest(String topic, String requestBody) {
+ // TODO Auto-generated method stub
+
+ };
+
+ };
+ dummy.registerHandler(topic, requestHandler);
+ assertEquals(new URL("http://localhost:7001/events/politics/myCluster/node1?timeout=5000&limit=3"), dummy.url);
+ assertEquals(topic, dummy.topic);
+
+ }
+
+ @Test
+ public void buildURL() throws Exception {
+ DummyConsumer dummy = getAuthDummy();
+ HttpURLConnection connection = dummy.buildHttpURLConnection(new URL("http://localhost:7001/events/politics/myCluster/node1?timeout=5000&limit=3"));
+ assertNotNull(connection);
+ assertEquals("application/json", connection.getRequestProperty("Accept"));
+ }
+
+}
diff --git a/message-router/consumer/provider/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/ConsumerFactoryTest.java b/message-router/consumer/provider/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/ConsumerFactoryTest.java new file mode 100644 index 000000000..d1018a014 --- /dev/null +++ b/message-router/consumer/provider/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/consumer/provider/impl/ConsumerFactoryTest.java @@ -0,0 +1,164 @@ +package org.onap.ccsdk.sli.adaptors.messagerouter.consumer.provider.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Properties; + +import org.junit.Test; + +public class ConsumerFactoryTest { + + @Test + public void testFactoryClientCreation() throws Exception { + Properties props = new Properties(); + String userName = "deadpool"; + String password = "notSECURE"; + String host = "http://localhost:7001"; + String group = "myCluster"; + String id = "node1"; + Integer connectTimeout = 10000; + Integer readTimeout = 20000; + props.put("username", userName); + props.put("password", password); + props.put("host", host); + props.put("group", group); + + ConsumerFactory factory = new ConsumerFactory(userName, password, host, group, id, connectTimeout, readTimeout); + assertNotNull(factory.createPollingClient()); + assertNotNull(factory.createPullingClient()); + } + + @Test + public void testFactoryDefaults() throws Exception { + Properties props = new Properties(); + String userName = "deadpool"; + String password = "notSECURE"; + String host = "http://localhost:7001"; + String group = "myCluster"; + String id = "node1"; + Integer connectTimeout = 10000; + Integer readTimeout = 20000; + props.put("username", userName); + props.put("password", password); + props.put("host", host); + props.put("group", group); + + ConsumerFactory factory = new ConsumerFactory(userName, password, host, group, id, connectTimeout, readTimeout); + + assertNotNull(factory.getAuth()); + assertNotNull(factory.getConnectTimeout()); + assertNotNull(factory.getReadTimeout()); + assertNotNull(factory.getFetchPause()); + assertNotNull(factory.getLimit()); + assertNotNull(factory.getTimeoutQueryParamValue()); + } + + @Test + public void testFactoryDefaultsWithProps() { + Properties props = new Properties(); + String userName = "deadpool"; + String password = "notSECURE"; + String host = "http://localhost:7001"; + String auth = "basic"; + String group = "myCluster"; + props.put("username", userName); + props.put("password", password); + props.put("host", host); + props.put("group", group); + + ConsumerFactory factory = new ConsumerFactory(props); + + assertNotNull(factory.getAuth()); + assertNotNull(factory.getConnectTimeout()); + assertNotNull(factory.getReadTimeout()); + assertNotNull(factory.getFetchPause()); + assertNotNull(factory.getLimit()); + assertNotNull(factory.getTimeoutQueryParamValue()); + } + + @Test + public void testFactoryOverrides() throws Exception { + Properties props = new Properties(); + String userName = "deadpool"; + String password = "notSECURE"; + String host = "http://localhost:7001"; + String group = "myCluster"; + props.put("username", userName); + props.put("password", password); + props.put("host", host); + props.put("group", group); + + String connectTimeout = "200"; + String readTimeout = "300"; + String fetchPause = "1000"; + String auth = "noauth"; + String timeoutQueryParamValue = "50"; + String limit = "2"; + props.put("connectTimeoutSeconds", connectTimeout); + props.put("readTimeoutMinutes", readTimeout); + props.put("fetchPause", fetchPause); + props.put("auth", auth); + props.put("timeout", timeoutQueryParamValue); + props.put("limit", limit); + + ConsumerFactory factory = new ConsumerFactory(props); + + assertEquals(auth, factory.getAuth()); + assertEquals(Integer.valueOf(connectTimeout), factory.getConnectTimeout()); + assertEquals(Integer.valueOf(readTimeout), factory.getReadTimeout()); + assertEquals(Integer.valueOf(fetchPause), factory.getFetchPause()); + assertEquals(Integer.valueOf(limit), factory.getLimit()); + assertEquals(Integer.valueOf(timeoutQueryParamValue), factory.getTimeoutQueryParamValue()); + } + + @Test + public void testManualOverrides() { + Properties props = new Properties(); + String userName = "deadpool"; + String password = "notSECURE"; + String host = "http://localhost:7001"; + String auth = "basic"; + String group = "myCluster"; + props.put("username", userName); + props.put("password", password); + props.put("host", host); + props.put("group", group); + + ConsumerFactory factory = new ConsumerFactory(props); + + assertNotNull(factory.getAuth()); + assertNotNull(factory.getConnectTimeout()); + assertNotNull(factory.getReadTimeout()); + assertNotNull(factory.getFetchPause()); + assertNotNull(factory.getLimit()); + assertNotNull(factory.getTimeoutQueryParamValue()); + String newAuth = "noauth"; + factory.setAuth(newAuth); + assertEquals(newAuth, factory.getAuth()); + + Integer connectTimeout = 1; + factory.setConnectTimeout(connectTimeout); + assertEquals(connectTimeout, factory.getConnectTimeout()); + + Integer fetchPause = 5; + factory.setFetchPause(fetchPause); + assertEquals(fetchPause, factory.getFetchPause()); + + factory.setFilter("\"filter\":{\n" + "\"class\":\"And\",\n" + "\"filters\":\n" + "[\n" + "{ \"class\":\"Equals\", \"foo\":\"abc\" },\n" + "{ \"class\":\"Assigned\", \"field\":\"bar\" }\n" + "]\n" + "}"); + assertNotNull(factory.getFilter()); + + Integer limit = 3; + factory.setLimit(limit); + assertEquals(limit, factory.getLimit()); + + Integer readTimeout = 2; + factory.setReadTimeout(readTimeout); + assertEquals(readTimeout, factory.getReadTimeout()); + + Integer timeoutQueryParamValue = 47; + factory.setTimeoutQueryParamValue(timeoutQueryParamValue); + assertEquals(timeoutQueryParamValue, factory.getTimeoutQueryParamValue()); + } + +} diff --git a/message-router/pom.xml b/message-router/pom.xml new file mode 100755 index 000000000..63d267d2a --- /dev/null +++ b/message-router/pom.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>messagerouter-root</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <modules> + <module>publisher</module> + <module>consumer</module> + </modules> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + </plugin> + </plugins> + </pluginManagement> + </build> +</project> diff --git a/message-router/publisher/README.md b/message-router/publisher/README.md new file mode 100755 index 000000000..58c1bf470 --- /dev/null +++ b/message-router/publisher/README.md @@ -0,0 +1,8 @@ +# Publisher
+
+## Modules
+- api - exports the publisher interface for clients and providers to import
+- features - used for managing the feature repository for publisher
+- installer - provides a simple install script
+- provider - provides an implementation of the publisher api, this implementation assumes the controller has a single identity for publishing to DMAAP message router
+- sample.client - a dummy client that posts a simple message to a configured topic during its initialization
diff --git a/message-router/publisher/api/pom.xml b/message-router/publisher/api/pom.xml new file mode 100755 index 000000000..7831284cf --- /dev/null +++ b/message-router/publisher/api/pom.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>publisher.aggregate</artifactId> + <version>1.1.1-SNAPSHOT</version> + </parent> + + <artifactId>publisher.api</artifactId> + <packaging>bundle</packaging> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Export-Package>org.onap.ccsdk.sli.adaptors.messagerouter.publisher.api</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/message-router/publisher/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/api/PublisherApi.java b/message-router/publisher/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/api/PublisherApi.java new file mode 100755 index 000000000..3551e0441 --- /dev/null +++ b/message-router/publisher/api/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/api/PublisherApi.java @@ -0,0 +1,5 @@ +package org.onap.ccsdk.sli.adaptors.messagerouter.publisher.api;
+
+public interface PublisherApi {
+ public Boolean publish(String topic, String body);
+}
diff --git a/message-router/publisher/installer/pom.xml b/message-router/publisher/installer/pom.xml new file mode 100644 index 000000000..bc0565e5b --- /dev/null +++ b/message-router/publisher/installer/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>publisher.aggregate</artifactId> + <version>1.1.1-SNAPSHOT</version> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>publisher.installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <properties> + <application.name>messagerouter-publisher</application.name> + <features.boot>messagerouter-publisher</features.boot> + <features.repositories>mvn:${project.groupId}/publisher.features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>publisher.api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>publisher.provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sample.client</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>${project.groupId}</includeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/message-router/publisher/installer/src/assembly/assemble_installer_zip.xml b/message-router/publisher/installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..c6169a879 --- /dev/null +++ b/message-router/publisher/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>installer_zip</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly>
\ No newline at end of file diff --git a/message-router/publisher/installer/src/assembly/assemble_mvnrepo_zip.xml b/message-router/publisher/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..377b5b153 --- /dev/null +++ b/message-router/publisher/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,49 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + + +</assembly>
\ No newline at end of file diff --git a/message-router/publisher/installer/src/main/resources/scripts/install-feature.sh b/message-router/publisher/installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..15dc0c27a --- /dev/null +++ b/message-router/publisher/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot}
\ No newline at end of file diff --git a/message-router/publisher/pom.xml b/message-router/publisher/pom.xml new file mode 100755 index 000000000..6fb9c82d3 --- /dev/null +++ b/message-router/publisher/pom.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>messagerouter-root</artifactId> + <version>1.1.1-SNAPSHOT</version> + </parent> + + <artifactId>publisher.aggregate</artifactId> + <packaging>pom</packaging> + + <modules> + <module>api</module> + <module>provider</module> + <module>sample.client</module> + <module>installer</module> + </modules> +</project> diff --git a/message-router/publisher/provider/pom.xml b/message-router/publisher/provider/pom.xml new file mode 100755 index 000000000..7cd311448 --- /dev/null +++ b/message-router/publisher/provider/pom.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>publisher.aggregate</artifactId> + <version>1.1.1-SNAPSHOT</version> + </parent> + + <artifactId>publisher.provider</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>publisher.api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Private-Package>${project.groupId}.publisher.provider.impl</Private-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/message-router/publisher/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/provider/impl/PublisherApiImpl.java b/message-router/publisher/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/provider/impl/PublisherApiImpl.java new file mode 100755 index 000000000..4aedc6071 --- /dev/null +++ b/message-router/publisher/provider/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/provider/impl/PublisherApiImpl.java @@ -0,0 +1,178 @@ +/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+package org.onap.ccsdk.sli.adaptors.messagerouter.publisher.provider.impl;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.SocketException;
+import java.net.URL;
+import java.util.Base64;
+
+import org.onap.ccsdk.sli.adaptors.messagerouter.publisher.api.PublisherApi;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PublisherApiImpl implements PublisherApi {
+ private static final Logger logger = LoggerFactory.getLogger(PublisherApiImpl.class);
+ protected static final Integer DEFAULT_CONNECT_TIMEOUT = 30000; // will be treated as 30 seconds
+ protected static final Integer DEFAULT_READ_TIMEOUT = 180000; // will be treated as 3 minutes
+ private String authorizationString;
+ protected Integer connectTimeout;
+ protected Integer readTimeout;
+ protected String baseUrl;
+ protected String username;
+ protected String[] hosts;
+ private String password;
+
+ public PublisherApiImpl() {
+ connectTimeout = DEFAULT_CONNECT_TIMEOUT;
+ readTimeout = DEFAULT_READ_TIMEOUT;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ setAuthorizationString();
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ setAuthorizationString();
+ }
+
+ public void setHost(String hostString) {
+ // a comma separated list of hosts can be passed in or a single host may be used
+ if (!hostString.contains(",")) {
+ this.hosts = new String[] { hostString };
+ } else {
+ this.hosts = hostString.split(",");
+ }
+ }
+
+ public void init() {
+ setAuthorizationString();
+ }
+
+ protected String buildUrlString(Integer hostIndex, String topic) {
+ return hosts[hostIndex] + "/events/" + topic;
+ }
+
+ protected void configureHttpURLConnection(HttpURLConnection httpUrlConnection) {
+ httpUrlConnection.setRequestProperty("Content-Type", "application/json");
+ }
+
+ public Boolean publish(String topic, String body) {
+ for (int hostIndex = 0; hostIndex < hosts.length; hostIndex++) {
+ HttpURLConnection httpUrlConnection = null;
+ URL url = null;
+ try {
+ url = new URL(buildUrlString(hostIndex, topic));
+ logger.info("Publishing body to topic {} using the url {}", topic, url);
+ logger.info("Message to publish is\n{}", body);
+ httpUrlConnection = buildHttpURLConnection(url);
+ httpUrlConnection.setDoInput(true);
+ httpUrlConnection.setDoOutput(true);
+ httpUrlConnection.setUseCaches(false);
+ httpUrlConnection.setRequestMethod("POST");
+
+ // Write message
+ httpUrlConnection.setRequestProperty("Content-Length", Integer.toString(body.length()));
+ DataOutputStream outStr = new DataOutputStream(httpUrlConnection.getOutputStream());
+ outStr.write(body.getBytes());
+ outStr.close();
+
+ int status = httpUrlConnection.getResponseCode();
+ logger.info("Publishing body for topic {} using url {} returned status {}.", topic, url, status);
+ if (status < 300) {
+ String responseFromDMaaP = readFromStream(httpUrlConnection.getInputStream());
+ logger.info("Message router response is\n{}", responseFromDMaaP);
+ return true;
+ } else {
+ if (httpUrlConnection.getErrorStream() != null) {
+ String responseFromDMaaP = readFromStream(httpUrlConnection.getErrorStream());
+ logger.warn("Publishing body for topic {} using url {} failed." + " Error message is\n{}",
+ topic, url, responseFromDMaaP);
+ }
+ return false;
+ }
+
+ } catch (SocketException socketException) {
+ logger.error("SocketException was thrown during publishing message to DMaaP on url {}.", url,
+ socketException);
+ if (hostIndex < hosts.length) {
+ logger.info("Message sent to {} failed with a SocketException, but will be tried on {}",
+ hosts[hostIndex], hosts[hostIndex + 1]);
+ }
+ } catch (Exception e) {
+ logger.warn("Exception was thrown during publishing message to DMaaP on url {}.", url, e);
+ return false;
+ } finally {
+ if (httpUrlConnection != null) {
+ httpUrlConnection.disconnect();
+ }
+ }
+ }
+ return false;
+ }
+
+ protected void setAuthorizationString() {
+ String str = buildAuthorizationString(this.username, this.password);
+ this.authorizationString = str;
+ //System.out.println(this.authorizationString);
+ }
+
+ protected String buildAuthorizationString(String username, String password) {
+ String basicAuthString = username + ":" + password;
+ basicAuthString = Base64.getEncoder().encodeToString(basicAuthString.getBytes());
+ return "Basic " + basicAuthString;
+ }
+
+ protected HttpURLConnection buildHttpURLConnection(URL url) throws IOException {
+ HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
+ if (authorizationString != null) {
+ System.out.println(authorizationString);
+ httpUrlConnection.setRequestProperty("Authorization", authorizationString);
+ }
+ httpUrlConnection.setRequestProperty("Accept", "application/json");
+ httpUrlConnection.setUseCaches(false);
+ httpUrlConnection.setConnectTimeout(connectTimeout);
+ httpUrlConnection.setReadTimeout(readTimeout);
+ configureHttpURLConnection(httpUrlConnection);
+ return httpUrlConnection;
+ }
+
+ protected String readFromStream(InputStream stream) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(stream));
+ StringBuilder sb = new StringBuilder();
+ String line;
+ while ((line = br.readLine()) != null) {
+ sb.append(line);
+ }
+ br.close();
+ return sb.toString();
+ }
+
+}
\ No newline at end of file diff --git a/message-router/publisher/provider/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/message-router/publisher/provider/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100755 index 000000000..4702a6260 --- /dev/null +++ b/message-router/publisher/provider/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0"> + + <bean id="publisher" + class="org.onap.ccsdk.sli.adaptors.messagerouter.publisher.provider.impl.PublisherApiImpl"> + <cm:managed-properties + persistent-id="org.onap.ccsdk.sli.adaptors.messagerouter.publisher.provider" + update-strategy="container-managed" /> + </bean> + + <service ref="publisher" interface="org.onap.ccsdk.sli.adaptors.messagerouter.publisher.api.PublisherApi" /> + +</blueprint>
\ No newline at end of file diff --git a/message-router/publisher/provider/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/provider/impl/PublisherApiImplTest.java b/message-router/publisher/provider/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/provider/impl/PublisherApiImplTest.java new file mode 100644 index 000000000..53744f73e --- /dev/null +++ b/message-router/publisher/provider/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/provider/impl/PublisherApiImplTest.java @@ -0,0 +1,51 @@ +package org.onap.ccsdk.sli.adaptors.messagerouter.publisher.provider.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.junit.Test;
+
+public class PublisherApiImplTest {
+ @Test
+ public void verifyDefaultTimeouts() {
+ PublisherApiImpl pub = new PublisherApiImpl();
+ assertEquals(pub.DEFAULT_CONNECT_TIMEOUT, pub.connectTimeout);
+ assertEquals(pub.DEFAULT_READ_TIMEOUT, pub.readTimeout);
+ }
+
+ @Test
+ public void buildHttpURLConnection() throws Exception {
+ PublisherApiImpl pub = new PublisherApiImpl();
+ pub.init();
+
+ String myUserName = "Batman";
+ pub.setUsername(myUserName);
+ assertEquals(myUserName, pub.username);
+ String password = "P@$$";
+ pub.setPassword(password);
+
+ HttpURLConnection httpUrlConnection = pub.buildHttpURLConnection(new URL("http://localhost:7001"));
+ assertNotNull(httpUrlConnection.getReadTimeout());
+ assertNotNull(httpUrlConnection.getConnectTimeout());
+ assertEquals("application/json", httpUrlConnection.getRequestProperty("Content-Type"));
+ assertEquals("application/json", httpUrlConnection.getRequestProperty("Accept"));
+ }
+
+ @Test
+ public void testMultipleHosts() {
+ PublisherApiImpl pub = new PublisherApiImpl();
+ String myTopic = "worldNews";
+ String hostOne = "http://localhost:7001";
+ String hostTwo = "http://localhost:7002";
+ String hostThree = "http://localhost:7003";
+
+ pub.setHost(hostOne + "," + hostTwo + "," + hostThree);
+
+ assertEquals("http://localhost:7001/events/worldNews", pub.buildUrlString(0, myTopic));
+ assertEquals("http://localhost:7002/events/worldNews", pub.buildUrlString(1, myTopic));
+ assertEquals("http://localhost:7003/events/worldNews", pub.buildUrlString(2, myTopic));
+ }
+}
\ No newline at end of file diff --git a/message-router/publisher/sample.client/pom.xml b/message-router/publisher/sample.client/pom.xml new file mode 100755 index 000000000..694af1f4a --- /dev/null +++ b/message-router/publisher/sample.client/pom.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.sli.adaptors.messagerouter</groupId> + <artifactId>publisher.aggregate</artifactId> + <version>1.1.1-SNAPSHOT</version> + </parent> + + <artifactId>sample.client</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>publisher.api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Private-Package>${project.groupId}.publisher.client.impl</Private-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/message-router/publisher/sample.client/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/client/impl/ClientImpl.java b/message-router/publisher/sample.client/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/client/impl/ClientImpl.java new file mode 100755 index 000000000..d1610305a --- /dev/null +++ b/message-router/publisher/sample.client/src/main/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/client/impl/ClientImpl.java @@ -0,0 +1,58 @@ +/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2019 AT&T Intellectual Property. All rights reserved.
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.ccsdk.sli.adaptors.messagerouter.publisher.client.impl;
+
+import org.onap.ccsdk.sli.adaptors.messagerouter.publisher.api.PublisherApi;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClientImpl {
+ private static final Logger logger = LoggerFactory.getLogger(ClientImpl.class);
+ private String topic;
+ private PublisherApi publisher;
+
+ public ClientImpl() {
+
+ }
+
+ public void setPublisher(PublisherApi publisherApi) {
+ this.publisher = publisherApi;
+ }
+
+ public void setTopic(String topic) {
+ this.topic = topic;
+ }
+
+
+
+ public void init() {
+ for (int i = 0; i < 5; i++) {
+ String body = "{\"hello\":\"world " + Math.random() + "\"}";
+ logger.error("Loop iteration " + i + " sending body " + body + " to the topic " + topic);
+ Boolean result = publisher.publish(topic, body);
+ logger.error("Loop iteration " + i + " returned the boolean value " + result);
+ }
+ }
+
+}
\ No newline at end of file diff --git a/message-router/publisher/sample.client/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/message-router/publisher/sample.client/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100755 index 000000000..c2e981da2 --- /dev/null +++ b/message-router/publisher/sample.client/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0"> + + <bean id="client" + class="org.onap.ccsdk.sli.adaptors.messagerouter.publisher.client.impl.ClientImpl" + init-method="init"> + <property name="publisher" ref="publisher" /> + <cm:managed-properties + persistent-id="org.onap.ccsdk.sli.adaptors.messagerouter.publisher.client" + update-strategy="container-managed" /> + </bean> + + <reference id="publisher" interface="org.onap.ccsdk.sli.adaptors.messagerouter.publisher.api.PublisherApi" /> + +</blueprint>
\ No newline at end of file diff --git a/message-router/publisher/sample.client/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/client/impl/ClientImplTest.java b/message-router/publisher/sample.client/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/client/impl/ClientImplTest.java new file mode 100644 index 000000000..82a1566c3 --- /dev/null +++ b/message-router/publisher/sample.client/src/test/java/org/onap/ccsdk/sli/adaptors/messagerouter/publisher/client/impl/ClientImplTest.java @@ -0,0 +1,29 @@ +package org.onap.ccsdk.sli.adaptors.messagerouter.publisher.client.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.messagerouter.publisher.api.PublisherApi;
+
+public class ClientImplTest {
+
+ @Test
+ public void testSetTopic() {
+ ClientImpl impl = new ClientImpl();
+ String myTopic = "stock updates";
+ impl.setTopic(myTopic);
+
+ PublisherApi publisherImpl = new PublisherApi() {
+
+ @Override
+ public Boolean publish(String topic, String body) {
+ assertEquals(myTopic,topic);
+ return true;
+ }
+
+ };
+ impl.setPublisher(publisherImpl);
+ impl.init();
+ }
+
+}
diff --git a/netbox-client/installer/pom.xml b/netbox-client/installer/pom.xml new file mode 100755 index 000000000..44fa16490 --- /dev/null +++ b/netbox-client/installer/pom.xml @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 AT&T, Bell Canada + + 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. + --> + +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: netbox-client :: ${project.artifactId}</name> + + <properties> + <application.name>ccsdk-netbox-client</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + + + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client-provider</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>org.onap.ccsdk.sli.adaptors</includeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/netbox-client/installer/src/assembly/assemble_installer_zip.xml b/netbox-client/installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..ea3bef72e --- /dev/null +++ b/netbox-client/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,53 @@ +<!-- + Copyright (C) 2018 AT&T, Bell Canada + + 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. + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>installer_zip</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + +</assembly> diff --git a/netbox-client/installer/src/assembly/assemble_mvnrepo_zip.xml b/netbox-client/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..b905cfe3f --- /dev/null +++ b/netbox-client/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,43 @@ +<!-- + Copyright (C) 2018 AT&T, Bell Canada + + 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. + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + +</assembly> diff --git a/netbox-client/installer/src/main/resources/scripts/install-feature.sh b/netbox-client/installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..b48869120 --- /dev/null +++ b/netbox-client/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# +# Copyright (C) 2018 AT&T, Bell Canada +# +# 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. +# + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -nd ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/netbox-client/pom.xml b/netbox-client/pom.xml new file mode 100644 index 000000000..6c9dbe85c --- /dev/null +++ b/netbox-client/pom.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 AT&T, Bell Canada + + 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. + --> + +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: netbox-client</name> + <description>The SDNC Adaptors for netbox IPAM as an OSGi service</description> + + <modules> + <module>provider</module> + <module>installer</module> + </modules> +</project> diff --git a/netbox-client/provider/pom.xml b/netbox-client/provider/pom.xml new file mode 100644 index 000000000..2242a157b --- /dev/null +++ b/netbox-client/provider/pom.xml @@ -0,0 +1,137 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 AT&T, Bell Canada + + 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. + --> + +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client-provider</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-adaptors :: netbox-client :: ${project.artifactId}</name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-core-artifacts</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>${gson.version}</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>${apache.httpcomponents.core.version}</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>${apache.httpcomponents.client.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sliPluginUtils-provider</artifactId> + <version>${ccsdk.sli.core.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + + <!--Testing--> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <!-- Requires mockito v2 --> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>2.2.11</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.github.tomakehurst</groupId> + <artifactId>wiremock</artifactId> + <version>2.23.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-server</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package> + org.onap.ccsdk.sli.adaptors.netbox.api, + org.onap.ccsdk.sli.adaptors.netbox.ipam, + org.onap.ccsdk.sli.adaptors.netbox.model + </Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/IpamException.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/IpamException.java new file mode 100644 index 000000000..869a57cef --- /dev/null +++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/IpamException.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.api; + +public class IpamException extends Exception { + + public IpamException(final String message) { + super(message); + } + + public IpamException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/NetboxClient.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/NetboxClient.java new file mode 100644 index 000000000..f770d1543 --- /dev/null +++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/NetboxClient.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.api; + +import java.util.Map; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; + +/** + * This client is meant to interact both with the IPAM system, and the SDNC DB, in order to provide, at any time, + * an up to date status of the assigned resources. + */ +public interface NetboxClient extends SvcLogicJavaPlugin { + + /** + * Assign next available IP in prefix and store it in the SDNC database, table IPAM_IP_ASSIGNEMENT. + * + * @param parameters HashMap<String,String> of parameters passed by the DG to this function + * <table border="1"> + * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead> + * <tbody> + * <tr><td>service_instance_id</td><td>Mandatory</td><td>The service instance ID uniquely identifying the service.</td></tr> + * <tr><td>vf_module_id</td><td>Mandatory</td><td>The VF module ID uniquely identifying the VF.</td></tr> + * <tr><td>prefix_id</td><td>Mandatory</td><td>The prefix from which to get next available IP.</td></tr> + * </tbody> + * </table> + */ + QueryStatus assignIpAddress(Map<String, String> parameters, SvcLogicContext ctx); + + /** + * Release the IP and update the entry in the SDNC database, table IPAM_IP_ASSIGNEMENT. + * + * @param parameters HashMap<String,String> of parameters passed by the DG to this function + * <table border="1"> + * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead> + * <tbody> + * <tr><td>service_instance_id</td><td>Mandatory</td><td>The service instance ID uniquely identifying the service.</td></tr> + * <tr><td>vf_module_id</td><td>Mandatory</td><td>The VF module ID uniquely identifying the VF.</td></tr> + * <tr><td>ip_address_id</td><td>Mandatory</td><td>The IP to release.</td></tr> + * </tbody> + * </table> + */ + QueryStatus unassignIpAddress(Map<String, String> parameters, SvcLogicContext ctx); +} + diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImpl.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImpl.java new file mode 100644 index 000000000..bfb5ee530 --- /dev/null +++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImpl.java @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.impl; + +import com.google.common.collect.Lists; +import com.google.gson.JsonSyntaxException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Map; +import java.util.Properties; + +import javax.sql.rowset.CachedRowSet; +import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; +import org.onap.ccsdk.sli.adaptors.netbox.api.NetboxClient; +import org.onap.ccsdk.sli.adaptors.netbox.model.IPAddress; +import org.onap.ccsdk.sli.adaptors.netbox.model.IPStatus; +import org.onap.ccsdk.sli.adaptors.netbox.property.NetboxProperties; +import org.onap.ccsdk.sli.core.dblib.DBResourceManager; +import org.onap.ccsdk.sli.core.dblib.DbLibService; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.onap.ccsdk.sli.core.slipluginutils.SliPluginUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NetboxClientImpl implements NetboxClient { + + private static final Logger LOG = LoggerFactory.getLogger(NetboxClientImpl.class); + + // Netbox URI + + private static final String NEXT_AVAILABLE_IP_IN_PREFIX_PATH = "/api/ipam/prefixes/%s/available-ips/"; + private static final String IP_ADDRESS_PATH = "/api/ipam/ip-addresses/%s/"; + + // Netbox Payload + + private static final String ASSIGN_IP_ADDRESS_PAYLOAD = "{\n" + + " \"custom_fields\": {\n" + + " \"external-key\": \"%s\",\n" + + " \"resource-name\": \"%s\"\n" + + " }\n" + + "}"; + + // Service Logic Context input variables and exception + + private static final String SERVICE_INSTANCE_ID_PROP = "service_instance_id"; + private static final String VF_MODULE_ID_PROP = "vf_module_id"; + private static final String EXTERNAL_KEY_PROP = "external_key"; + private static final String SQL_EXCEPTION_MESSAGE = "Caught SQL exception"; + + // SQL statement + + private static final String ASSIGN_IP_SQL_STATEMENT = + "INSERT INTO IPAM_IP_ASSIGNEMENT (service_instance_id, vf_module_id, prefix_id, ip_address_id, ip_address, ip_status, ip_response_json, external_key, ip_address_type) \n" + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + private static final String UNASSIGN_IP_SQL_STATEMENT = + "UPDATE IPAM_IP_ASSIGNEMENT SET ip_status = ? WHERE service_instance_id = ? AND external_key = ?"; + private static final String GET_IP_ADDRESS_ID_SQL_STATEMENT = + "SELECT ip_address_id FROM IPAM_IP_ASSIGNEMENT WHERE service_instance_id = ? AND external_key = ?"; + + private final NetboxHttpClient client; + private final DbLibService dbLibService; + + public NetboxClientImpl() { + this(null, null); + } + + public NetboxClientImpl(final NetboxHttpClient client, final DbLibService dbLibService) { + if (client == null) { + this.client = new NetboxHttpClient(new NetboxProperties()); + } else { + this.client = client; + } + + if (dbLibService == null) { + Properties dblibProps = System.getProperties(); + + String cfgDir = dblibProps.getProperty("sdnc.config.dir", System.getenv("SDNC_CONFIG_DIR")); + + if ((cfgDir == null) || (cfgDir.length() == 0)) { + cfgDir = "/opt/sdnc/data/properties"; + } + + File dblibPropFile = new File(cfgDir + "/dblib.properties"); + if (dblibPropFile.exists()) { + try { + LOG.debug("Loading dblib properties from {}", dblibPropFile.getAbsolutePath()); + dblibProps = new Properties(); + dblibProps.load(new FileInputStream(dblibPropFile)); + } catch (Exception e) { + LOG.warn("Could not load properties file {}", dblibPropFile.getAbsolutePath(), e); + + dblibProps = System.getProperties(); + } + } + + DbLibService dbSvc = null; + try { + dbSvc = new DBResourceManager(dblibProps); + } catch (Exception e) { + LOG.error("Caught exception trying to create dblib service", e); + } + + try { + dbSvc = new DBResourceManager(dblibProps); + } catch (Exception e) { + LOG.error("Caught exception trying to create dblib service", e); + } + this.dbLibService = dbSvc; + + } else { + this.dbLibService = dbLibService; + } + } + + @Override + public QueryStatus assignIpAddress(final Map<String, String> parameters, final SvcLogicContext ctx) { + + try { + SliPluginUtils + .checkParameters(parameters, + new String[]{SERVICE_INSTANCE_ID_PROP, VF_MODULE_ID_PROP, "prefix_id", "resource_name", + EXTERNAL_KEY_PROP}, LOG); + } catch (SvcLogicException e) { + return QueryStatus.FAILURE; + } + + final String serviceInstanceId = parameters.get(SERVICE_INSTANCE_ID_PROP); + final String vfModuleId = parameters.get(VF_MODULE_ID_PROP); + final String prefixId = parameters.get("prefix_id"); + final String resourceName = parameters.get("resource_name"); + final String externalKey = parameters.get(EXTERNAL_KEY_PROP); + + HttpResponse httpResp; + try { + httpResp = client + .post(String.format(NEXT_AVAILABLE_IP_IN_PREFIX_PATH, prefixId), + String.format(ASSIGN_IP_ADDRESS_PAYLOAD, externalKey, resourceName)); + } catch (IOException e) { + LOG.error("Fail to assign IP for Prefix(id={}). {}", prefixId, e.getMessage(), e.getCause()); + return QueryStatus.FAILURE; + } + + String ipamRespJson; + try { + ipamRespJson = EntityUtils.toString(httpResp.getEntity(), "UTF-8"); + } catch (IOException e) { + LOG.error("Fail to parse IPAM response for assign in Prefix(id={}). Response={}", prefixId, + httpResp.getEntity(), e); + return QueryStatus.FAILURE; + } + + if (httpResp.getStatusLine().getStatusCode() != 201) { + LOG.error("Fail to assign IP for Prefix(id={}). HTTP code 201!={}. Response={}", prefixId, + httpResp.getStatusLine().getStatusCode(), ipamRespJson); + return QueryStatus.FAILURE; + } + + IPAddress ipAddress; + try { + ipAddress = IPAddress.fromJson(ipamRespJson); + } catch (JsonSyntaxException e) { + LOG.error("Fail to parse IPAM JSON reponse to IPAddress POJO. IPAM JSON Response={}", ipamRespJson, e); + return QueryStatus.FAILURE; + } + + ArrayList<String> args = Lists.newArrayList( + serviceInstanceId, + vfModuleId, + String.valueOf(prefixId), + String.valueOf(ipAddress.getId()), + ipAddress.getAddress(), + IPStatus.ASSIGNED.name(), + ipamRespJson, + externalKey, + resourceName); + + try { + dbLibService.writeData(ASSIGN_IP_SQL_STATEMENT, args, null); + } catch (SQLException e) { + LOG.error(SQL_EXCEPTION_MESSAGE, e); + return QueryStatus.FAILURE; + } + + ctx.setAttribute("self_serve_netbox_ip_assignement.ip-address", ipAddress.getAddress()); + + return QueryStatus.SUCCESS; + } + + @Override + public QueryStatus unassignIpAddress(final Map<String, String> parameters, final SvcLogicContext ctx) { + try { + SliPluginUtils + .checkParameters(parameters, new String[]{SERVICE_INSTANCE_ID_PROP, EXTERNAL_KEY_PROP}, + LOG); + } catch (SvcLogicException e) { + return QueryStatus.FAILURE; + } + + final String serviceInstanceId = parameters.get(SERVICE_INSTANCE_ID_PROP); + final String externalKey = parameters.get(EXTERNAL_KEY_PROP); + + String ipAddressId; + ArrayList<String> args = Lists.newArrayList( + serviceInstanceId, + externalKey); + try (CachedRowSet row = dbLibService.getData(GET_IP_ADDRESS_ID_SQL_STATEMENT, args, null)) { + if (row.next()) { + ipAddressId = row.getString("ip_address_id"); + } else { + throw new SQLException("Data not found."); + } + } catch (SQLException e) { + LOG.error(SQL_EXCEPTION_MESSAGE, e); + return QueryStatus.FAILURE; + } + + HttpResponse httpResp; + try { + httpResp = client.delete(String.format(IP_ADDRESS_PATH, ipAddressId)); + } catch (IOException e) { + LOG.error("Fail to unassign IP for IPAddress(id= " + ipAddressId + "). " + e.getMessage(), + e.getCause()); + return QueryStatus.FAILURE; + } + + if (httpResp.getStatusLine().getStatusCode() - 200 >= 100) { + LOG.error("Fail to unassign IP for IPAddress(id={}). HTTP code={}.", ipAddressId, + httpResp.getStatusLine().getStatusCode()); + return QueryStatus.FAILURE; + } + + args.clear(); + args = Lists.newArrayList( + IPStatus.DELETED.name(), + serviceInstanceId, + externalKey); + + try { + dbLibService.writeData(UNASSIGN_IP_SQL_STATEMENT, args, null); + } catch (SQLException e) { + LOG.error(SQL_EXCEPTION_MESSAGE, e); + return QueryStatus.FAILURE; + } + + return QueryStatus.SUCCESS; + } +} diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClient.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClient.java new file mode 100644 index 000000000..505c5a77e --- /dev/null +++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClient.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.impl; + +import static org.apache.http.HttpHeaders.ACCEPT; +import static org.apache.http.HttpHeaders.AUTHORIZATION; +import static org.apache.http.HttpHeaders.CONTENT_TYPE; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import javax.net.ssl.SSLContext; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.ssl.TrustStrategy; +import org.onap.ccsdk.sli.adaptors.netbox.property.NetboxProperties; + +public class NetboxHttpClient implements AutoCloseable { + + private static final String APPLICATION_JSON = "application/json"; + + private final CloseableHttpClient client; + private final String url; + private final String token; + + // Used by the blueprint container + public NetboxHttpClient(NetboxProperties properties) { + this(properties.getHost(), properties.getApiKey()); + } + + NetboxHttpClient(final String url, final String token) { + this.url = url; + this.token = token; + + final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; + final SSLContext sslContext; + try { + sslContext = SSLContexts.custom() + .loadTrustMaterial(null, acceptingTrustStrategy).build(); + } catch (final NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { + throw new IllegalStateException("Can't create http client", e); + } + client = HttpClientBuilder.create() + .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .setSSLContext(sslContext) + .build(); + } + + @Override + public void close() throws IOException { + client.close(); + } + + HttpResponse post(final String uri, final String requestBody) throws IOException { + final HttpPost request = new HttpPost(url + uri); + setHeaders(request); + request.setEntity(new StringEntity(requestBody, Charset.forName("UTF-8"))); + return client.execute(request); + } + + HttpResponse delete(final String uri) throws IOException { + final HttpDelete request = new HttpDelete(url + uri); + setHeaders(request); + return client.execute(request); + } + + private void setHeaders(final HttpRequestBase request) { + request.addHeader(ACCEPT, APPLICATION_JSON); + request.addHeader(CONTENT_TYPE, APPLICATION_JSON); + request.addHeader(AUTHORIZATION, "Token " + token); + } +}
\ No newline at end of file diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPAddress.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPAddress.java new file mode 100644 index 000000000..4c2880bc4 --- /dev/null +++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPAddress.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.model; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.util.Objects; + +public class IPAddress extends Identifiable { + + private static final Gson gson = new GsonBuilder().create(); + + private String address; + + public void setAddress(String address) { + this.address = address; + } + + public String getAddress() { + return address; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + IPAddress ipAddress = (IPAddress) o; + return Objects.equals(address, ipAddress.address); + } + + @Override + public int hashCode() { + return Objects.hash(address); + } + + public static IPAddress fromJson(final String json) { + return gson.fromJson(json, IPAddress.class); + } +} diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPStatus.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPStatus.java new file mode 100644 index 000000000..f3a74387a --- /dev/null +++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPStatus.java @@ -0,0 +1,5 @@ +package org.onap.ccsdk.sli.adaptors.netbox.model; + +public enum IPStatus { + ASSIGNED, DELETED +} diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Identifiable.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Identifiable.java new file mode 100644 index 000000000..501088d78 --- /dev/null +++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Identifiable.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.model; + +public abstract class Identifiable { + + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(final Integer id) { + this.id = id; + } +} diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Prefix.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Prefix.java new file mode 100644 index 000000000..b20be91db --- /dev/null +++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Prefix.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.model; + +public class Prefix extends Identifiable { + +} diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxProperties.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxProperties.java new file mode 100644 index 000000000..9b4751e64 --- /dev/null +++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxProperties.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.property; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Properties; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NetboxProperties { + + private static final Logger LOG = LoggerFactory.getLogger(NetboxProperties.class); + + private static final String NETBOX_PROPERTY_FILE_NAME = "netbox.properties"; + private static final String DEFAULT_PROPERTIES_DIR = "/opt/onap/ccsdk/data/properties"; + private static final String PROPERTIES_DIR_KEY = "SDNC_CONFIG_DIR"; + + private static final String NETBOX_URL_PROP = "org.onap.ccsdk.sli.adaptors.netbox.url"; + private static final String NETBOX_API_KEY_PROP = "org.onap.ccsdk.sli.adaptors.netbox.apikey"; + + private Properties properties; + + public NetboxProperties() { + loadProps(); + } + + public String getHost() { + return properties.getProperty(NETBOX_URL_PROP); + } + + public String getApiKey() { + return properties.getProperty(NETBOX_API_KEY_PROP); + } + + private void loadProps() { + properties = new Properties(); + // Try to load config from dir + final String ccsdkConfigDir = + System.getProperty(PROPERTIES_DIR_KEY, DEFAULT_PROPERTIES_DIR) + "/" + NETBOX_PROPERTY_FILE_NAME; + try (FileInputStream in = new FileInputStream(ccsdkConfigDir)) { + properties.load(in); + LOG.info("Loaded {} properties from file {}", properties.size(), ccsdkConfigDir); + } catch (Exception e) { + try { + // Try to load config from jar via OSGi + final Bundle bundle = FrameworkUtil.getBundle(NetboxProperties.class); + final BundleContext ctx = bundle.getBundleContext(); + final URL url = ctx.getBundle().getResource(NETBOX_PROPERTY_FILE_NAME); + InputStream inputStream = url.openStream(); + properties.load(inputStream); + LOG.info("Loaded {} properties from file {}", properties.size(), NETBOX_PROPERTY_FILE_NAME); + } catch (NoClassDefFoundError e1) { + // Try to load config from jar via class loader + try (InputStream inputStream = NetboxProperties.class.getResourceAsStream("/"+NETBOX_PROPERTY_FILE_NAME)) { + properties.load(inputStream); + } catch (Exception e2) { + LOG.error("Failed to load properties for file: {} " + NETBOX_PROPERTY_FILE_NAME, e1); + } + ; + LOG.info("Loaded {} properties from file {}", properties.size(), NETBOX_PROPERTY_FILE_NAME); + + } catch (IOException e1) { + LOG.error("Failed to load properties for file: {} " + NETBOX_PROPERTY_FILE_NAME, e1); + } + } + } +} diff --git a/netbox-client/provider/src/main/resources/OSGI-INF/blueprint/netbox-client.xml b/netbox-client/provider/src/main/resources/OSGI-INF/blueprint/netbox-client.xml new file mode 100644 index 000000000..b667dcba5 --- /dev/null +++ b/netbox-client/provider/src/main/resources/OSGI-INF/blueprint/netbox-client.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 AT&T, Bell Canada + + 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. + --> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <reference id="dbLibService" + interface="org.onap.ccsdk.sli.core.dblib.DbLibService"/> + + <bean id="netboxProperty" class="org.onap.ccsdk.sli.adaptors.netbox.property.NetboxProperties"/> + <bean id="httpClient" class="org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxHttpClient" destroy-method="close"> + <argument ref="netboxProperty"/> + </bean> + + <bean id="netboxClient" class="org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxClientImpl"> + <argument ref="httpClient"/> + <argument ref="dbLibService"/> + </bean> + + <service ref="netboxClient" + interface="org.onap.ccsdk.sli.adaptors.netbox.api.NetboxClient" + odl:type="default"/> + +</blueprint> diff --git a/netbox-client/provider/src/main/resources/netbox.properties b/netbox-client/provider/src/main/resources/netbox.properties new file mode 100644 index 000000000..4346d1774 --- /dev/null +++ b/netbox-client/provider/src/main/resources/netbox.properties @@ -0,0 +1,19 @@ +# +# Copyright (C) 2019 Bell Canada. +# +# 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. +# + +# Configuration file for Netbox client +org.onap.ccsdk.sli.adaptors.netbox.url=http://netbox-nginx:8080 +org.onap.ccsdk.sli.adaptors.netbox.apikey=onceuponatimeiplayedwithnetbox20180814
\ No newline at end of file diff --git a/netbox-client/provider/src/main/resources/org/opendaylight/blueprint/netbox-client.xml b/netbox-client/provider/src/main/resources/org/opendaylight/blueprint/netbox-client.xml new file mode 100644 index 000000000..b667dcba5 --- /dev/null +++ b/netbox-client/provider/src/main/resources/org/opendaylight/blueprint/netbox-client.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2018 AT&T, Bell Canada + + 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. + --> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <reference id="dbLibService" + interface="org.onap.ccsdk.sli.core.dblib.DbLibService"/> + + <bean id="netboxProperty" class="org.onap.ccsdk.sli.adaptors.netbox.property.NetboxProperties"/> + <bean id="httpClient" class="org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxHttpClient" destroy-method="close"> + <argument ref="netboxProperty"/> + </bean> + + <bean id="netboxClient" class="org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxClientImpl"> + <argument ref="httpClient"/> + <argument ref="dbLibService"/> + </bean> + + <service ref="netboxClient" + interface="org.onap.ccsdk.sli.adaptors.netbox.api.NetboxClient" + odl:type="default"/> + +</blueprint> diff --git a/netbox-client/provider/src/test/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplTest.java b/netbox-client/provider/src/test/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplTest.java new file mode 100644 index 000000000..624a1906e --- /dev/null +++ b/netbox-client/provider/src/test/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplTest.java @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.impl; + +import static com.github.tomakehurst.wiremock.client.WireMock.created; +import static com.github.tomakehurst.wiremock.client.WireMock.delete; +import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.givenThat; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.serverError; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.apache.http.HttpHeaders.ACCEPT; +import static org.apache.http.HttpHeaders.AUTHORIZATION; +import static org.apache.http.HttpHeaders.CONTENT_TYPE; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.Appender; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableMap; +import com.google.common.io.Resources; +import java.io.IOException; +import java.net.URL; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.sql.rowset.CachedRowSet; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.onap.ccsdk.sli.core.dblib.DbLibService; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.slf4j.LoggerFactory; + +@RunWith(MockitoJUnitRunner.class) +public class NetboxClientImplTest { + + private static final String APPLICATION_JSON = "application/json"; + + @Rule + public WireMockRule wm = new WireMockRule(wireMockConfig().dynamicPort()); + @Mock + private DbLibService dbLib; + @Mock + private SvcLogicContext svcLogicContext; + @Mock + private Appender<ILoggingEvent> appender; + @Captor + private ArgumentCaptor<ILoggingEvent> captor; + + + private String token = "token"; + private String serviceInstanceId = UUID.randomUUID().toString(); + private String vfModuleId = UUID.randomUUID().toString(); + + private Map<String, String> params = ImmutableMap + .of("service_instance_id", serviceInstanceId, + "vf_module_id", vfModuleId, + "prefix_id", "3", + "external_key", "3", + "resource_name", "3" + ); + + private NetboxHttpClient httpClient; + private NetboxClientImpl netboxClient; + + @Mock + private NetboxHttpClient httpClientMock; + @Mock + private NetboxClientImpl netboxClientMock; + + + @Before + public void setup() { + ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory + .getLogger(NetboxClientImpl.class); + logger.addAppender(appender); + + String baseUrl = "http://localhost:" + wm.port(); + + httpClient = new NetboxHttpClient(baseUrl, token); + + netboxClient = new NetboxClientImpl(httpClient, dbLib); + + netboxClientMock = new NetboxClientImpl(httpClientMock, dbLib); + + wm.addMockServiceRequestListener( + (request, response) -> { + System.out.println("Request URL :" + request.getAbsoluteUrl()); + System.out.println("Request body :" + request.getBodyAsString()); + System.out.println("Response status :" + response.getStatus()); + System.out.println("Response body :" + response.getBodyAsString()); + }); + } + + @After + public void tearDown() throws IOException { + httpClient.close(); + } + + @Test + public void unassignIpAddressTestNoParams() { + QueryStatus status = netboxClient.unassignIpAddress(ImmutableMap.of(), svcLogicContext); + Assert.assertEquals(QueryStatus.FAILURE, status); + verifyLogEntry( + "This method requires the parameters [service_instance_id,external_key], but no parameters were passed in."); + } + + @Test + public void unassignIpAddressFailedRequest() throws IOException, SQLException { + doThrow(new IOException("Failed request")).when(httpClientMock).delete(anyString()); + + CachedRowSet crs = mock(CachedRowSet.class); + doReturn("3").when(crs).getString(eq("ip_address_id")); + doReturn(true).when(crs).next(); + doReturn(crs).when(dbLib).getData(anyString(), any(ArrayList.class), eq(null)); + + QueryStatus status = netboxClientMock + .unassignIpAddress(params, svcLogicContext); + + Assert.assertEquals(QueryStatus.FAILURE, status); + verifyLogEntry("Fail to unassign IP for IPAddress(id= 3). Failed request"); + } + + @Test + public void unassignIpAddressServerError() throws SQLException { + + String expectedUrl = "/api/ipam/ip-addresses/3/"; + givenThat(delete(urlEqualTo(expectedUrl)).willReturn(serverError())); + + CachedRowSet crs = mock(CachedRowSet.class); + doReturn("3").when(crs).getString(eq("ip_address_id")); + doReturn(true).when(crs).next(); + doReturn(crs).when(dbLib).getData(anyString(), any(ArrayList.class), eq(null)); + + QueryStatus status = netboxClient.unassignIpAddress(params, svcLogicContext); + + Assert.assertEquals(QueryStatus.FAILURE, status); + verifyLogEntry("Fail to unassign IP for IPAddress(id=3). HTTP code=500."); + } + + @Test + public void unassignIpAddressFailSQL() throws IOException, SQLException { + + String response = "{}"; + + String expectedUrl = "/api/ipam/ip-addresses/3/"; + givenThat(delete(urlEqualTo(expectedUrl)).willReturn(created().withBody(response))); + + CachedRowSet crs = mock(CachedRowSet.class); + doReturn(true).when(crs).next(); + doReturn("3").when(crs).getString(eq("ip_address_id")); + doReturn(crs).when(dbLib).getData(anyString(), any(ArrayList.class), eq(null)); + + doThrow(new SQLException("Failed")).when(dbLib).writeData(anyString(), any(ArrayList.class), eq(null)); + + QueryStatus status = netboxClient.unassignIpAddress(params, svcLogicContext); + + Assert.assertEquals(QueryStatus.FAILURE, status); + verifyLogEntry("Caught SQL exception"); + } + + @Test + public void unassignIpAddressSuccess() throws IOException, SQLException { + String response = "{}"; + + String expectedUrl = "/api/ipam/ip-addresses/3/"; + givenThat(delete(urlEqualTo(expectedUrl)).willReturn(created().withBody(response))); + + CachedRowSet crs = mock(CachedRowSet.class); + doReturn("3").when(crs).getString(eq("ip_address_id")); + doReturn(true).when(crs).next(); + doReturn(crs).when(dbLib).getData(anyString(), any(ArrayList.class), eq(null)); + + QueryStatus status = netboxClient.unassignIpAddress(params, svcLogicContext); + + verify(deleteRequestedFor(urlEqualTo(expectedUrl)) + .withHeader(ACCEPT, equalTo(APPLICATION_JSON)) + .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON)) + .withHeader(AUTHORIZATION, equalTo("Token " + token))); + + Mockito.verify(dbLib).writeData(anyString(), any(ArrayList.class), eq(null)); + Assert.assertEquals(QueryStatus.SUCCESS, status); + } + + + @Test + public void nextAvailableIpInPrefixTestNoId() { + QueryStatus status = netboxClient.assignIpAddress(ImmutableMap.of(), svcLogicContext); + Assert.assertEquals(QueryStatus.FAILURE, status); + verifyLogEntry( + "This method requires the parameters [service_instance_id,vf_module_id,prefix_id,resource_name,external_key], but no parameters were passed in."); + } + + @Test + public void nextAvailableIpInPrefixFailedRequest() throws IOException { + doThrow(new IOException("Failed request")).when(httpClientMock).post(anyString(), anyString()); + QueryStatus status = netboxClientMock.assignIpAddress(params, svcLogicContext); + + Assert.assertEquals(QueryStatus.FAILURE, status); + verifyLogEntry("Fail to assign IP for Prefix(id=3). Failed request"); + } + + @Test + public void nextAvailableIpInPrefixBadRespPayload() throws IOException { + URL url = Resources.getResource("badResponse.json"); + String response = Resources.toString(url, Charsets.UTF_8); + + String expectedUrl = "/api/ipam/prefixes/3/available-ips/"; + givenThat(post(urlEqualTo(expectedUrl)).willReturn(created().withBody(response))); + + QueryStatus status = netboxClient.assignIpAddress(params, svcLogicContext); + + Assert.assertEquals(QueryStatus.FAILURE, status); + verifyLogEntry("Fail to parse IPAM JSON reponse to IPAddress POJO. IPAM JSON Response={\n" + + " \"id\": 8\n" + + " \"address\": \"192.168.20.7/32\"\n" + + "}"); + } + + @Test + public void nextAvailableIpInPrefixFailSQL() throws IOException, SQLException { + URL url = Resources.getResource("nextAvailableIpResponse.json"); + String response = Resources.toString(url, Charsets.UTF_8); + + String expectedUrl = "/api/ipam/prefixes/3/available-ips/"; + givenThat(post(urlEqualTo(expectedUrl)).willReturn(created().withBody(response))); + + doThrow(new SQLException("Failed")).when(dbLib).writeData(anyString(), any(ArrayList.class), eq(null)); + + QueryStatus status = netboxClient.assignIpAddress(params, svcLogicContext); + + Assert.assertEquals(QueryStatus.FAILURE, status); + verifyLogEntry("Caught SQL exception"); + } + + @Test + public void nextAvailableIpInPrefixError500() throws IOException { + URL url = Resources.getResource("nextAvailableIpResponse.json"); + String response = Resources.toString(url, Charsets.UTF_8); + + String expectedUrl = "/api/ipam/prefixes/3/available-ips/"; + givenThat(post(urlEqualTo(expectedUrl)).willReturn(serverError().withBody(response))); + + QueryStatus status = netboxClient.assignIpAddress(params, svcLogicContext); + + Assert.assertEquals(QueryStatus.FAILURE, status); + verifyLogEntry("Fail to assign IP for Prefix(id=3). HTTP code 201!=500."); + } + + @Test + public void nextAvailableIpInPrefixSuccess() throws IOException, SQLException { + URL url = Resources.getResource("nextAvailableIpResponse.json"); + String response = Resources.toString(url, Charsets.UTF_8); + + String expectedUrl = "/api/ipam/prefixes/3/available-ips/"; + givenThat(post(urlEqualTo(expectedUrl)).willReturn(created().withBody(response))); + + QueryStatus status = netboxClient.assignIpAddress(params, svcLogicContext); + + verify(postRequestedFor(urlEqualTo(expectedUrl)) + .withHeader(ACCEPT, equalTo(APPLICATION_JSON)) + .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON)) + .withHeader(AUTHORIZATION, equalTo("Token " + token))); + + Mockito.verify(dbLib).writeData(anyString(), any(ArrayList.class), eq(null)); + Assert.assertEquals(QueryStatus.SUCCESS, status); + } + + private void verifyLogEntry(String message) { + Mockito.verify(appender, times(1)).doAppend(captor.capture()); + List<ILoggingEvent> allValues = captor.getAllValues(); + for (ILoggingEvent loggingEvent : allValues) { + Assert.assertTrue(loggingEvent.getFormattedMessage().contains(message)); + } + } + +}
\ No newline at end of file diff --git a/netbox-client/provider/src/test/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientTest.java b/netbox-client/provider/src/test/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientTest.java new file mode 100644 index 000000000..8634742ae --- /dev/null +++ b/netbox-client/provider/src/test/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.impl; + +import static com.github.tomakehurst.wiremock.client.WireMock.delete; +import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.givenThat; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.apache.http.HttpHeaders.ACCEPT; +import static org.apache.http.HttpHeaders.CONTENT_TYPE; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import java.io.IOException; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +public class NetboxHttpClientTest { + + private static final String APPLICATION_JSON = "application/json"; + + @Rule + public WireMockRule wm = new WireMockRule(wireMockConfig().dynamicPort()); + + private NetboxHttpClient httpClient; + + @Before + public void setup() { + String baseUrl = "http://localhost:" + wm.port(); + String token = "token"; + + httpClient = new NetboxHttpClient(baseUrl, token); + + wm.addMockServiceRequestListener( + (request, response) -> { + System.out.println("Request URL :" + request.getAbsoluteUrl()); + System.out.println("Request body :" + request.getBodyAsString()); + System.out.println("Response status :" + response.getStatus()); + System.out.println("Response body :" + response.getBodyAsString()); + }); + } + + @After + public void tearDown() throws IOException { + httpClient.close(); + } + + @Test + public void postTest() throws IOException { + String expectedUrl = "/testPost"; + givenThat(post(urlEqualTo(expectedUrl)).willReturn(ok())); + + httpClient.post(expectedUrl, ""); + + verify(postRequestedFor(urlEqualTo(expectedUrl)) + .withHeader(ACCEPT, equalTo(APPLICATION_JSON)) + .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON))); + } + + @Test + public void deleteTest() throws IOException { + String expectedUrl = "/testDelete"; + givenThat(delete(urlEqualTo(expectedUrl)).willReturn(ok())); + httpClient.delete(expectedUrl); + verify(deleteRequestedFor(urlEqualTo(expectedUrl)) + .withHeader(ACCEPT, equalTo(APPLICATION_JSON)) + .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON))); + } +} diff --git a/netbox-client/provider/src/test/resources/badResponse.json b/netbox-client/provider/src/test/resources/badResponse.json new file mode 100644 index 000000000..713109fd9 --- /dev/null +++ b/netbox-client/provider/src/test/resources/badResponse.json @@ -0,0 +1,4 @@ +{ + "id": 8 + "address": "192.168.20.7/32" +}
\ No newline at end of file diff --git a/netbox-client/provider/src/test/resources/nextAvailableIpResponse.json b/netbox-client/provider/src/test/resources/nextAvailableIpResponse.json new file mode 100644 index 000000000..dec1245e9 --- /dev/null +++ b/netbox-client/provider/src/test/resources/nextAvailableIpResponse.json @@ -0,0 +1,13 @@ +{ + "id": 8, + "address": "192.168.20.7/32", + "vrf": null, + "tenant": 1, + "status": 1, + "role": null, + "interface": null, + "description": "", + "nat_inside": null, + "created": "2018-08-15", + "last_updated": "2018-08-15T15:51:26.634903Z" +}
\ No newline at end of file diff --git a/releases/0.5.0.yaml b/releases/0.5.0.yaml new file mode 100644 index 000000000..37812aa12 --- /dev/null +++ b/releases/0.5.0.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '0.5.0' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/160/' diff --git a/releases/0.5.1.yaml b/releases/0.5.1.yaml new file mode 100644 index 000000000..3a5c7e5a4 --- /dev/null +++ b/releases/0.5.1.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '0.5.1' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/166/' diff --git a/releases/0.5.2.yaml b/releases/0.5.2.yaml new file mode 100644 index 000000000..b12976297 --- /dev/null +++ b/releases/0.5.2.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '0.5.2' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/175/' diff --git a/releases/0.6.0.yaml b/releases/0.6.0.yaml new file mode 100644 index 000000000..44bed26c8 --- /dev/null +++ b/releases/0.6.0.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '0.6.0' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/189/' diff --git a/releases/0.6.1.yaml b/releases/0.6.1.yaml new file mode 100644 index 000000000..54d356532 --- /dev/null +++ b/releases/0.6.1.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '0.6.1' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/206/' diff --git a/releases/0.7.0.yaml b/releases/0.7.0.yaml new file mode 100644 index 000000000..e0490b849 --- /dev/null +++ b/releases/0.7.0.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '0.7.0' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/304/' diff --git a/releases/0.7.1.yaml b/releases/0.7.1.yaml new file mode 100644 index 000000000..da8191dee --- /dev/null +++ b/releases/0.7.1.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '0.7.1' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/305/' diff --git a/releases/1.0.0.yaml b/releases/1.0.0.yaml new file mode 100644 index 000000000..b7c72915b --- /dev/null +++ b/releases/1.0.0.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '1.0.0' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/306/' diff --git a/releases/1.0.1.yaml b/releases/1.0.1.yaml new file mode 100644 index 000000000..3499a88b4 --- /dev/null +++ b/releases/1.0.1.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '1.0.1' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/307/' diff --git a/releases/1.1.0.yaml b/releases/1.1.0.yaml new file mode 100644 index 000000000..9aa20862e --- /dev/null +++ b/releases/1.1.0.yaml @@ -0,0 +1,5 @@ +--- +distribution_type: 'maven' +version: '1.1.0' +project: 'ccsdk-sli-adaptors' +log_dir: 'ccsdk-sli-adaptors-maven-stage-master/308/' diff --git a/resource-assignment/.gitignore b/resource-assignment/.gitignore new file mode 100755 index 000000000..b73caf31e --- /dev/null +++ b/resource-assignment/.gitignore @@ -0,0 +1,34 @@ +#####standard .git ignore entries##### + +## IDE Specific Files ## +org.eclipse.core.resources.prefs +.classpath +.project +.settings +.idea +.externalToolBuilders +maven-eclipse.xml +workspace + +## Compilation Files ## +*.class +**/target +target +target-ide +MANIFEST.MF + +## Misc Ignores (OS specific etc) ## +bin/ +dist +*~ +*.ipr +*.iml +*.iws +classes +out/ +.DS_STORE +.metadata + +## Folders which contain auto generated source code ## +yang-gen-config +yang-gen-sal diff --git a/resource-assignment/.sonar/checkstyle.xml b/resource-assignment/.sonar/checkstyle.xml new file mode 100755 index 000000000..3fa231535 --- /dev/null +++ b/resource-assignment/.sonar/checkstyle.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"><!-- Generated by Sonar --><module name="Checker"><module name="SuppressionCommentFilter"/><module name="TreeWalker"><module name="FileContentsHolder"/> <module name="ClassFanOutComplexity"><property name="severity" value="warning"/></module><module name="NestedForDepth"><property name="severity" value="warning"/><property name="max" value="1"/></module><module name="ClassDataAbstractionCoupling"><property name="severity" value="warning"/></module></module></module>
\ No newline at end of file diff --git a/resource-assignment/.sonar/pmd.xml b/resource-assignment/.sonar/pmd.xml new file mode 100755 index 000000000..80343b3bd --- /dev/null +++ b/resource-assignment/.sonar/pmd.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<ruleset>
+ <rule ref="rulesets/java/naming.xml/BooleanGetMethodName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/j2ee.xml/StaticEJBFieldShouldBeFinal">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/coupling.xml/CouplingBetweenObjects">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/codesize.xml/TooManyMethods">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingTypeName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/basic.xml/DoubleCheckedLocking">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingMethodName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/coupling.xml/ExcessiveImports">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/basic.xml/OverrideBothEqualsAndHashcode">
+ <priority>2</priority>
+ </rule>
+ <rule ref="rulesets/java/naming.xml/ShortMethodName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/basic.xml/BooleanInstantiation">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/codesize.xml/TooManyFields">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/controversial.xml/AvoidUsingNativeCode">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/optimizations.xml/UseStringBufferForStringAppends">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/coupling.xml/LooseCoupling">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/design.xml/NonThreadSafeSingleton">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/j2ee.xml/DoNotUseThreads">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/sunsecure.xml/ArrayIsStoredDirectly">
+ <priority>5</priority>
+ </rule>
+ <rule ref="rulesets/java/sunsecure.xml/MethodReturnsInternalArray">
+ <priority>2</priority>
+ </rule>
+ <rule ref="rulesets/java/design.xml/AssignmentToNonFinalStatic">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/strictexception.xml/AvoidCatchingGenericException">
+ <priority>3</priority>
+ </rule>
+</ruleset>
+
diff --git a/resource-assignment/installer/pom.xml b/resource-assignment/installer/pom.xml new file mode 100755 index 000000000..11ff40ce3 --- /dev/null +++ b/resource-assignment/installer/pom.xml @@ -0,0 +1,128 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>resource-assignment-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: resource-assignment :: ${project.artifactId}</name> + + <properties> + <application.name>ccsdk-resource-assignment</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>resource-assignment-provider</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>org.onap.ccsdk.sli.adaptors</includeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/resource-assignment/installer/src/assembly/assemble_installer_zip.xml b/resource-assignment/installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..b81e1d47a --- /dev/null +++ b/resource-assignment/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>installer_zip</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/resource-assignment/installer/src/assembly/assemble_mvnrepo_zip.xml b/resource-assignment/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..9b4a25f49 --- /dev/null +++ b/resource-assignment/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,49 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/resource-assignment/installer/src/main/resources/scripts/install-feature.sh b/resource-assignment/installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..06f5b7d5e --- /dev/null +++ b/resource-assignment/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -nd ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/resource-assignment/pom.xml b/resource-assignment/pom.xml new file mode 100755 index 000000000..c2ef269ca --- /dev/null +++ b/resource-assignment/pom.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>resource-assignment</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: resource-assignment</name> + <description>The resource assignment adaptor allows service logic to check and allocate network capacity</description> + + <modules> + <module>provider</module> + <module>installer</module> + </modules> +</project> diff --git a/resource-assignment/provider/pom.xml b/resource-assignment/provider/pom.xml new file mode 100755 index 000000000..014daeae5 --- /dev/null +++ b/resource-assignment/provider/pom.xml @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>resource-assignment-provider</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-adaptors :: resource-assignment :: ${project.artifactId}</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-core-artifacts</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>dblib-provider</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.mariadb.jdbc</groupId> + <artifactId>mariadb-java-client</artifactId> + <type>jar</type> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-jdbc</artifactId> + </dependency> + </dependencies> +</project> diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/LockHelper.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/LockHelper.java new file mode 100644 index 000000000..040d19273 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/LockHelper.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.lock.comp; + +import java.util.Collection; + +public interface LockHelper { + + void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */); + + void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */, int lockWait /* Seconds */, int retryCount); + + void unlock(String resourceName, boolean force); + + void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */); + + void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */, int lockWait /* Seconds */, int retryCount); + + void unlock(Collection<String> resourceNameList, boolean force); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/LockHelperImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/LockHelperImpl.java new file mode 100644 index 000000000..735d240c0 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/LockHelperImpl.java @@ -0,0 +1,206 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.lock.comp; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import org.onap.ccsdk.sli.adaptors.lock.dao.ResourceLockDao; +import org.onap.ccsdk.sli.adaptors.lock.data.ResourceLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LockHelperImpl implements LockHelper { + + private static final Logger log = LoggerFactory.getLogger(LockHelperImpl.class); + + private ResourceLockDao resourceLockDao; + private int retryCount = 10; + private int lockWait = 5; // Seconds + + @Override + public void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */) { + lock(resourceName, lockRequester, lockTimeout, lockWait, retryCount); + } + + @Override + public void lock(String resourceName, String lockRequester, int lockTimeout /* Seconds */, + int lockWait /* Seconds */, int retryCount) { + lock(Collections.singleton(resourceName), lockRequester, lockTimeout, lockWait, retryCount); + } + + @Override + public void unlock(String resourceName, boolean force) { + unlock(Collections.singleton(resourceName), force); + } + + @Override + public void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) { + lock(resourceNameList, lockRequester, lockTimeout, lockWait, retryCount); + } + + @Override + public void lock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */, + int lockWait /* Seconds */, int retryCount) { + for (int i = 0; true; i++) { + try { + tryLock(resourceNameList, lockRequester, lockTimeout); + log.info("Resources locked: " + resourceNameList); + return; + } catch (ResourceLockedException e) { + if (i >= retryCount) { + throw e; + } + try { + Thread.sleep(lockWait * 1000); + } catch (InterruptedException ex) { + log.error("Interrupted Exception", ex); + } + } + } + } + + @Override + public void unlock(Collection<String> lockNames, boolean force) { + if (lockNames == null || lockNames.isEmpty()) { + return; + } + + try { + for (String name : lockNames) { + ResourceLock l = resourceLockDao.getByResourceName(name); + if (l != null) { + if (force || l.lockCount == 1) { + resourceLockDao.delete(l.id); + } else { + resourceLockDao.decrementLockCount(l.id); + } + } + } + + resourceLockDao.commit(); + + log.info("Resources unlocked: " + lockNames); + } finally { + resourceLockDao.rollback(); + } + } + + public void tryLock(Collection<String> resourceNameList, String lockRequester, int lockTimeout /* Seconds */) { + if (resourceNameList == null || resourceNameList.isEmpty()) { + return; + } + + lockRequester = generateLockRequester(lockRequester, 100); + + // First check if all requested records are available to lock + + Date now = new Date(); + + try { + List<ResourceLock> dbLockList = new ArrayList<>(); + List<String> insertLockNameList = new ArrayList<>(); + for (String name : resourceNameList) { + ResourceLock l = resourceLockDao.getByResourceName(name); + + boolean canLock = l == null || now.getTime() > l.expirationTime.getTime() || + lockRequester != null && lockRequester.equals(l.lockHolder) || l.lockCount <= 0; + if (!canLock) { + throw new ResourceLockedException(l.resourceName, l.lockHolder, lockRequester); + } + + if (l != null) { + if (now.getTime() > l.expirationTime.getTime() || l.lockCount <= 0) { + l.lockCount = 0; + } + dbLockList.add(l); + } else { + insertLockNameList.add(name); + } + } + + // Update the lock info in DB + for (ResourceLock l : dbLockList) { + resourceLockDao.update(l.id, lockRequester, now, new Date(now.getTime() + lockTimeout * 1000), l.lockCount + 1); + } + + // Insert records for those that are not yet there + for (String lockName : insertLockNameList) { + ResourceLock l = new ResourceLock(); + l.resourceName = lockName; + l.lockHolder = lockRequester; + l.lockTime = now; + l.expirationTime = new Date(now.getTime() + lockTimeout * 1000); + l.lockCount = 1; + + try { + resourceLockDao.add(l); + } catch (Exception e) { + log.info("Failed to insert lock record: " + lockName); + throw new ResourceLockedException(l.resourceName, "unknown", lockRequester); + } + } + + resourceLockDao.commit(); + + }finally + + { + resourceLockDao.rollback(); + } + } + + private static String generateLockRequester(String name, int maxLength) { + if (name == null) { + name = ""; + } + int l1 = name.length(); + String tname = Thread.currentThread().getName(); + int l2 = tname.length(); + if (l1 + l2 + 1 > maxLength) { + int maxl1 = maxLength / 2; + if (l1 > maxl1) { + name = name.substring(0, maxl1); + l1 = maxl1; + } + int maxl2 = maxLength - l1 - 1; + if (l2 > maxl2) { + tname = tname.substring(0, 6) + "..." + tname.substring(l2 - maxl2 + 9); + } + } + return tname + '-' + name; + } + + public void setResourceLockDao(ResourceLockDao resourceLockDao) { + this.resourceLockDao = resourceLockDao; + } + + public void setRetryCount(int retryCount) { + this.retryCount = retryCount; + } + + public void setLockWait(int lockWait /* Seconds */) { + this.lockWait = lockWait; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/ResourceLockedException.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/ResourceLockedException.java new file mode 100644 index 000000000..f503332cc --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/ResourceLockedException.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.lock.comp; + +public class ResourceLockedException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private final String lockName; + private final String lockHolder; + private final String lockRequester; + + public ResourceLockedException(String lockName, String lockHolder, String lockRequester) { + this.lockName = lockName; + this.lockHolder = lockHolder; + this.lockRequester = lockRequester; + } + + @Override + public String getMessage() { + return "Failed to lock [" + lockName + "] for [" + lockRequester + "]. Currently locked by [" + lockHolder + + "]."; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/SynchronizedFunction.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/SynchronizedFunction.java new file mode 100644 index 000000000..9cce17a46 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/comp/SynchronizedFunction.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.lock.comp; + +import java.security.SecureRandom; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public abstract class SynchronizedFunction { + + private Set<String> synchset; + private String lockRequester; + private int lockTimeout; // Seconds + private LockHelper lockHelper; + + protected SynchronizedFunction(LockHelper lockHelper, Collection<String> synchset, int lockTimeout) { + this.lockHelper = lockHelper; + this.synchset = new HashSet<String>(synchset); + this.lockRequester = generateLockRequester(); + this.lockTimeout = lockTimeout; + } + + protected abstract void _exec(); + + public void exec() { + lockHelper.lock(synchset, lockRequester, lockTimeout); + try { + _exec(); + } finally { + lockHelper.unlock(synchset, true); + } + } + + private static String generateLockRequester() { + SecureRandom rand = new SecureRandom(); + return "SynchronizedFunction-" + (int) (rand.nextDouble() * 1000000); + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/dao/ResourceLockDao.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/dao/ResourceLockDao.java new file mode 100644 index 000000000..dc86f70af --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/dao/ResourceLockDao.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.lock.dao; + +import java.util.Date; +import org.onap.ccsdk.sli.adaptors.lock.data.ResourceLock; + +public interface ResourceLockDao { + + void add(ResourceLock l); + + void update(long id, String lockHolder, Date lockTime, Date expirationTime, int lockCount); + + ResourceLock getByResourceName(String resourceName); + + void delete(long id); + + void decrementLockCount(long id); + + void commit(); + + void rollback(); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/dao/ResourceLockDaoImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/dao/ResourceLockDaoImpl.java new file mode 100644 index 000000000..b8b3a66d6 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/dao/ResourceLockDaoImpl.java @@ -0,0 +1,103 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.lock.dao; + +import java.util.Date; +import java.util.List; +import org.onap.ccsdk.sli.adaptors.lock.data.ResourceLock; +import org.onap.ccsdk.sli.adaptors.util.db.CachedDataSourceWrap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +public class ResourceLockDaoImpl implements ResourceLockDao { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(ResourceLockDaoImpl.class); + + private JdbcTemplate jdbcTemplate; + + @Override + public void add(ResourceLock l) { + jdbcTemplate.update( + "INSERT INTO RESOURCE_LOCK (resource_name, lock_holder, lock_count, lock_time, expiration_time)\n" + + "VALUES (?, ?, ?, ?, ?)", + new Object[] { l.resourceName, l.lockHolder, l.lockCount, l.lockTime, l.expirationTime }); + } + + @Override + public void update(long id, String lockHolder, Date lockTime, Date expirationTime, int lockCount) { + jdbcTemplate.update( + "UPDATE RESOURCE_LOCK SET lock_holder = ?, lock_time = ?, expiration_time = ?, lock_count = ? WHERE resource_lock_id = ?", + new Object[] { lockHolder, lockTime, expirationTime, lockCount, id }); + } + + @Override + public ResourceLock getByResourceName(String resourceName) { + List<ResourceLock> ll = jdbcTemplate.query("SELECT * FROM RESOURCE_LOCK WHERE resource_name = ?", + new Object[] { resourceName }, (RowMapper<ResourceLock>) (rs, rowNum) -> { + ResourceLock rl = new ResourceLock(); + rl.id = rs.getLong("resource_lock_id"); + rl.resourceName = rs.getString("resource_name"); + rl.lockHolder = rs.getString("lock_holder"); + rl.lockCount = rs.getInt("lock_count"); + rl.lockTime = rs.getTimestamp("lock_time"); + rl.expirationTime = rs.getTimestamp("expiration_time"); + return rl; + }); + return ll != null && !ll.isEmpty() ? ll.get(0) : null; + } + + @Override + public void delete(long id) { + jdbcTemplate.update("DELETE FROM RESOURCE_LOCK WHERE resource_lock_id = ?", new Object[] { id }); + } + + @Override + public void decrementLockCount(long id) { + jdbcTemplate.update("UPDATE RESOURCE_LOCK SET lock_count = lock_count - 1 WHERE resource_lock_id = ?", + new Object[] { id }); + } + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public void commit() { + if (jdbcTemplate.getDataSource() instanceof CachedDataSourceWrap) { + CachedDataSourceWrap ds = (CachedDataSourceWrap) jdbcTemplate.getDataSource(); + ds.commit(); + ds.releaseConnection(); + } + } + + @Override + public void rollback() { + if (jdbcTemplate.getDataSource() instanceof CachedDataSourceWrap) { + CachedDataSourceWrap ds = (CachedDataSourceWrap) jdbcTemplate.getDataSource(); + ds.rollback(); + ds.releaseConnection(); + } + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/data/ResourceLock.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/data/ResourceLock.java new file mode 100644 index 000000000..cb434e142 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/lock/data/ResourceLock.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.lock.data; + +import java.util.Date; + +public class ResourceLock { + + public long id; + public String resourceName; + public String lockHolder; + public int lockCount; + public Date lockTime; + public Date expirationTime; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/ResourceAllocator.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/ResourceAllocator.java new file mode 100644 index 000000000..10f3e02b7 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/ResourceAllocator.java @@ -0,0 +1,583 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights + * reserved. + * Modifications Copyright (C) 2019 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ra; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.onap.ccsdk.sli.adaptors.ra.comp.AllocationData; +import org.onap.ccsdk.sli.adaptors.ra.comp.EndPointAllocator; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceData; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceEntity; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceRequest; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceResponse; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceTarget; +import org.onap.ccsdk.sli.adaptors.rm.comp.ResourceManager; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationStatus; +import org.onap.ccsdk.sli.adaptors.rm.data.ReleaseRequest; +import org.onap.ccsdk.sli.adaptors.util.speed.SpeedUtil; +import org.onap.ccsdk.sli.adaptors.util.str.StrUtil; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResourceAllocator implements SvcLogicResource { + + private static final Logger log = LoggerFactory.getLogger(ResourceAllocator.class); + + private static final String[] INPUT_PREFIX = {"ra-input.", "tmp.resource-allocator."}; + + private ResourceManager resourceManager; + private EndPointAllocator endPointAllocator; + private SpeedUtil speedUtil; + + public ResourceAllocator() { + log.info("ResourceAllocator created."); + } + + @Override + public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) + throws SvcLogicException { + return QueryStatus.SUCCESS; + } + + @Override + public QueryStatus update(String resource, String key, Map<String, String> parms, String prefix, + SvcLogicContext ctx) throws SvcLogicException { + + return QueryStatus.SUCCESS; + } + + @Override + public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + return QueryStatus.SUCCESS; + } + + @Override + public QueryStatus delete(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException { + return QueryStatus.SUCCESS; + } + + @Override + public QueryStatus save(String arg0, boolean arg1, boolean arg2, String arg3, Map<String, String> arg4, String arg5, + SvcLogicContext arg6) throws SvcLogicException { + return QueryStatus.SUCCESS; + } + + @Override + public QueryStatus isAvailable(String resource, String key, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + return allocateResources(ctx, true, prefix); + } + + @Override + public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, + String orderBy, SvcLogicContext ctx) throws SvcLogicException { + + String resourceEntityId = getParam(ctx, + new String[] {"service-instance-id", "resource-entity-id", "reservation-entity-id"}, false, null); + String resourceEntityType = + getParam(ctx, new String[] {"reservation-entity-type", "resource-entity-type"}, false, null); + String resourceEntityVersion = + getParam(ctx, new String[] {"reservation-entity-version", "resource-entity-version"}, false, "1"); + + String resourceTargetId = + getParam(ctx, new String[] {"reservation-target-id", "resource-target-id"}, false, null); + String resourceTargetType = + getParam(ctx, new String[] {"reservation-target-type", "resource-target-type"}, false, null); + String resourceName = getParam(ctx, "resource-name", false, null); + String resourceEntityTypeFilter = getParam(ctx, "resource-entity-type-filter", false, null); + String resourceEntityIdFilter = getParam(ctx, "resource-entity-id-filter", false, null); + String resourceShareGroupFilter = getParam(ctx, "resource-share-group-filter", false, null); + String resourceTargetTypeFilter = getParam(ctx, "resource-target-type-filter", false, null); + String resourceTargetIdFilter = getParam(ctx, "resource-target-id-filter", false, null); + + if (resourceEntityId != null && resourceEntityType != null) { + List<ResourceData> rdlist = endPointAllocator.getResourcesForEntity(resourceEntityType, resourceEntityId, + resourceEntityVersion); + setResourceDataInContext(ctx, prefix, rdlist); + } else if (resourceTargetId != null && resourceTargetType != null && resourceName != null) { + ResourceData rd = endPointAllocator.getResource(resourceTargetType, resourceTargetId, resourceName, + resourceEntityTypeFilter, resourceEntityIdFilter, resourceShareGroupFilter); + if (rd != null) { + setResourceDataInContext(ctx, prefix, Collections.singletonList(rd)); + } + } else if ((resourceTargetTypeFilter != null || resourceTargetIdFilter != null) && resourceName != null) { + List<ResourceData> rdlist = endPointAllocator.getResourcesForTarget(resourceTargetTypeFilter, + resourceTargetIdFilter, resourceName); + setResourceDataInContext(ctx, prefix, rdlist); + } + + return QueryStatus.SUCCESS; + } + + public AllocationStatus query(ResourceEntity sd, ResourceTarget rt, ResourceRequest rr, + List<ResourceResponse> rsList) throws Exception { + + if (sd != null && sd.resourceEntityId != null && sd.resourceEntityType != null) { + List<ResourceData> rdlist = endPointAllocator.getResourcesForEntity(sd.resourceEntityType, + sd.resourceEntityId, sd.resourceEntityVersion); + setResourceDataInResponse(rdlist, rsList); + } else if (rt != null && rt.resourceTargetId != null && rt.resourceTargetType != null && rr != null + && rr.resourceName != null) { + ResourceData rd = endPointAllocator.getResource(rt.resourceTargetType, rt.resourceTargetId, rr.resourceName, + rr.resourceEntityTypeFilter, rr.resourceEntityIdFilter, rr.resourceShareGroupFilter); + setResourceDataInResponse(Collections.singletonList(rd), rsList); + } else if (rr != null && (rr.resourceTargetTypeFilter != null || rr.resourceTargetIdFilter != null) + && rr.resourceName != null) { + List<ResourceData> rdlist = endPointAllocator.getResourcesForTarget(rr.resourceTargetTypeFilter, + rr.resourceTargetIdFilter, rr.resourceName); + setResourceDataInResponse(rdlist, rsList); + } + + return AllocationStatus.Success; + } + + private void setResourceDataInContext(SvcLogicContext ctx, String prefix, List<ResourceData> rdlist) { + if (rdlist == null || rdlist.isEmpty()) { + return; + } + + prefix = prefix == null ? "" : prefix + '.'; + + setAttr(ctx, prefix + "resource-list_length", String.valueOf(rdlist.size())); + + for (int i = 0; i < rdlist.size(); i++) { + ResourceData rd = rdlist.get(i); + + String pp = prefix + "resource-list[" + i + "]."; + + setAttr(ctx, pp + "resource-name", rd.resourceName); + setAttr(ctx, pp + "endpoint-position", rd.endPointPosition); + setAttr(ctx, pp + "resource-target-type", rd.resourceTargetType); + setAttr(ctx, pp + "resource-target-id", rd.resourceTargetId); + setAttr(ctx, pp + "resource-target-value", rd.resourceTargetValue); + setAttr(ctx, pp + "status", rd.status); + + Map<String, String> dataProp = dataToProperties(rd.data); + for (String kk : dataProp.keySet()) { + String value = String.valueOf(dataProp.get(kk)); + setAttr(ctx, pp + kk, value); + } + + if (rd.allocationDataList != null && !rd.allocationDataList.isEmpty()) { + + setAttr(ctx, pp + "allocation-data-list_length", String.valueOf(rd.allocationDataList.size())); + + for (int j = 0; j < rd.allocationDataList.size(); j++) { + AllocationData ad = rd.allocationDataList.get(j); + + String ppp = pp + "allocation-data-list[" + j + "]."; + + setAttr(ctx, ppp + "resource-entity-type", ad.resourceEntityType); + setAttr(ctx, ppp + "resource-entity-id", ad.resourceEntityId); + setAttr(ctx, ppp + "resource-entity-version", ad.resourceEntityVersion); + + if (ad.data != null && !ad.data.isEmpty()) { + for (String kk : ad.data.keySet()) { + String value = String.valueOf(ad.data.get(kk)); + setAttr(ctx, ppp + kk, value); + } + } + } + } + } + } + + @Override + public QueryStatus reserve(String resource, String select, String key, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + return allocateResources(ctx, false, prefix); + } + + public AllocationStatus reserve(ResourceEntity sd, ResourceTarget rt, ResourceRequest rr, + List<ResourceResponse> rsList) throws Exception { + return allocateResources(sd, rt, rr, rsList); + } + + @Override + public QueryStatus release(String resource, String key, SvcLogicContext ctx) throws SvcLogicException { + String resourceEntityId = getParam(ctx, + new String[] {"service-instance-id", "resource-entity-id", "reservation-entity-id"}, true, null); + String resourceEntityType = + getParam(ctx, new String[] {"reservation-entity-type", "resource-entity-type"}, true, null); + String resourceEntityVersion = + getParam(ctx, new String[] {"reservation-entity-version", "resource-entity-version"}, false, null); + String resourceTargetId = + getParam(ctx, new String[] {"reservation-target-id", "resource-target-id"}, false, null); + String resourceTargetType = + getParam(ctx, new String[] {"reservation-target-type", "resource-target-type"}, false, null); + String resourceName = getParam(ctx, new String[] {"resource-name"}, false, null); + String limitReleaseAmountStr = getParam(ctx, new String[] {"limit-release-amount"}, false, "-1"); + int limitReleaseAmount = Integer.parseInt(limitReleaseAmountStr); + String rangeReleaseNumbers = getParam(ctx, new String[] {"range-release-numbers"}, false, null); + + + String endPointPosition = getParam(ctx, "endpoint-position", false, null); + + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = resourceEntityId; + sd.resourceEntityType = resourceEntityType; + sd.resourceEntityVersion = resourceEntityVersion; + + ResourceRequest rr = new ResourceRequest(); + rr.endPointPosition = endPointPosition; + rr.resourceName = resourceName; + rr.rangeReleaseNumbers = rangeReleaseNumbers; + rr.limitReleaseAmount = limitReleaseAmount; + + ResourceTarget rt = new ResourceTarget(); + rt.resourceTargetType = resourceTargetType; + rt.resourceTargetId = resourceTargetId; + + try { + this.release(sd, rr, rt); + } catch (Exception e) { + throw new SvcLogicException(e.getMessage()); + } + return QueryStatus.SUCCESS; + } + + public AllocationStatus release(ResourceEntity sd) throws Exception { + return release(sd, null, null); + } + + public AllocationStatus release(ResourceEntity sd, ResourceRequest rr) throws Exception { + return release(sd, rr, null); + } + + public AllocationStatus release(ResourceEntity sd, ResourceRequest rr, ResourceTarget rt) { + + ReleaseRequest releaseRequest = new ReleaseRequest(); + + if (sd != null && sd.resourceEntityVersion != null) { + releaseRequest.resourceSetId = null; + + if (rr != null && rr.endPointPosition != null && !rr.endPointPosition.isEmpty()) { + releaseRequest.resourceSetId = sd.resourceEntityType + "::" + sd.resourceEntityId + "::" + + rr.endPointPosition + "::" + sd.resourceEntityVersion; + } else { + releaseRequest.resourceSetId = + sd.resourceEntityType + "::" + sd.resourceEntityId + "::" + sd.resourceEntityVersion; + } + + } else if (sd != null && (sd.resourceEntityVersion == null || sd.resourceEntityVersion.isEmpty())) { + releaseRequest.resourceUnionId = null; + + if (rr != null && rr.endPointPosition != null && !rr.endPointPosition.isEmpty()) { + releaseRequest.resourceUnionId = + sd.resourceEntityType + "::" + sd.resourceEntityId + "::" + rr.endPointPosition; + } else { + releaseRequest.resourceUnionId = sd.resourceEntityType + "::" + sd.resourceEntityId; + } + } + + if (rt != null && rt.resourceTargetId != null && rt.resourceTargetType != null) { + releaseRequest.assetId = rt.resourceTargetType + "::" + rt.resourceTargetId; + } + + if (rr != null) { + releaseRequest.resourceName = rr.resourceName; + releaseRequest.releaseNumbers = + StrUtil.listInt(rr.rangeReleaseNumbers, "Invalid value for range-release-numbers"); + releaseRequest.releaseAmount = rr.limitReleaseAmount; + } + + log.info("Releasing resources:"); + StrUtil.info(log, releaseRequest); + + resourceManager.releaseResources(releaseRequest); + + return AllocationStatus.Success; + } + + private QueryStatus allocateResources(SvcLogicContext ctx, boolean checkOnly, String prefix) + throws SvcLogicException { + String serviceModel = getParam(ctx, "service-model", true, null); + String requestType = getParam(ctx, "request-type", false, "New"); + + ResourceEntity sd = getResourceEntityData(ctx); + ResourceTarget rt = getResourceTargetData(ctx); + ResourceRequest rr = getResourceRequest(ctx); + + log.info("Starting reserve: " + requestType + ", service-model: " + serviceModel); + StrUtil.info(log, sd); + StrUtil.info(log, rt); + StrUtil.info(log, rr); + + boolean change = "change".equalsIgnoreCase(requestType); + + List<ResourceData> rlist = endPointAllocator.allocateResources(serviceModel, sd, rt, rr, checkOnly, change); + + if (rlist != null && !rlist.isEmpty()) { + setResourceDataInContext(ctx, prefix, rlist); + + for (ResourceData rd : rlist) { + if (!"Success".equals(rd.status)) { + log.info("Capacity not found for: " + sd.resourceEntityType + "::" + sd.resourceEntityId); + return QueryStatus.NOT_FOUND; + } + } + } + return QueryStatus.SUCCESS; + } + + private AllocationStatus allocateResources(ResourceEntity sd, ResourceTarget rt, ResourceRequest rr, + List<ResourceResponse> rsList) throws Exception { + + String serviceModel = rr.serviceModel; + String requestType = rr.requestType == null ? "New" : rr.requestType; + + log.info("Starting reserve: " + requestType + ", service-model: " + serviceModel); + StrUtil.info(log, sd); + StrUtil.info(log, rt); + StrUtil.info(log, rr); + + boolean change = "change".equalsIgnoreCase(requestType); + + List<ResourceData> rlist = endPointAllocator.allocateResources(serviceModel, sd, rt, rr, rr.checkOnly, change); + + if (rlist != null && !rlist.isEmpty()) { + setResourceDataInResponse(rlist, rsList); + + for (ResourceData rd : rlist) { + if (!"Success".equals(rd.status)) { + log.info("Capacity not found for: " + sd.resourceEntityType + "::" + sd.resourceEntityId); + return AllocationStatus.ResourceNotFound; + } + } + } + + return AllocationStatus.Success; + } + + private void setResourceDataInResponse(List<ResourceData> rlist, List<ResourceResponse> rsList) { + for (ResourceData rd : emptyIfNull(rlist)) { + ResourceResponse res = new ResourceResponse(); + res.resourceName = rd.resourceName; + res.endPointPosition = rd.endPointPosition; + res.resourceTargetId = rd.resourceTargetId; + res.resourceTargetType = rd.resourceTargetType; + res.status = rd.status; + if (rd.data != null && !rd.data.isEmpty()) { + for (String kk : rd.data.keySet()) { + if ("allocated".equalsIgnoreCase(kk)) { + res.resourceAllocated = String.valueOf(rd.data.get(kk)); + } + + if ("used".equalsIgnoreCase(kk)) { + res.resourceUsed = String.valueOf(rd.data.get(kk)); + } + + if ("available".equalsIgnoreCase(kk)) { + res.resourceAvailable = String.valueOf(rd.data.get(kk)); + } + + if ("limit".equalsIgnoreCase(kk)) { + res.resourceLimit = String.valueOf(rd.data.get(kk)); + } + + } + } + rsList.add(res); + } + + } + + public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) { + return iterable == null ? Collections.<T>emptyList() : iterable; + } + + private void setAttr(SvcLogicContext ctx, String name, String value) { + ctx.setAttribute(name, value); + log.info("Added context attr: " + name + ": " + value); + } + + private ResourceEntity getResourceEntityData(SvcLogicContext ctx) throws SvcLogicException { + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = getParam(ctx, + new String[] {"service-instance-id", "resource-entity-id", "reservation-entity-id"}, true, null); + sd.resourceEntityType = + getParam(ctx, new String[] {"reservation-entity-type", "resource-entity-type"}, true, null); + sd.resourceEntityVersion = + getParam(ctx, new String[] {"reservation-entity-version", "resource-entity-version"}, false, "1"); + sd.data = getDataParam(ctx, "reservation-entity-data", "resource-entity-data", "service-data"); + return sd; + } + + private ResourceTarget getResourceTargetData(SvcLogicContext ctx) throws SvcLogicException { + ResourceTarget sd = new ResourceTarget(); + sd.resourceTargetId = getParam(ctx, new String[] {"reservation-target-id", "resource-target-id"}, true, null); + sd.resourceTargetType = + getParam(ctx, new String[] {"reservation-target-type", "resource-target-type"}, true, null); + sd.data = getDataParam(ctx, "reservation-target-data", "resource-target-data", "equipment-data"); + return sd; + } + + private ResourceRequest getResourceRequest(SvcLogicContext ctx) throws SvcLogicException { + ResourceRequest rr = new ResourceRequest(); + rr.resourceName = getParam(ctx, "resource-name", false, null); + rr.resourceShareGroup = getParam(ctx, "resource-share-group", false, null); + rr.rangeRequestedNumbers = getParam(ctx, "range-requested-numbers", false, null); + rr.rangeExcludeNumbers = getParam(ctx, "range-exclude-numbers", false, null); + String rangeReverseOrderStr = getParam(ctx, "range-reverse-order", false, "false"); + rr.rangeReverseOrder = Boolean.parseBoolean(rangeReverseOrderStr); + String rangeMinOverrideStr = getParam(ctx, "range-min-override", false, "-1"); + rr.rangeMinOverride = Integer.parseInt(rangeMinOverrideStr); + String rangeMaxOverrideStr = getParam(ctx, "range-max-override", false, "-1"); + rr.rangeMaxOverride = Integer.parseInt(rangeMaxOverrideStr); + String rangeForceNewNumbersStr = getParam(ctx, "range-force-new-numbers", false, "false"); + rr.rangeForceNewNumbers = Boolean.parseBoolean(rangeForceNewNumbersStr); + String rangeNextInSequenceStr = getParam(ctx, "range-next-in-sequence", false, "false"); + rr.rangeNextInSequence = Boolean.parseBoolean(rangeNextInSequenceStr); + String replaceStr = getParam(ctx, "replace", false, "true"); + rr.replace = Boolean.parseBoolean(replaceStr); + rr.applicationId = getParam(ctx, "application-id", false, "SDNC"); + rr.endPointPosition = getParam(ctx, "endpoint-position", false, null); + return rr; + } + + private String getParam(SvcLogicContext ctx, String name, boolean required, String def) throws SvcLogicException { + String v = null; + for (String p : INPUT_PREFIX) { + v = ctx.getAttribute(p + name); + if (v != null && v.trim().length() > 0) { + log.info("Param: " + name + ": " + v.trim()); + return v.trim(); + } + } + if (required) { + throw new SvcLogicException("The following variable is required in DG context: " + name); + } + + log.info("Param: " + name + " not supplied. Using default: " + def); + return def; + } + + private String getParam(SvcLogicContext ctx, String[] names, boolean required, String def) + throws SvcLogicException { + String v = null; + for (String name : names) { + v = getParam(ctx, name, false, def); + if (v != null) { + return v; + } + } + if (required) { + throw new SvcLogicException( + "One of the following variable is required in DG context: " + Arrays.deepToString(names)); + } + + log.info("Param: " + Arrays.deepToString(names) + " not supplied. Using default: " + def); + return def; + } + + private Map<String, String> getDataParam(SvcLogicContext ctx, String... names) { + Map<String, String> data = new HashMap<>(); + Set<String> ctxNames = ctx.getAttributeKeySet(); + for (String n : ctxNames) { + for (String p : INPUT_PREFIX) { + for (String name : names) { + String pp = p + name + '.'; + if (n.startsWith(pp)) { + String nn = n.substring(pp.length()); + String vv = ctx.getAttribute(n); + data.put(nn, vv); + + log.info("Data param: " + nn + ": " + vv); + + if (ctxNames.contains(n + "-unit")) { + try { + long v = Long.parseLong(vv); + String unit = ctx.getAttribute(n + "-unit"); + long kbps = speedUtil.convertToKbps(v, unit); + long mbps = speedUtil.convertToMbps(v, unit); + data.put(nn + "-kbps", String.valueOf(kbps)); + data.put(nn + "-mbps", String.valueOf(mbps)); + + log.info("Data param: " + nn + "-kbps: " + kbps); + log.info("Data param: " + nn + "-mbps: " + mbps); + + } catch (Exception e) { + log.warn("Invalid number for " + n + ": " + vv); + } + } + } + } + } + } + return data; + } + + @SuppressWarnings("unchecked") + public static Map<String, String> dataToProperties(Map<String, Object> data) { + if (data == null || data.isEmpty()) { + return Collections.emptyMap(); + } + + Map<String, String> prop = new HashMap<>(); + Map<String, Object> data1 = new HashMap<>(data); + + while (!data1.isEmpty()) { + for (String key : new ArrayList<>(data1.keySet())) { + Object o = data1.get(key); + data1.remove(key); + + if (o instanceof Boolean || o instanceof Number || o instanceof String) { + prop.put(key, o.toString()); + } else if (o instanceof Map) { + Map<String, Object> mm = (Map<String, Object>) o; + for (String key1 : mm.keySet()) { + data1.put(key + "." + key1, mm.get(key1)); + } + } else if (o instanceof List) { + List<Object> ll = (List<Object>) o; + prop.put(key + "_length", String.valueOf(ll.size())); + for (int i = 0; i < ll.size(); i++) { + data1.put(key + '[' + i + ']', ll.get(i)); + } + } + } + } + return prop; + } + + public void setResourceManager(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + public void setEndPointAllocator(EndPointAllocator endPointAllocator) { + this.endPointAllocator = endPointAllocator; + } + + public void setSpeedUtil(SpeedUtil speedUtil) { + this.speedUtil = speedUtil; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/ResourceLockNode.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/ResourceLockNode.java new file mode 100644 index 000000000..a7d4b0e27 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/ResourceLockNode.java @@ -0,0 +1,101 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra; + +import java.security.SecureRandom; +import java.util.Map; +import org.onap.ccsdk.sli.adaptors.lock.comp.LockHelper; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResourceLockNode implements SvcLogicJavaPlugin { + + private static final Logger log = LoggerFactory.getLogger(ResourceLockNode.class); + + private LockHelper lockHelper; + + public void setLockHelper(LockHelper lockHelper) { + this.lockHelper = lockHelper; + } + + public void lockResource(Map<String, String> paramMap, SvcLogicContext ctx) throws SvcLogicException { + String resourceName = getParam(paramMap, "resource-name", true, null); + String lockRequester = getParam(paramMap, "lock-requester", false, generateLockRequester()); + String lockTimeoutStr = getParam(paramMap, "lock-timeout", false, "600"); // Default lock timeout: 10 min + int lockTimeout = Integer.parseInt(lockTimeoutStr); + String lockWaitStr = getParam(paramMap, "lock-wait", false, "5"); // Time waiting before next retry. Default: 5 sec + int lockWait = Integer.parseInt(lockWaitStr); + String lockRetryCountStr = getParam(paramMap, "lock-retry-count", false, "10"); // Default: 10 retries + int lockRetryCount = Integer.parseInt(lockRetryCountStr); + + lockHelper.lock(resourceName, lockRequester, lockTimeout, lockWait, lockRetryCount); + } + + public void unlockResource(Map<String, String> paramMap, SvcLogicContext ctx) throws SvcLogicException { + String resourceName = getParam(paramMap, "resource-name", true, null); + + lockHelper.unlock(resourceName, false); + } + + public void lockResource(String resourceName, String lockRequester, int lockTimeout /* sec */) { + lockResource(resourceName, lockRequester, lockTimeout, 5, 10); + } + + public void lockResource(String resourceName, String lockRequester, int lockTimeout /* sec */, int lockWait /* Seconds */, int retryCount) { + if (lockRequester == null) { + lockRequester = generateLockRequester(); + } + if (lockTimeout <= 0) { + lockTimeout = 600; + } + + lockHelper.lock(resourceName, lockRequester, lockTimeout, lockWait, retryCount); + } + + public void unlockResource(String resourceName) { + lockHelper.unlock(resourceName, false); + } + + private String getParam(Map<String, String> paramMap, String name, boolean required, String def) + throws SvcLogicException { + String v = paramMap.get(name); + if (v != null && v.trim().length() > 0) { + log.info("Param: " + name + ": " + v.trim()); + return v.trim(); + } + if (required) { + throw new SvcLogicException("The following node parameter is required: " + name); + } + + log.info("Param: " + name + " not supplied. Using default: " + def); + return def; + } + + private static String generateLockRequester() { + SecureRandom rand = new SecureRandom(); + return "SynchronizedFunction-" + (int) (rand.nextDouble() * 1000000); + } +} + diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/alloc/DbAllocationRule.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/alloc/DbAllocationRule.java new file mode 100644 index 000000000..d15b1508f --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/alloc/DbAllocationRule.java @@ -0,0 +1,256 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.alloc; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.onap.ccsdk.sli.adaptors.ra.comp.AllocationRule; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceEntity; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceRequest; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceTarget; +import org.onap.ccsdk.sli.adaptors.ra.rule.dao.RangeRuleDao; +import org.onap.ccsdk.sli.adaptors.ra.rule.dao.ResourceRuleDao; +import org.onap.ccsdk.sli.adaptors.ra.rule.data.RangeRule; +import org.onap.ccsdk.sli.adaptors.ra.rule.data.ResourceRule; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationAction; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.MultiResourceAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.Range; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; +import org.onap.ccsdk.sli.adaptors.util.expr.ExpressionEvaluator; +import org.onap.ccsdk.sli.adaptors.util.str.StrUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DbAllocationRule implements AllocationRule { + + private static final Logger log = LoggerFactory.getLogger(DbAllocationRule.class); + + private ResourceRuleDao resourceRuleDao; + private RangeRuleDao rangeRuleDao; + + @Override + public AllocationRequest buildAllocationRequest(String serviceModel, ResourceEntity resourceEntity, + ResourceTarget resourceTarget, ResourceRequest resourceRequest, boolean checkOnly, boolean change) { + List<ResourceRule> resourceRuleList = resourceRuleDao.getResourceRules(serviceModel, + resourceTarget.resourceTargetType); + List<RangeRule> rangeRuleList = rangeRuleDao.getRangeRules(serviceModel, resourceTarget.resourceTargetType); + + List<AllocationRequest> arlist = new ArrayList<>(); + + for (ResourceRule rr : resourceRuleList) { + if (resourceRequest.resourceName != null && !resourceRequest.resourceName.equals(rr.resourceName)) { + continue; + } + + boolean matches = ExpressionEvaluator.evalBoolean(rr.serviceExpression, resourceEntity.data); + matches = matches && ExpressionEvaluator.evalBoolean(rr.equipmentExpression, resourceTarget.data); + + if (matches) { + AllocationRequest ar1 = buildAllocationRequest(rr, resourceEntity, resourceTarget, resourceRequest, + checkOnly, change); + arlist.add(ar1); + } + } + + for (RangeRule rr : rangeRuleList) { + if (resourceRequest.resourceName != null && !resourceRequest.resourceName.equals(rr.rangeName)) { + continue; + } + if (resourceRequest.endPointPosition != null + && !resourceRequest.endPointPosition.equals(rr.endPointPosition)) { + continue; + } + + if (!ExpressionEvaluator.evalBoolean(rr.equipmentExpression, resourceTarget.data)) { + continue; + } + + AllocationRequest ar1 = buildAllocationRequest(rr, resourceEntity, resourceTarget, resourceRequest, + checkOnly, change); + arlist.add(ar1); + } + + if ((rangeRuleList == null || rangeRuleList.isEmpty()) + && ResourceType.Range.equals(resourceRequest.resourceType)) { + AllocationRequest ar1 = buildAllocationRequest(resourceEntity, resourceTarget, resourceRequest, checkOnly, + change); + arlist.add(ar1); + } + + if (arlist.isEmpty()) { + return null; + } + + if (arlist.size() == 1) { + return arlist.get(0); + } + + MultiResourceAllocationRequest ar = new MultiResourceAllocationRequest(); + ar.stopOnFirstFailure = false; + ar.allocationRequestList = arlist; + return ar; + } + + private AllocationRequest buildAllocationRequest(ResourceEntity resourceEntity, ResourceTarget resourceTarget, + ResourceRequest resourceRequest, boolean checkOnly, boolean change) { + + RangeAllocationRequest ar = new RangeAllocationRequest(); + ar.applicationId = resourceRequest.applicationId; + if (resourceRequest.endPointPosition != null) { + ar.resourceUnionId = resourceEntity.resourceEntityType + "::" + resourceEntity.resourceEntityId + "::" + + resourceRequest.endPointPosition; + ar.endPointPosition = resourceRequest.endPointPosition; + } else { + ar.resourceUnionId = resourceEntity.resourceEntityType + "::" + resourceEntity.resourceEntityId; + } + ar.resourceSetId = ar.resourceUnionId + "::" + resourceEntity.resourceEntityVersion; + ar.resourceName = resourceRequest.resourceName; + if (resourceRequest.resourceShareGroup != null) { + ar.resourceShareGroupList = Collections.singleton(resourceRequest.resourceShareGroup); + } + ar.assetId = resourceTarget.resourceTargetType + "::" + resourceTarget.resourceTargetId; + ar.requestedNumbers = StrUtil.listInt(resourceRequest.rangeRequestedNumbers, + "Invalid value for requested-numbers"); + if (ar.requestedNumbers != null) { + ar.requestedCount = ar.requestedNumbers.size(); + } + ar.excludeNumbers = StrUtil.listInt(resourceRequest.rangeExcludeNumbers, "Invalid value for exclude-numbers"); + ar.reverseOrder = resourceRequest.rangeReverseOrder; + ar.missingResourceAction = AllocationAction.Succeed_Allocate; + ar.expiredResourceAction = AllocationAction.Succeed_Allocate; + ar.replace = resourceRequest.replace; + ar.check = true; + ar.allocate = !checkOnly; + ar.rangeList = resourceRequest.rangeOverrideList; + if (ar.rangeList == null || ar.rangeList.isEmpty()) { + if (resourceRequest.rangeMinOverride >= 0 + && resourceRequest.rangeMaxOverride >= resourceRequest.rangeMinOverride) { + ar.rangeList = new ArrayList<>(); + Range range = new Range(); + range.min = resourceRequest.rangeMinOverride; + range.max = resourceRequest.rangeMaxOverride; + ar.rangeList.add(range); + } + } else { + if (resourceRequest.rangeMinOverride >= 0) { + ar.rangeList.get(0).min = resourceRequest.rangeMinOverride; + } + if (resourceRequest.rangeMaxOverride >= 0) { + ar.rangeList.get(ar.rangeList.size() - 1).max = resourceRequest.rangeMaxOverride; + } + } + ar.forceNewNumbers = resourceRequest.rangeForceNewNumbers; + StrUtil.info(log, ar); + return ar; + } + + private AllocationRequest buildAllocationRequest(ResourceRule resourceRule, ResourceEntity resourceEntity, + ResourceTarget resourceTarget, ResourceRequest resourceRequest, boolean checkOnly, boolean change) { + StrUtil.info(log, resourceRule); + + LimitAllocationRequest ar = new LimitAllocationRequest(); + ar.applicationId = resourceRequest.applicationId; + ar.resourceUnionId = resourceEntity.resourceEntityType + "::" + resourceEntity.resourceEntityId; + ar.resourceSetId = ar.resourceUnionId + "::" + resourceEntity.resourceEntityVersion; + ar.resourceName = resourceRule.resourceName; + if (resourceRequest.resourceShareGroup != null) { + ar.resourceShareGroupList = Collections.singleton(resourceRequest.resourceShareGroup); + } + ar.assetId = resourceTarget.resourceTargetType + "::" + resourceTarget.resourceTargetId; + ar.missingResourceAction = AllocationAction.Succeed_Allocate; + ar.expiredResourceAction = AllocationAction.Succeed_Allocate; + ar.replace = resourceRequest.replace; + ar.strict = false; + ar.checkLimit = ExpressionEvaluator.evalLong( + change ? resourceRule.hardLimitExpression : resourceRule.softLimitExpression, resourceTarget.data); + ar.checkCount = ExpressionEvaluator.evalLong(resourceRule.allocationExpression, resourceEntity.data); + ar.allocateCount = checkOnly ? 0 : ar.checkCount; + return ar; + } + + private AllocationRequest buildAllocationRequest(RangeRule rangeRule, ResourceEntity resourceEntity, + ResourceTarget resourceTarget, ResourceRequest resourceRequest, boolean checkOnly, boolean change) { + StrUtil.info(log, rangeRule); + + RangeAllocationRequest ar = new RangeAllocationRequest(); + ar.applicationId = resourceRequest.applicationId; + if (resourceRequest.endPointPosition != null) { + ar.resourceUnionId = resourceEntity.resourceEntityType + "::" + resourceEntity.resourceEntityId + "::" + + resourceRequest.endPointPosition; + ar.endPointPosition = resourceRequest.endPointPosition; + } else { + ar.resourceUnionId = resourceEntity.resourceEntityType + "::" + resourceEntity.resourceEntityId; + } + ar.resourceSetId = ar.resourceUnionId + "::" + resourceEntity.resourceEntityVersion; + ar.resourceName = rangeRule.rangeName; + if (resourceRequest.resourceShareGroup != null) { + ar.resourceShareGroupList = Collections.singleton(resourceRequest.resourceShareGroup); + } + ar.assetId = resourceTarget.resourceTargetType + "::" + resourceTarget.resourceTargetId; + ar.requestedNumbers = StrUtil.listInt(resourceRequest.rangeRequestedNumbers, + "Invalid value for requested-numbers"); + if (ar.requestedNumbers != null) { + ar.requestedCount = ar.requestedNumbers.size(); + } + ar.excludeNumbers = StrUtil.listInt(resourceRequest.rangeExcludeNumbers, "Invalid value for exclude-numbers"); + ar.reverseOrder = resourceRequest.rangeReverseOrder; + ar.missingResourceAction = AllocationAction.Succeed_Allocate; + ar.expiredResourceAction = AllocationAction.Succeed_Allocate; + ar.replace = resourceRequest.replace; + ar.check = true; + ar.allocate = !checkOnly; + ar.rangeList = rangeRule.rangeList; + if (ar.rangeList == null || ar.rangeList.isEmpty()) { + if (resourceRequest.rangeMinOverride >= 0 + && resourceRequest.rangeMaxOverride >= resourceRequest.rangeMinOverride) { + ar.rangeList = new ArrayList<>(); + Range range = new Range(); + range.min = resourceRequest.rangeMinOverride; + range.max = resourceRequest.rangeMaxOverride; + ar.rangeList.add(range); + } + } else { + if (resourceRequest.rangeMinOverride >= 0) { + ar.rangeList.get(0).min = resourceRequest.rangeMinOverride; + } + if (resourceRequest.rangeMaxOverride >= 0) { + ar.rangeList.get(ar.rangeList.size() - 1).max = resourceRequest.rangeMaxOverride; + } + + } + ar.forceNewNumbers = resourceRequest.rangeForceNewNumbers; + ar.nextInSequence = resourceRequest.rangeNextInSequence; + return ar; + } + + public void setResourceRuleDao(ResourceRuleDao resourceRuleDao) { + this.resourceRuleDao = resourceRuleDao; + } + + public void setRangeRuleDao(RangeRuleDao rangeRuleDao) { + this.rangeRuleDao = rangeRuleDao; + } +}
\ No newline at end of file diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/AllocationData.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/AllocationData.java new file mode 100644 index 000000000..3e0e6b140 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/AllocationData.java @@ -0,0 +1,11 @@ +package org.onap.ccsdk.sli.adaptors.ra.comp; + +import java.util.Map; + +public class AllocationData { + + public String resourceEntityType; + public String resourceEntityId; + public String resourceEntityVersion; + public Map<String, String> data; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/AllocationRule.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/AllocationRule.java new file mode 100644 index 000000000..0e9737419 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/AllocationRule.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.comp; + +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationRequest; + +public interface AllocationRule { + + AllocationRequest buildAllocationRequest(String serviceModel, ResourceEntity resourceEntity, + ResourceTarget resourceTarget, ResourceRequest resourceRequest, boolean checkOnly, boolean change); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/EndPointAllocator.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/EndPointAllocator.java new file mode 100644 index 000000000..abfb8d44f --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/EndPointAllocator.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.comp; + +import java.util.List; + +public interface EndPointAllocator { + + List<ResourceData> allocateResources(String serviceModel, ResourceEntity resourceEntity, + ResourceTarget resourceTarget, ResourceRequest resourceRequest, boolean checkOnly, boolean change); + + List<ResourceData> getResourcesForEntity(String resourceEntityType, String resourceEntityId, + String resourceEntityVersion); + + ResourceData getResource(String resourceTargetType, String resourceTargetId, String resourceName, + String resourceEntityTypeFilter, String resourceEntityIdFilter, String resourceShareGroupFilter); + + List<ResourceData> getResourcesForTarget(String resourceTargetTypeFilter, String resourceTargetIdFilter, + String resourceName); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/EndPointAllocatorImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/EndPointAllocatorImpl.java new file mode 100644 index 000000000..36e40d589 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/EndPointAllocatorImpl.java @@ -0,0 +1,368 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * + * Modifications Copyright (C) 2019 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.ra.comp; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.onap.ccsdk.sli.adaptors.rm.comp.ResourceManager; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationStatus; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitResource; +import org.onap.ccsdk.sli.adaptors.rm.data.MultiResourceAllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.Range; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeResource; +import org.onap.ccsdk.sli.adaptors.rm.data.ReleaseRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.Resource; +import org.onap.ccsdk.sli.adaptors.util.str.StrUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EndPointAllocatorImpl implements EndPointAllocator { + + private static final Logger log = LoggerFactory.getLogger(EndPointAllocatorImpl.class); + + private ResourceManager resourceManager; + + private Map<String, List<AllocationRule>> allocationRuleMap; + + @Override + public List<ResourceData> allocateResources(String serviceModel, ResourceEntity resourceEntity, + ResourceTarget resourceTarget, ResourceRequest resourceRequest, boolean checkOnly, boolean change) { + + List<ResourceData> resourceList = new ArrayList<>(); + + if (allocationRuleMap != null) { + List<AllocationRule> allocationRuleList = allocationRuleMap.get(serviceModel); + if (allocationRuleList == null) { + allocationRuleList = allocationRuleMap.get("DEFAULT"); + } + + if (allocationRuleList != null) { + boolean allgood = true; + for (AllocationRule allocationRule : allocationRuleList) { + AllocationRequest ar = allocationRule.buildAllocationRequest(serviceModel, resourceEntity, + resourceTarget, resourceRequest, checkOnly, change); + if (ar != null) { + AllocationOutcome ao = resourceManager.allocateResources(ar); + List<ResourceData> rr = getResourceData(ao); + resourceList.addAll(rr); + + if (ao.status != AllocationStatus.Success) { + allgood = false; + } + } + } + + if (!allgood) { + String resourceSetId = resourceEntity.resourceEntityType + "::" + resourceEntity.resourceEntityId + + "::" + resourceEntity.resourceEntityVersion; + resourceManager.releaseResources(ReleaseRequest.resourceSet(resourceSetId)); + } + } + } + + return resourceList; + } + + private List<ResourceData> getResourceData(AllocationOutcome ao) { + if (ao instanceof MultiResourceAllocationOutcome) { + List<ResourceData> rr = new ArrayList<>(); + for (AllocationOutcome ao1 : ((MultiResourceAllocationOutcome) ao).allocationOutcomeList) { + rr.addAll(getResourceData(ao1)); + } + return rr; + } + + ResourceData rd = new ResourceData(); + rd.data = new HashMap<>(); + + AllocationRequest ar = ao.request; + rd.resourceName = ar.resourceName; + rd.endPointPosition = ar.endPointPosition; + int i1 = ar.assetId.indexOf("::"); + if (i1 > 0) { + rd.resourceTargetType = ar.assetId.substring(0, i1); + rd.resourceTargetId = ar.assetId.substring(i1 + 2); + } else { + rd.resourceTargetType = ""; + rd.resourceTargetId = ar.assetId; + } + rd.status = ao.status.toString(); + + if (ao instanceof LimitAllocationOutcome) { + LimitAllocationOutcome lao = (LimitAllocationOutcome) ao; + rd.data.put("allocated", String.valueOf(lao.allocatedCount)); + rd.data.put("used", String.valueOf(lao.used)); + rd.data.put("limit", String.valueOf(lao.limit)); + rd.data.put("available", String.valueOf(lao.limit - lao.used)); + } else if (ao instanceof RangeAllocationOutcome) { + RangeAllocationOutcome rao = (RangeAllocationOutcome) ao; + rd.data.put("allocated", String.valueOf(StrUtil.listInt(rao.allocated))); + rd.data.put("used", String.valueOf(StrUtil.listInt(rao.used))); + List<Range> rangeList = ((RangeAllocationRequest) rao.request).rangeList; + if (rangeList != null && !rangeList.isEmpty()) { + List<Object> ll = new ArrayList<>(); + for (Range r : rangeList) { + Map<String, Object> mm = new HashMap<>(); + mm.put("min", r.min); + mm.put("max", r.max); + ll.add(mm); + } + rd.data.put("range-list", ll); + } + } + + return Collections.singletonList(rd); + } + + @Override + public List<ResourceData> getResourcesForEntity(String resourceEntityType, String resourceEntityId, + String resourceEntityVersion) { + List<ResourceData> rdlist = new ArrayList<>(); + + String resourceUnionId = resourceEntityType + "::" + resourceEntityId; + List<Resource> rlist = resourceManager.getResourceUnion(resourceUnionId); + + for (Resource r : rlist) { + + // Find the needed allocation item: if resourceEntityVersion is specified, use that, + // otherwise, find the latest allocation item + AllocationItem ai = null; + if (resourceEntityVersion != null) { + String resourceSetId = resourceUnionId + "::" + resourceEntityVersion; + for (AllocationItem ai1 : r.allocationItems) { + if (ai1.resourceSetId.equals(resourceSetId)) { + ai = ai1; + break; + } + } + } else { + Date aitime = null; + for (AllocationItem ai1 : r.allocationItems) { + if (ai1.resourceUnionId.equals(resourceUnionId)) { + if (aitime == null || ai1.allocationTime.after(aitime)) { + ai = ai1; + aitime = ai1.allocationTime; + } + } + } + } + + if (ai != null) { + ResourceData rd = new ResourceData(); + rdlist.add(rd); + + rd.resourceName = r.resourceKey.resourceName; + int i1 = r.resourceKey.assetId.indexOf("::"); + if (i1 > 0) { + rd.resourceTargetType = r.resourceKey.assetId.substring(0, i1); + rd.resourceTargetId = r.resourceKey.assetId.substring(i1 + 2); + + int i2 = r.resourceKey.assetId.lastIndexOf("::"); + if (i2 > i1) { + rd.resourceTargetValue = r.resourceKey.assetId.substring(i2 + 2); + } + } else { + rd.resourceTargetType = ""; + rd.resourceTargetId = r.resourceKey.assetId; + } + + rd.data = new HashMap<>(); + + if (ai instanceof RangeAllocationItem) { + RangeAllocationItem rai = (RangeAllocationItem) ai; + + String ss = String.valueOf(rai.used); + ss = ss.substring(1, ss.length() - 1); + rd.data.put("allocated", ss); + + } else if (ai instanceof LimitAllocationItem) { + LimitAllocationItem lai = (LimitAllocationItem) ai; + + rd.data.put("allocated", String.valueOf(lai.used)); + } + } + } + + return rdlist; + } + + @Override + public List<ResourceData> getResourcesForTarget(String resourceTargetTypeFilter, String resourceTargetIdFilter, + String resourceName) { + List<ResourceData> rdlist = new ArrayList<>(); + + String assetIdFilter = null; + if (resourceTargetTypeFilter != null && resourceTargetIdFilter != null) { + assetIdFilter = resourceTargetTypeFilter + "::" + resourceTargetIdFilter; + } else if (resourceTargetTypeFilter != null) { + assetIdFilter = resourceTargetTypeFilter; + } else if (resourceTargetIdFilter != null) { + assetIdFilter = resourceTargetIdFilter; + } + + List<Resource> rlist = resourceManager.queryResources(resourceName, assetIdFilter); + + for (Resource r : rlist) { + if (r.allocationItems == null || r.allocationItems.isEmpty()) { + continue; + } + + log.info("ResourceName:" + r.resourceKey.resourceName + " assetId:" + r.resourceKey.assetId); + + + rdlist.add(getResourceData(r)); + } + + return rdlist; + } + + @Override + public ResourceData getResource(String resourceTargetType, String resourceTargetId, String resourceName, + String resourceEntityTypeFilter, String resourceEntityIdFilter, String resourceShareGroupFilter) { + String assetId = resourceTargetType + "::" + resourceTargetId; + + String resourceUnionFilter = null; + if (resourceEntityTypeFilter != null && resourceEntityIdFilter != null) { + resourceUnionFilter = resourceEntityTypeFilter + "::" + resourceEntityIdFilter; + } else if (resourceEntityTypeFilter != null) { + resourceUnionFilter = resourceEntityTypeFilter; + } else if (resourceEntityIdFilter != null) { + resourceUnionFilter = resourceEntityIdFilter; + } + + Resource r = null; + if (resourceUnionFilter != null || resourceShareGroupFilter != null) { + r = resourceManager.queryResource(resourceName, assetId, resourceUnionFilter, resourceShareGroupFilter); + } else { + r = resourceManager.getResource(resourceName, assetId); + } + + if (r != null && r.allocationItems != null && !r.allocationItems.isEmpty()) { + log.info("ResourceName:" + r.resourceKey.resourceName + " assetId:" + r.resourceKey.assetId); + return getResourceData(r); + } + + return null; + } + + private ResourceData getResourceData(Resource r) { + ResourceData rd = new ResourceData(); + + rd.resourceName = r.resourceKey.resourceName; + int i1 = r.resourceKey.assetId.indexOf("::"); + if (i1 > 0) { + rd.resourceTargetType = r.resourceKey.assetId.substring(0, i1); + rd.resourceTargetId = r.resourceKey.assetId.substring(i1 + 2); + + int i2 = r.resourceKey.assetId.lastIndexOf("::"); + if (i2 > i1) { + rd.resourceTargetValue = r.resourceKey.assetId.substring(i2 + 2); + } + } else { + rd.resourceTargetType = ""; + rd.resourceTargetId = r.resourceKey.assetId; + } + + rd.data = new HashMap<>(); + + if (r instanceof RangeResource) { + RangeResource rr = (RangeResource) r; + + log.info("rr.used: " + rr.used); + String ss = String.valueOf(rr.used); + ss = ss.substring(1, ss.length() - 1); + rd.data.put("allocated", ss); + + } else if (r instanceof LimitResource) { + LimitResource lr = (LimitResource) r; + + log.info("lr.used: " + lr.used); + rd.data.put("allocated", String.valueOf(lr.used)); + } + + rd.allocationDataList = new ArrayList<>(); + + if (r.allocationItems != null) { + for (AllocationItem ai : r.allocationItems) { + AllocationData ad = new AllocationData(); + rd.allocationDataList.add(ad); + + i1 = ai.resourceUnionId.indexOf("::"); + if (i1 > 0) { + ad.resourceEntityType = ai.resourceUnionId.substring(0, i1); + ad.resourceEntityId = ai.resourceUnionId.substring(i1 + 2); + } else { + ad.resourceEntityType = ""; + ad.resourceEntityId = ai.resourceUnionId; + } + + i1 = ai.resourceSetId.lastIndexOf("::"); + if (i1 > 0) { + ad.resourceEntityVersion = ai.resourceSetId.substring(i1 + 2); + } else { + ad.resourceEntityVersion = ""; + } + + ad.data = new HashMap<>(); + + if (ai instanceof RangeAllocationItem) { + RangeAllocationItem rai = (RangeAllocationItem) ai; + + log.info("rr.used: " + rai.used); + String ss = String.valueOf(rai.used); + ss = ss.substring(1, ss.length() - 1); + ad.data.put("allocated", ss); + + } else if (ai instanceof LimitAllocationItem) { + LimitAllocationItem lai = (LimitAllocationItem) ai; + + log.info("lr.used: " + lai.used); + ad.data.put("allocated", String.valueOf(lai.used)); + } + } + } + + return rd; + } + + public void setResourceManager(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + public void setAllocationRuleMap(Map<String, List<AllocationRule>> allocationRuleMap) { + this.allocationRuleMap = allocationRuleMap; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceData.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceData.java new file mode 100644 index 000000000..d83d4cdb4 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceData.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.comp; + +import java.util.List; +import java.util.Map; + +public class ResourceData { + + public String resourceName; + public String resourceTargetId; + public String resourceTargetValue; + public String resourceTargetType; + public String endPointPosition; + public String status; + public Map<String, Object> data; + public List<AllocationData> allocationDataList; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceEntity.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceEntity.java new file mode 100644 index 000000000..12fb695b7 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceEntity.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.comp; + +import java.util.Map; + +public class ResourceEntity { + + public String resourceEntityId; + public String resourceEntityVersion; + public String resourceEntityType; + public Map<String, String> data; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceRequest.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceRequest.java new file mode 100644 index 000000000..2ebad4c89 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceRequest.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.comp; + +import java.util.List; +import org.onap.ccsdk.sli.adaptors.rm.data.Range; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; + +public class ResourceRequest { + + public String resourceName; + public String resourceShareGroup; + public String rangeRequestedNumbers; + public String rangeExcludeNumbers; + public boolean rangeReverseOrder; + public int rangeMinOverride; + public int rangeMaxOverride; + public boolean rangeForceNewNumbers; + public boolean rangeNextInSequence; + public boolean replace; + public String requestType; + public String serviceModel; + public boolean checkOnly; + public String applicationId; + public String endPointPosition; + public ResourceType resourceType; + public List<Range> rangeOverrideList; + public String resourceEntityTypeFilter; + public String resourceEntityIdFilter; + public String resourceShareGroupFilter; + public String resourceTargetTypeFilter; + public String resourceTargetIdFilter; + public String rangeReleaseNumbers; + public int limitReleaseAmount; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceResponse.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceResponse.java new file mode 100644 index 000000000..989333c3e --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceResponse.java @@ -0,0 +1,13 @@ +package org.onap.ccsdk.sli.adaptors.ra.comp; + +public class ResourceResponse { + public String resourceName; + public String endPointPosition; + public String resourceTargetType; + public String resourceTargetId; + public String resourceLimit; + public String resourceAvailable; + public String resourceUsed; + public String resourceAllocated; + public String status; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceTarget.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceTarget.java new file mode 100644 index 000000000..95cec330a --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/comp/ResourceTarget.java @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.comp; + +import java.util.Map; + +public class ResourceTarget { + + public String resourceTargetId; + public String resourceTargetType; + public Map<String, String> data; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/RangeRuleDao.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/RangeRuleDao.java new file mode 100644 index 000000000..a7fcb61f2 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/RangeRuleDao.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.rule.dao; + +import java.util.List; +import org.onap.ccsdk.sli.adaptors.ra.rule.data.RangeRule; + +public interface RangeRuleDao { + + List<RangeRule> getRangeRules(String serviceModel, String equipLevel); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/RangeRuleDaoImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/RangeRuleDaoImpl.java new file mode 100644 index 000000000..b021620ba --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/RangeRuleDaoImpl.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.rule.dao; + +import java.util.ArrayList; +import java.util.List; +import org.onap.ccsdk.sli.adaptors.ra.rule.data.RangeRule; +import org.onap.ccsdk.sli.adaptors.rm.data.Range; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +public class RangeRuleDaoImpl implements RangeRuleDao { + + private static final Logger log = LoggerFactory.getLogger(RangeRuleDaoImpl.class); + + private static final String GET_SQL = "SELECT * FROM RANGE_RULE WHERE service_model = ? AND equipment_level = ?"; + + private JdbcTemplate jdbcTemplate; + + @Override + public List<RangeRule> getRangeRules(String serviceModel, String equipLevel) { + return jdbcTemplate.query(GET_SQL, new Object[] { serviceModel, equipLevel }, + (RowMapper<RangeRule>) (rs, rowNum) -> { + RangeRule rl = new RangeRule(); + rl.id = rs.getLong("range_rule_id"); + rl.rangeName = rs.getString("range_name"); + rl.serviceModel = rs.getString("service_model"); + rl.endPointPosition = rs.getString("end_point_position"); + rl.equipmentLevel = rs.getString("equipment_level"); + rl.equipmentExpression = rs.getString("equipment_expression"); + + String rangesStr = rs.getString("ranges"); + String[] ranges = rangesStr.split(","); + rl.rangeList = new ArrayList<>(); + for (String rangeStr : ranges) { + Range range = new Range(); + String[] nn = rangeStr.split("-"); + if (nn.length >= 1) { + try { + range.min = range.max = Integer.parseInt(nn[0]); + } catch (NumberFormatException e) { + log.warn("Invalid value found in DB for range: " + rangeStr, e); + } + } + if (nn.length >= 2) { + try { + range.max = Integer.parseInt(nn[1]); + } catch (NumberFormatException e) { + log.warn("Invalid value found in DB for range: " + rangeStr, e); + } + } + if (nn.length > 2) { + log.warn("Invalid value found in DB for range: {}", rangeStr); + } + rl.rangeList.add(range); + } + + return rl; + }); + + } + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } +}
\ No newline at end of file diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/ResourceRuleDao.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/ResourceRuleDao.java new file mode 100644 index 000000000..54fdcbc20 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/ResourceRuleDao.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.rule.dao; + +import java.util.List; +import org.onap.ccsdk.sli.adaptors.ra.rule.data.ResourceRule; + +public interface ResourceRuleDao { + + List<ResourceRule> getResourceRules(String serviceModel, String equipLevel); + + ResourceRule getResourceRule(String serviceModel, String endPointPosition, String equipLevel, String resourceName); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/ResourceRuleDaoImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/ResourceRuleDaoImpl.java new file mode 100644 index 000000000..451dc57cd --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/dao/ResourceRuleDaoImpl.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.rule.dao; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import org.onap.ccsdk.sli.adaptors.ra.rule.data.ResourceRule; +import org.onap.ccsdk.sli.adaptors.ra.rule.data.ResourceThreshold; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +public class ResourceRuleDaoImpl implements ResourceRuleDao { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(ResourceRuleDaoImpl.class); + + private static final String GET1_SQL = + "SELECT * FROM RESOURCE_RULE WHERE service_model = ? AND equipment_level = ?"; + private static final String GET2_SQL = + "SELECT * FROM RESOURCE_RULE WHERE service_model = ? AND end_point_position = ? AND equipment_level = ? AND resource_name = ?"; + private static final String THRESHOLD_SQL = "SELECT * FROM RESOURCE_THRESHOLD WHERE resource_rule_id = ?"; + + private JdbcTemplate jdbcTemplate; + ResourceRuleRowMapper resourceRuleRowMapper = new ResourceRuleRowMapper(); + ResourceThresholdRowMapper resourceThresholdRowMapper = new ResourceThresholdRowMapper(); + + @Override + public List<ResourceRule> getResourceRules(String serviceModel, String equipLevel) { + List<ResourceRule> resourceRuleList = + jdbcTemplate.query(GET1_SQL, new Object[] {serviceModel, equipLevel}, resourceRuleRowMapper); + + for (ResourceRule rr : resourceRuleList) { + rr.thresholdList = jdbcTemplate.query(THRESHOLD_SQL, new Object[] {rr.id}, resourceThresholdRowMapper); + } + + return resourceRuleList; + } + + @Override + public ResourceRule getResourceRule(String serviceModel, String endPointPosition, String equipLevel, + String resourceName) { + List<ResourceRule> resourceRuleList = jdbcTemplate.query(GET2_SQL, + new Object[] {serviceModel, endPointPosition, equipLevel, resourceName}, resourceRuleRowMapper); + + if (resourceRuleList == null || resourceRuleList.isEmpty()) { + return null; + } + + ResourceRule rr = resourceRuleList.get(0); + rr.thresholdList = jdbcTemplate.query(THRESHOLD_SQL, new Object[] {rr.id}, resourceThresholdRowMapper); + + return rr; + } + + private static class ResourceRuleRowMapper implements RowMapper<ResourceRule> { + + @Override + public ResourceRule mapRow(ResultSet rs, int rowNum) throws SQLException { + ResourceRule rl = new ResourceRule(); + rl.id = rs.getLong("resource_rule_id"); + rl.resourceName = rs.getString("resource_name"); + rl.serviceModel = rs.getString("service_model"); + rl.endPointPosition = rs.getString("end_point_position"); + rl.serviceExpression = rs.getString("service_expression"); + rl.equipmentLevel = rs.getString("equipment_level"); + rl.equipmentExpression = rs.getString("equipment_expression"); + rl.allocationExpression = rs.getString("allocation_expression"); + rl.softLimitExpression = rs.getString("soft_limit_expression"); + rl.hardLimitExpression = rs.getString("hard_limit_expression"); + return rl; + } + } + + private static class ResourceThresholdRowMapper implements RowMapper<ResourceThreshold> { + + @Override + public ResourceThreshold mapRow(ResultSet rs, int rowNum) throws SQLException { + ResourceThreshold th = new ResourceThreshold(); + th.expression = rs.getString("threshold_expression"); + th.message = rs.getString("threshold_message"); + return th; + } + } + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/RangeRule.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/RangeRule.java new file mode 100644 index 000000000..c1ccd8196 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/RangeRule.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.rule.data; + +import java.util.List; +import org.onap.ccsdk.sli.adaptors.rm.data.Range; + +public class RangeRule { + + public long id; + public String rangeName; + public String serviceModel; + public String endPointPosition; + public String equipmentLevel; + public String equipmentExpression; + public List<Range> rangeList; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/ResourceRule.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/ResourceRule.java new file mode 100644 index 000000000..17e0196b2 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/ResourceRule.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.rule.data; + +import java.util.List; + +public class ResourceRule { + + public long id; + public String resourceName; + public String serviceModel; + public String endPointPosition; + public String serviceExpression; + public String equipmentLevel; + public String equipmentExpression; + public String allocationExpression; + public String softLimitExpression; + public String hardLimitExpression; + public List<ResourceThreshold> thresholdList; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/ResourceThreshold.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/ResourceThreshold.java new file mode 100644 index 000000000..3f07d9f6b --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/ResourceThreshold.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.rule.data; + +public class ResourceThreshold { + + public String expression; + public String message; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/ThresholdStatus.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/ThresholdStatus.java new file mode 100644 index 000000000..5bc8d3450 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/ra/rule/data/ThresholdStatus.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.ra.rule.data; + +public class ThresholdStatus { + + public ResourceRule resourceRule; + public ResourceThreshold resourceThreshold; + public long limitValue; + public long thresholdValue; + public long used; + public long lastAdded; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/AllocationFunction.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/AllocationFunction.java new file mode 100644 index 000000000..485010656 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/AllocationFunction.java @@ -0,0 +1,433 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.rm.comp; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import org.onap.ccsdk.sli.adaptors.lock.comp.LockHelper; +import org.onap.ccsdk.sli.adaptors.lock.comp.ResourceLockedException; +import org.onap.ccsdk.sli.adaptors.lock.comp.SynchronizedFunction; +import org.onap.ccsdk.sli.adaptors.rm.dao.ResourceDao; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationStatus; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelAllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelResource; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitResource; +import org.onap.ccsdk.sli.adaptors.rm.data.MultiAssetAllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.MultiAssetAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.MultiResourceAllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.MultiResourceAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.Range; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeResource; +import org.onap.ccsdk.sli.adaptors.rm.data.Resource; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceKey; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; +import org.onap.ccsdk.sli.adaptors.rm.util.LabelUtil; +import org.onap.ccsdk.sli.adaptors.rm.util.LimitUtil; +import org.onap.ccsdk.sli.adaptors.rm.util.RangeUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class AllocationFunction extends SynchronizedFunction { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(AllocationFunction.class); + + private ResourceDao resourceDao; + + private AllocationRequest request; + private AllocationOutcome outcome; + + private List<Resource> updateList = new ArrayList<>(); + + public AllocationFunction(LockHelper lockHelper, ResourceDao resourceDao, AllocationRequest request, + int lockTimeout) { + super(lockHelper, getLockNames(request), lockTimeout); + this.resourceDao = resourceDao; + this.request = request; + } + + private static Collection<String> getLockNames(AllocationRequest request) { + Set<String> lockResourceNames = new HashSet<>(); + addLockNames(lockResourceNames, request); + return lockResourceNames; + } + + private static void addLockNames(Set<String> lockResourceNames, AllocationRequest request) { + if (request instanceof MultiAssetAllocationRequest) { + MultiAssetAllocationRequest req = (MultiAssetAllocationRequest) request; + if (req.assetIdList != null) { + lockResourceNames.addAll(req.assetIdList); + } + } else if (request instanceof MultiResourceAllocationRequest) { + MultiResourceAllocationRequest req = (MultiResourceAllocationRequest) request; + if (req.allocationRequestList != null) { + for (AllocationRequest request1 : req.allocationRequestList) { + addLockNames(lockResourceNames, request1); + } + } + } else if (request.assetId != null) { + lockResourceNames.add(request.assetId); + } + } + + @Override + public void _exec() throws ResourceLockedException { + outcome = allocate(request); + + if (outcome!=null && outcome.status == AllocationStatus.Success) { + for (Resource r : updateList) { + resourceDao.saveResource(r); + } + } + } + + private AllocationOutcome allocate(AllocationRequest allocationRequest) throws ResourceLockedException { + if (allocationRequest instanceof MultiAssetAllocationRequest) { + return allocateMultiAsset((MultiAssetAllocationRequest) allocationRequest); + } + if (allocationRequest instanceof MultiResourceAllocationRequest) { + return allocateMultiResource((MultiResourceAllocationRequest) allocationRequest); + } + if (allocationRequest instanceof LimitAllocationRequest) { + return allocateLimit((LimitAllocationRequest) allocationRequest); + } + if (allocationRequest instanceof LabelAllocationRequest) { + return allocateLabel((LabelAllocationRequest) allocationRequest); + } + if (allocationRequest instanceof RangeAllocationRequest) { + return allocateRange((RangeAllocationRequest) allocationRequest); + } + return null; + } + + private MultiAssetAllocationOutcome allocateMultiAsset(MultiAssetAllocationRequest req) { + + return null; + } + + private MultiResourceAllocationOutcome allocateMultiResource(MultiResourceAllocationRequest req) { + MultiResourceAllocationOutcome out = new MultiResourceAllocationOutcome(); + out.request = req; + out.allocationOutcomeList = new ArrayList<>(); + out.status = AllocationStatus.Success; + + if (req.allocationRequestList != null) { + for (AllocationRequest req1 : req.allocationRequestList) { + AllocationOutcome out1 = allocate(req1); + out.allocationOutcomeList.add(out1); + if (out1.status != AllocationStatus.Success) { + out.status = AllocationStatus.Failure; + } + } + } + + return out; + } + + private LimitAllocationOutcome allocateLimit(LimitAllocationRequest req) { + LimitAllocationOutcome out = new LimitAllocationOutcome(); + out.request = req; + + Resource r = resourceDao.getResource(req.assetId, req.resourceName); + if (r == null) { + r = new LimitResource(); + r.resourceKey = new ResourceKey(); + r.resourceKey.assetId = req.assetId; + r.resourceKey.resourceName = req.resourceName; + r.resourceType = ResourceType.Limit; + } else { + if (r.resourceType != ResourceType.Limit) { + out.status = AllocationStatus.ResourceNotFound; + return out; + } + LimitUtil.recalculate((LimitResource) r); + } + + LimitResource l = (LimitResource) r; + if (LimitUtil.checkLimit(l, req)) { + out.status = AllocationStatus.Success; + if (req.allocateCount > 0) { + out.allocatedCount = LimitUtil.allocateLimit(l, req); + updateList.add(l); + } + } else { + out.status = AllocationStatus.Failure; + } + + out.used = l.used; + out.limit = req.checkLimit; + + return out; + } + + private LabelAllocationOutcome allocateLabel(LabelAllocationRequest req) { + LabelAllocationOutcome out = new LabelAllocationOutcome(); + + out.request = req; + + Resource r = resourceDao.getResource(req.assetId, req.resourceName); + if (r == null) { + r = new LabelResource(); + r.resourceKey = new ResourceKey(); + r.resourceKey.assetId = req.assetId; + r.resourceKey.resourceName = req.resourceName; + r.resourceType = ResourceType.Label; + } else { + if (r.resourceType != ResourceType.Label) { + out.status = AllocationStatus.ResourceNotFound; + return out; + } + LabelUtil.recalculate((LabelResource) r); + } + + LabelResource l = (LabelResource) r; + if (LabelUtil.checkLabel(l, req)) { + out.status = AllocationStatus.Success; + out.currentLabel = l.label; + if (req.allocate) { + out.allocatedLabel = LabelUtil.allocateLabel(l, req); + updateList.add(l); + } + } else { + out.status = AllocationStatus.Failure; + } + + return out; + } + + private RangeAllocationOutcome allocateRange(RangeAllocationRequest req) { + RangeAllocationOutcome out = new RangeAllocationOutcome(); + + out.request = req; + + Resource r = resourceDao.getResource(req.assetId, req.resourceName); + if (r == null) { + r = new RangeResource(); + r.resourceKey = new ResourceKey(); + r.resourceKey.assetId = req.assetId; + r.resourceKey.resourceName = req.resourceName; + r.resourceType = ResourceType.Range; + } else { + if (r.resourceType != ResourceType.Range) { + out.status = AllocationStatus.ResourceNotFound; + return out; + } + RangeUtil.recalculate((RangeResource) r); + } + + RangeResource rr = (RangeResource) r; + SortedSet<Integer> foundNumbers = null; + if (!req.check) { + out.status = AllocationStatus.Success; + foundNumbers = req.requestedNumbers; + } else { + if (req.requestedNumbers != null && !req.requestedNumbers.isEmpty()) { + foundNumbers = req.requestedNumbers; + out.status = AllocationStatus.Success; + for (int n : foundNumbers) { + if (!RangeUtil.checkRange(rr, req, n)) { + out.status = AllocationStatus.Failure; + break; + } + } + } else { + foundNumbers = new TreeSet<>(); + int foundCount = 0; + + // First try to reuse the numbers already taken by the same resource union + SortedSet<Integer> uu = RangeUtil.getUsed(rr, req.resourceUnionId); + if (uu != null && !uu.isEmpty() && req.replace && !req.forceNewNumbers) { + if (uu.size() >= req.requestedCount) { + // Just take the first req.requestedCount numbers from uu + Iterator<Integer> i = uu.iterator(); + while (foundCount < req.requestedCount) { + foundNumbers.add(i.next()); + foundCount++; + } + } else { + // Additional numbers are requested. Try to find them starting from + // the minimum we have in uu (the first element) towards the min + // parameter, and then starting from the maximum in uu (the last + // element) towards the max parameter. + // NOTE: In case of request for sequential numbers, the parameters + // alignBlockSize and alignModulus are ignored. It would be harder + // to take them into account, and currently it is not needed. + + // Request may contain multiple ranges. We will find the range from the request + // that contains the currently used numbers (the first one). We will only look + // for additional numbers in that range. + + Range range = null; + if (req.rangeList != null) { + for (Range range1 : req.rangeList) { + if (uu.first() >= range1.min && uu.first() <= range1.max) { + range = range1; + break; + } + } + } + + if (range != null) { + int uumin = uu.first() - 1; + int uumax = uu.last() + 1; + foundNumbers.addAll(uu); + foundCount = uu.size(); + for (int n = uumin; foundCount < req.requestedCount && n >= range.min; n--) { + if (RangeUtil.checkRange(rr, req, n)) { + foundNumbers.add(n); + foundCount++; + } else if (req.sequential) { + break; + } + } + for (int n = uumax; foundCount < req.requestedCount && n <= range.max; n++) { + if (RangeUtil.checkRange(rr, req, n)) { + foundNumbers.add(n); + foundCount++; + } else if (req.sequential) { + break; + } + } + } + + // If we could not find enough numbers trying to reuse currently + // allocated, reset foundNumbers and foundCount, continue with + // the normal allocation of new numbers. + if (foundCount < req.requestedCount) { + foundNumbers = new TreeSet<>(); + foundCount = 0; + } + } + } + + if (req.rangeList != null && !req.rangeList.isEmpty()) { + if (req.nextInSequence) { + // This means we allocate numbers in ascending sequence, not trying from the beginning + // of the range (leaving possible holes in the sequence of allocated numbers) + // To do that, we go through the ranges from the last towards the first (assuming + // ranges are ordered from smallest to the largest numbers), and within each range, from + // the max towards the min and find the first allocated number. Then we take the next numbers + // in the range (that we already checked are available). + + int rangeIndex; + Range range = null; + int n = 0; + boolean foundAllocated = false; + for (rangeIndex = req.rangeList.size() - 1; !foundAllocated && rangeIndex >= 0; rangeIndex--) { + range = req.rangeList.get(rangeIndex); + for (n = range.max; n >= range.min; n--) { + if (!RangeUtil.checkRange(rr, req, n)) { + foundAllocated = true; + break; + } + } + if (foundAllocated) { + break; + } + } + n++; + for (; foundCount < req.requestedCount && n <= range.max; n++) { + foundNumbers.add(n); + foundCount++; + } + if (foundCount < req.requestedCount) { + rangeIndex++; + for (; rangeIndex < req.rangeList.size(); rangeIndex++) { + range = req.rangeList.get(rangeIndex); + for (n = range.min; foundCount < req.requestedCount && n <= range.max; n++) { + foundNumbers.add(n); + foundCount++; + } + } + } + // If we could not find enough numbers by going up in sequence, + // reset foundNumbers and foundCount, and go back to the holes + if (foundCount < req.requestedCount) { + foundNumbers = new TreeSet<>(); + foundCount = 0; + } + } + + if (req.reverseOrder) { + for (int i = req.rangeList.size() - 1; i >= 0; i--) { + Range range = req.rangeList.get(i); + for (int n = range.max; foundCount < req.requestedCount && n >= range.min; n--) { + if (RangeUtil.checkRange(rr, req, n)) { + foundNumbers.add(n); + foundCount++; + } else if (req.sequential) { + foundCount = 0; + } + } + } + } else { + for (Range range : req.rangeList) { + for (int n = range.min; foundCount < req.requestedCount && n <= range.max; n++) { + if (RangeUtil.checkRange(rr, req, n)) { + foundNumbers.add(n); + foundCount++; + } else if (req.sequential) { + foundCount = 0; + } + } + } + } + } + + out.status = foundCount == req.requestedCount ? AllocationStatus.Success : AllocationStatus.Failure; + } + } + + if (out.status == AllocationStatus.Success) { + out.allocated = foundNumbers; + if (req.allocate) { + RangeUtil.allocateRange(rr, out.allocated, req); + updateList.add(rr); + } + } else { + out.allocated = new TreeSet<>(); + } + + out.used = rr.used; + + return out; + } + + public AllocationOutcome getAllocationOutcome() { + return outcome; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ReleaseFunction.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ReleaseFunction.java new file mode 100644 index 000000000..b466b164b --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ReleaseFunction.java @@ -0,0 +1,149 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * Modifications Copyright © 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.rm.comp; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import org.onap.ccsdk.sli.adaptors.lock.comp.LockHelper; +import org.onap.ccsdk.sli.adaptors.lock.comp.ResourceLockedException; +import org.onap.ccsdk.sli.adaptors.lock.comp.SynchronizedFunction; +import org.onap.ccsdk.sli.adaptors.rm.dao.ResourceDao; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.ReleaseRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.Resource; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; +import org.onap.ccsdk.sli.adaptors.rm.util.ResourceUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class ReleaseFunction extends SynchronizedFunction { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(ReleaseFunction.class); + + private ResourceDao resourceDao; + + private ReleaseRequest releaseRequest; + + public ReleaseFunction(LockHelper lockHelper, ResourceDao resourceDao, ReleaseRequest releaseRequest, + Collection<String> lockNames, int lockTimeout) { + super(lockHelper, lockNames, lockTimeout); + this.resourceDao = resourceDao; + this.releaseRequest = releaseRequest; + } + + @Override + public void _exec() throws ResourceLockedException { + List<Resource> resourceList = new ArrayList<>(); + if (releaseRequest.assetId != null && releaseRequest.resourceName != null) { + Resource r = resourceDao.getResource(releaseRequest.assetId, releaseRequest.resourceName); + if (r != null) { + resourceList.add(r); + } + } else if (releaseRequest.assetId != null) { + if (releaseRequest.resourceSetId != null) { + resourceList = resourceDao.getResourceSetForAsset(releaseRequest.resourceSetId, releaseRequest.assetId); + } else { + resourceList = + resourceDao.getResourceUnionForAsset(releaseRequest.resourceUnionId, releaseRequest.assetId); + } + } else { + if (releaseRequest.resourceSetId != null) { + resourceList = resourceDao.getResourceSet(releaseRequest.resourceSetId); + } else { + resourceList = resourceDao.getResourceUnion(releaseRequest.resourceUnionId); + } + } + + for (Resource r : resourceList) { + boolean updated = false; + if (r.allocationItems != null) { + Iterator<AllocationItem> i = r.allocationItems.iterator(); + while (i.hasNext()) { + AllocationItem ai = i.next(); + if (releaseRequest.resourceSetId != null) { + + if (releaseRequest.resourceSetId.equals(ai.resourceSetId)) { + if (r.resourceType == ResourceType.Limit) { + LimitAllocationItem lai = (LimitAllocationItem) ai; + if (releaseRequest.releaseAmount > 0 && releaseRequest.releaseAmount < lai.used) { + lai.used -= releaseRequest.releaseAmount; + } else { + i.remove(); + } + } else if (r.resourceType == ResourceType.Range) { + RangeAllocationItem rai = (RangeAllocationItem) ai; + if (releaseRequest.releaseNumbers != null && !releaseRequest.releaseNumbers.isEmpty()) { + rai.used.removeAll(releaseRequest.releaseNumbers); + if (rai.used.isEmpty()) { + i.remove(); + } + } else { + i.remove(); + } + } else { + i.remove(); + } + updated = true; + } + + } else if (releaseRequest.resourceUnionId != null) { + + if (releaseRequest.resourceUnionId.equals(ai.resourceUnionId)) { + if (r.resourceType == ResourceType.Limit) { + LimitAllocationItem lai = (LimitAllocationItem) ai; + if (releaseRequest.releaseAmount > 0 && releaseRequest.releaseAmount < lai.used) { + lai.used -= releaseRequest.releaseAmount; + } else { + i.remove(); + } + } else if (r.resourceType == ResourceType.Range) { + RangeAllocationItem rai = (RangeAllocationItem) ai; + if (releaseRequest.releaseNumbers != null && !releaseRequest.releaseNumbers.isEmpty()) { + rai.used.removeAll(releaseRequest.releaseNumbers); + if (rai.used.isEmpty()) { + i.remove(); + } + } else { + i.remove(); + } + } else { + i.remove(); + } + updated = true; + } + + } + } + } + if (updated) { + ResourceUtil.recalculate(r); + resourceDao.saveResource(r); + } + } + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ResourceLoader.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ResourceLoader.java new file mode 100644 index 000000000..2d4df68b5 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ResourceLoader.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.comp; + +import java.util.Collection; + +import org.onap.ccsdk.sli.adaptors.rm.data.Resource; + +public interface ResourceLoader { + + void loadResource(String applicationId, Resource resource, boolean force); + + void loadResources(String applicationId, Collection<Resource> resourceList, boolean force); + + void loadResourcesForAsset(String applicationId, String assetId, Collection<Resource> resourceList, boolean force); + + void deleteResource(String applicationId, String assetId, String resourceName); + + void deleteResourcesForAsset(String applicationId, String assetId); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ResourceManager.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ResourceManager.java new file mode 100644 index 000000000..9dd54cc39 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ResourceManager.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.comp; + +import java.util.List; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.ReleaseRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.Resource; + +public interface ResourceManager { + + Resource getResource(String resourceName, String assetId); + + List<Resource> getResourceUnion(String resourceUnionId); + + AllocationOutcome allocateResources(AllocationRequest allocationRequest); + + void releaseResources(ReleaseRequest releaseRequest); + + Resource queryResource(String resourceName, String assetId, String resourceUnionFilter, + String resourceShareGroupFilter); + + List<Resource> queryResources(String resourceName, String assetIdFilter); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ResourceManagerImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ResourceManagerImpl.java new file mode 100644 index 000000000..83da27071 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/comp/ResourceManagerImpl.java @@ -0,0 +1,148 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.comp; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.onap.ccsdk.sli.adaptors.lock.comp.LockHelper; +import org.onap.ccsdk.sli.adaptors.rm.dao.ResourceDao; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationOutcome; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.ReleaseRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.Resource; +import org.onap.ccsdk.sli.adaptors.rm.util.ResourceUtil; +import org.onap.ccsdk.sli.adaptors.util.str.StrUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResourceManagerImpl implements ResourceManager { + + private static final Logger log = LoggerFactory.getLogger(ResourceManagerImpl.class); + + private LockHelper lockHelper; + private ResourceDao resourceDao; + + private int lockTimeout = 10 * 60; // Default 10 min + + public ResourceManagerImpl() { + log.info("ResourceManager created."); + } + + @Override + public Resource getResource(String resourceName, String assetId) { + Resource r = resourceDao.getResource(assetId, resourceName); + ResourceUtil.recalculate(r); + return r; + } + + @Override + public List<Resource> getResourceUnion(String resourceUnionId) { + List<Resource> rlist = resourceDao.getResourceUnion(resourceUnionId); + for (Resource r : rlist) { + ResourceUtil.recalculate(r); + } + return rlist; + } + + @Override + public AllocationOutcome allocateResources(AllocationRequest allocationRequest) { + if (allocationRequest == null) { + throw new IllegalArgumentException("allocateResources called with null argument"); + } + + AllocationFunction allocationFunction = + new AllocationFunction(lockHelper, resourceDao, allocationRequest, lockTimeout); + allocationFunction.exec(); + AllocationOutcome allocationOutcome = allocationFunction.getAllocationOutcome(); + + StrUtil.info(log, allocationOutcome); + + return allocationOutcome; + } + + @Override + public void releaseResources(ReleaseRequest releaseRequest) { + if (releaseRequest.resourceSetId == null && releaseRequest.resourceUnionId == null) { + return; + } + + Set<String> lockNames = new HashSet<>(); + if (releaseRequest.assetId != null) { + lockNames.add(releaseRequest.assetId); + } else { + List<Resource> resourceList = null; + if (releaseRequest.resourceSetId != null) { + resourceList = resourceDao.getResourceSet(releaseRequest.resourceSetId); + } else { + resourceList = resourceDao.getResourceUnion(releaseRequest.resourceUnionId); + } + + if (resourceList == null || resourceList.isEmpty()) { + return; + } + + lockNames = getLockNames(resourceList); + } + + ReleaseFunction releaseFunction = + new ReleaseFunction(lockHelper, resourceDao, releaseRequest, lockNames, lockTimeout); + releaseFunction.exec(); + } + + @Override + public Resource queryResource(String resourceName, String assetId, String resourceUnionFilter, + String resourceShareGroupFilter) { + Resource r = resourceDao.query(assetId, resourceName, resourceUnionFilter, resourceShareGroupFilter); + ResourceUtil.recalculate(r); + return r; + } + + @Override + public List<Resource> queryResources(String resourceName, String assetIdFilter) { + List<Resource> rlist = resourceDao.query(assetIdFilter, resourceName); + for (Resource r : rlist) { + ResourceUtil.recalculate(r); + } + return rlist; + } + + private Set<String> getLockNames(List<Resource> resourceList) { + Set<String> lockNames = new HashSet<>(); + for (Resource r : resourceList) { + lockNames.add(r.resourceKey.assetId); + } + return lockNames; + } + + public void setResourceDao(ResourceDao resourceDao) { + this.resourceDao = resourceDao; + } + + public void setLockTimeout(int lockTimeout) { + this.lockTimeout = lockTimeout; + } + + public void setLockHelper(LockHelper lockHelper) { + this.lockHelper = lockHelper; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/ResourceDao.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/ResourceDao.java new file mode 100644 index 000000000..87baf26c1 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/ResourceDao.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.dao; + +import java.util.List; +import org.onap.ccsdk.sli.adaptors.rm.data.Resource; + +public interface ResourceDao { + + Resource getResource(String assetId, String resourceName); + + void saveResource(Resource resource); + + void deleteResource(String assetId, String resourceName); + + List<Resource> getResourceSet(String resourceSetId); + + List<Resource> getResourceUnion(String resourceUnionId); + + List<Resource> getResourceSetForAsset(String resourceSetId, String assetId); + + List<Resource> getResourceUnionForAsset(String resourceUnionId, String assetId); + + Resource query(String assetId, String resourceName, String resourceUnionFilter, String resourceShareGroupFilter); + + List<Resource> query(String assetIdFilter, String resourceName); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/AllocationItem.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/AllocationItem.java new file mode 100644 index 000000000..25d8bf97e --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/AllocationItem.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +import java.util.Date; + +public class AllocationItem { + + public long id; + public long resourceId; + public String applicationId; + public String resourceSetId, resourceUnionId; + public String resourceShareGroupList; + public long ltUsed; + public String llLabel; + public String rrUsed; + public Date allocationTime; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/AllocationItemJdbcDao.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/AllocationItemJdbcDao.java new file mode 100644 index 000000000..8e3a12988 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/AllocationItemJdbcDao.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +import java.util.List; + +public interface AllocationItemJdbcDao { + + void add(AllocationItem ai); + + List<AllocationItem> getAllocationItems(long resourceId); + + void update(AllocationItem ai); + + void delete(long id); + + List<AllocationItem> queryAllocationItems(long resourceId, String resourceUnionFilter, String resourceShareGroupFilter); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/AllocationItemJdbcDaoImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/AllocationItemJdbcDaoImpl.java new file mode 100644 index 000000000..2a62c63a3 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/AllocationItemJdbcDaoImpl.java @@ -0,0 +1,146 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * Modifications Copyright © 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Collections; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; + +public class AllocationItemJdbcDaoImpl implements AllocationItemJdbcDao { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(ResourceJdbcDaoImpl.class); + + private static final String INSERT_SQL = "INSERT INTO ALLOCATION_ITEM (\n" + + " resource_id, application_id, resource_set_id, resource_union_id, resource_share_group_list,\n" + + " lt_used, ll_label, rr_used, allocation_time)\nVALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + private static final String UPDATE_SQL = "UPDATE ALLOCATION_ITEM SET\n" + + " resource_share_group_list = ?, lt_used = ?, ll_label = ?, rr_used = ?, allocation_time = ?\n" + + "WHERE allocation_item_id = ?"; + + private static final String DELETE_SQL = "DELETE FROM ALLOCATION_ITEM WHERE allocation_item_id = ?"; + + private static final String GET_SQL = "SELECT * FROM ALLOCATION_ITEM WHERE resource_id = ?"; + + private JdbcTemplate jdbcTemplate; + private AllocationItemRowMapper allocationItemRowMapper = new AllocationItemRowMapper(); + + @Override + public void add(final AllocationItem ai) { + PreparedStatementCreator psc = dbc -> { + PreparedStatement ps = dbc.prepareStatement(INSERT_SQL, new String[] { "allocation_item_id" }); + ps.setLong(1, ai.resourceId); + ps.setString(2, ai.applicationId); + ps.setString(3, ai.resourceSetId); + ps.setString(4, ai.resourceUnionId); + ps.setString(5, ai.resourceShareGroupList); + ps.setLong(6, ai.ltUsed); + ps.setString(7, ai.llLabel); + ps.setString(8, ai.rrUsed); + ps.setTimestamp(9, new Timestamp(ai.allocationTime.getTime())); + return ps; + }; + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(psc, keyHolder); + ai.id = keyHolder.getKey().longValue(); + } + + @Override + public void update(AllocationItem ai) { + Long ltUsed = ai.ltUsed <= 0 ? null : ai.ltUsed; + jdbcTemplate.update(UPDATE_SQL, ai.resourceShareGroupList, ltUsed, ai.llLabel, ai.rrUsed, ai.allocationTime, + ai.id); + } + + @Override + public void delete(long id) { + jdbcTemplate.update(DELETE_SQL, id); + } + + @Override + public List<AllocationItem> getAllocationItems(long resourceId) { + if (resourceId <= 0) { + return Collections.emptyList(); + } + + return jdbcTemplate.query(GET_SQL, new Object[] { resourceId }, allocationItemRowMapper); + } + + @Override + public List<AllocationItem> queryAllocationItems(long resourceId, String resourceUnionFilter, + String resourceShareGroupFilter) { + if (resourceId <= 0) { + return Collections.emptyList(); + } + + String sql = GET_SQL; + + if (resourceUnionFilter != null) { + sql += " AND resource_union_id LIKE '" + resourceUnionFilter + "'"; + } + + if (resourceShareGroupFilter != null) { + if (("null").equalsIgnoreCase(resourceShareGroupFilter)) { + sql += " AND resource_share_group_list IS NULL"; + } else { + sql += " AND resource_share_group_list LIKE '" + resourceShareGroupFilter + "'"; + } + } + + return jdbcTemplate.query(sql, new Object[] { resourceId }, allocationItemRowMapper); + } + + private static class AllocationItemRowMapper implements RowMapper<AllocationItem> { + + @Override + public AllocationItem mapRow(ResultSet rs, int n) throws SQLException { + AllocationItem ai = new AllocationItem(); + ai.id = rs.getLong("allocation_item_id"); + ai.resourceId = rs.getLong("resource_id"); + ai.applicationId = rs.getString("application_id"); + ai.resourceSetId = rs.getString("resource_set_id"); + ai.resourceUnionId = rs.getString("resource_union_id"); + ai.resourceShareGroupList = rs.getString("resource_share_group_list"); + ai.ltUsed = rs.getLong("lt_used"); + ai.llLabel = rs.getString("ll_label"); + ai.rrUsed = rs.getString("rr_used"); + ai.allocationTime = rs.getTimestamp("allocation_time"); + return ai; + } + } + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/Resource.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/Resource.java new file mode 100644 index 000000000..6b764a7e1 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/Resource.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +public class Resource { + + public long id; + public String assetId; + public String name; + public String type; + public long ltUsed; + public String llLabel; + public int llReferenceCount; + public String rrUsed; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceDaoImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceDaoImpl.java new file mode 100644 index 000000000..21f5575fc --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceDaoImpl.java @@ -0,0 +1,462 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import org.onap.ccsdk.sli.adaptors.rm.dao.ResourceDao; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelResource; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitResource; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeResource; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceKey; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; +import org.onap.ccsdk.sli.adaptors.util.str.StrUtil; + +public class ResourceDaoImpl implements ResourceDao { + + private ResourceJdbcDao resourceJdbcDao; + private ResourceLoadJdbcDao resourceLoadJdbcDao; + private AllocationItemJdbcDao allocationItemJdbcDao; + + @Override + public org.onap.ccsdk.sli.adaptors.rm.data.Resource getResource(String assetId, String resourceName) { + Resource rEntity = resourceJdbcDao.getResource(assetId, resourceName); + return createResourceWithItems(rEntity); + } + + @Override + public org.onap.ccsdk.sli.adaptors.rm.data.Resource query(String assetId, String resourceName, + String resourceUnionFilter, String resourceShareGroupFilter) { + Resource rEntity = resourceJdbcDao.getResource(assetId, resourceName); + org.onap.ccsdk.sli.adaptors.rm.data.Resource r = createResource(rEntity); + + if (r != null) { + List<AllocationItem> aiEntityList = allocationItemJdbcDao.queryAllocationItems(rEntity.id, + resourceUnionFilter, resourceShareGroupFilter); + r.allocationItems = new ArrayList<>(); + for (AllocationItem aiEntity : aiEntityList) { + org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem ai = createAllocationItem(r, aiEntity); + r.allocationItems.add(ai); + } + + List<ResourceLoad> rlEntityList = resourceLoadJdbcDao.getResourceLoads(rEntity.id); + r.resourceLoadList = new ArrayList<>(); + for (ResourceLoad rlEntity : rlEntityList) { + org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad rl = createResourceLoad(r, rlEntity); + r.resourceLoadList.add(rl); + } + } + + return r; + } + + @Override + public List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> query(String assetIdFilter, String resourceName) { + List<Resource> rEntityList = resourceJdbcDao.queryResources(assetIdFilter, resourceName); + List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> rlist = new ArrayList<>(); + for (Resource rEntity : rEntityList) { + org.onap.ccsdk.sli.adaptors.rm.data.Resource r = createResourceWithItems(rEntity); + rlist.add(r); + } + return rlist; + } + + @Override + public void saveResource(org.onap.ccsdk.sli.adaptors.rm.data.Resource resource) { + if (resource == null) { + return; + } + + org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.Resource resourceEntity = + resourceJdbcDao.getResource(resource.resourceKey.assetId, resource.resourceKey.resourceName); + if (resourceEntity == null) { + resourceEntity = createResourceEntity(resource); + resourceJdbcDao.add(resourceEntity); + if (resource.allocationItems != null) { + for (org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem ai : resource.allocationItems) { + AllocationItem aiEntity = createAllocationItemEntity(resourceEntity.id, ai); + allocationItemJdbcDao.add(aiEntity); + } + } + if (resource.resourceLoadList != null) { + for (org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad rl : resource.resourceLoadList) { + ResourceLoad rlEntity = createResourceLoadEntity(resourceEntity.id, rl); + resourceLoadJdbcDao.add(rlEntity); + } + } + } else { + updateResourceEntity(resourceEntity, resource); + resourceJdbcDao.update(resourceEntity); + + List<AllocationItem> oldAiEntityList = allocationItemJdbcDao.getAllocationItems(resourceEntity.id); + if (resource.allocationItems != null) { + for (org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem newai : resource.allocationItems) { + AllocationItem foundAiEntity = null; + for (AllocationItem oldAiEntity : oldAiEntityList) { + if (oldAiEntity.resourceSetId.equals(newai.resourceSetId)) { + foundAiEntity = oldAiEntity; + break; + } + } + if (foundAiEntity != null) { + if (allocationItemChanged(foundAiEntity, newai)) { + updateAllocationItemEntity(foundAiEntity, newai); + allocationItemJdbcDao.update(foundAiEntity); + } + } else { + AllocationItem newAiEntity = createAllocationItemEntity(resourceEntity.id, newai); + allocationItemJdbcDao.add(newAiEntity); + } + } + } + for (AllocationItem oldAiEntity : oldAiEntityList) { + boolean found = false; + if (resource.allocationItems != null) { + for (org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem newai : resource.allocationItems) { + if (oldAiEntity.resourceSetId.equals(newai.resourceSetId)) { + found = true; + break; + } + } + } + if (!found) { + allocationItemJdbcDao.delete(oldAiEntity.id); + } + } + + List<ResourceLoad> oldRlEntityList = resourceLoadJdbcDao.getResourceLoads(resourceEntity.id); + if (resource.resourceLoadList != null) { + for (org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad newrl : resource.resourceLoadList) { + ResourceLoad foundRlEntity = null; + for (ResourceLoad oldRlEntity : oldRlEntityList) { + if (oldRlEntity.applicationId.equals(newrl.applicationId)) { + foundRlEntity = oldRlEntity; + break; + } + } + if (foundRlEntity != null) { + updateResourceLoadEntity(foundRlEntity, newrl); + resourceLoadJdbcDao.update(foundRlEntity); + } else { + ResourceLoad newRlEntity = createResourceLoadEntity(resourceEntity.id, newrl); + resourceLoadJdbcDao.add(newRlEntity); + } + } + } + for (ResourceLoad oldRlEntity : oldRlEntityList) { + boolean found = false; + if (resource.resourceLoadList != null) { + for (org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad newrl : resource.resourceLoadList) { + if (oldRlEntity.applicationId.equals(newrl.applicationId)) { + found = true; + break; + } + } + } + if (!found) { + resourceLoadJdbcDao.delete(oldRlEntity.id); + } + } + } + } + + private boolean allocationItemChanged(AllocationItem aiEntity, + org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem newai) { + String newShareGroupList = StrUtil.listStr(newai.resourceShareGroupList); + if (!eq(aiEntity.resourceShareGroupList, newShareGroupList)) { + return true; + } + + if (newai.resourceType == ResourceType.Limit) { + if (aiEntity.ltUsed != ((LimitAllocationItem) newai).used) { + return true; + } + } else if (newai.resourceType == ResourceType.Label) { + if (!eq(aiEntity.llLabel, ((LabelAllocationItem) newai).label)) { + return true; + } + } else if (newai.resourceType == ResourceType.Range) { + String newRrUsed = StrUtil.listInt(((RangeAllocationItem) newai).used); + if (!eq(aiEntity.rrUsed, newRrUsed)) { + return true; + } + } + + return false; + } + + @Override + public void deleteResource(String assetId, String resourceName) { + org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.Resource resourceEntity = + resourceJdbcDao.getResource(assetId, resourceName); + if (resourceEntity != null) { + resourceJdbcDao.delete(resourceEntity.id); + } + } + + @Override + public List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> getResourceSet(String resourceSetId) { + List<Resource> rEntityList = resourceJdbcDao.getResourceSet(resourceSetId); + List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> rlist = new ArrayList<>(); + for (Resource rEntity : rEntityList) { + org.onap.ccsdk.sli.adaptors.rm.data.Resource r = createResourceWithItems(rEntity); + rlist.add(r); + } + return rlist; + } + + @Override + public List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> getResourceUnion(String resourceUnionId) { + List<Resource> rEntityList = resourceJdbcDao.getResourceUnion(resourceUnionId); + List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> rlist = new ArrayList<>(); + for (Resource rEntity : rEntityList) { + org.onap.ccsdk.sli.adaptors.rm.data.Resource r = createResourceWithItems(rEntity); + rlist.add(r); + } + return rlist; + } + + @Override + public List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> getResourceSetForAsset(String resourceSetId, + String assetId) { + List<Resource> rEntityList = resourceJdbcDao.getResourceSetForAsset(resourceSetId, assetId); + List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> rlist = new ArrayList<>(); + for (Resource rEntity : rEntityList) { + org.onap.ccsdk.sli.adaptors.rm.data.Resource r = createResourceWithItems(rEntity); + rlist.add(r); + } + return rlist; + } + + @Override + public List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> getResourceUnionForAsset(String resourceUnionId, + String assetId) { + List<Resource> rEntityList = resourceJdbcDao.getResourceUnionForAsset(resourceUnionId, assetId); + List<org.onap.ccsdk.sli.adaptors.rm.data.Resource> rlist = new ArrayList<>(); + for (Resource rEntity : rEntityList) { + org.onap.ccsdk.sli.adaptors.rm.data.Resource r = createResourceWithItems(rEntity); + rlist.add(r); + } + return rlist; + } + + private Resource createResourceEntity(org.onap.ccsdk.sli.adaptors.rm.data.Resource resource) { + Resource resourceEntity = new Resource(); + resourceEntity.assetId = resource.resourceKey.assetId; + resourceEntity.name = resource.resourceKey.resourceName; + resourceEntity.type = resource.resourceType.toString(); + if (resource.resourceType == ResourceType.Limit) { + resourceEntity.ltUsed = ((LimitResource) resource).used; + } else if (resource.resourceType == ResourceType.Label) { + resourceEntity.llLabel = ((LabelResource) resource).label; + resourceEntity.llReferenceCount = ((LabelResource) resource).referenceCount; + } else if (resource.resourceType == ResourceType.Range) { + resourceEntity.rrUsed = StrUtil.listInt(((RangeResource) resource).used); + } + + return resourceEntity; + } + + private ResourceLoad createResourceLoadEntity(long resourceId, + org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad rl) { + ResourceLoad rlEntity = new ResourceLoad(); + rlEntity.resourceId = resourceId; + rlEntity.applicationId = rl.applicationId; + rlEntity.loadTime = rl.resourceLoadTime; + rlEntity.expirationTime = rl.resourceExpirationTime; + return rlEntity; + } + + private void updateResourceLoadEntity(ResourceLoad rlEntity, org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad rl) { + rlEntity.loadTime = rl.resourceLoadTime; + rlEntity.expirationTime = rl.resourceExpirationTime; + } + + private AllocationItem createAllocationItemEntity(long resourceId, + org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem ai) { + AllocationItem aiEntity = new AllocationItem(); + aiEntity.resourceId = resourceId; + aiEntity.resourceSetId = ai.resourceSetId; + aiEntity.resourceUnionId = ai.resourceUnionId; + aiEntity.resourceShareGroupList = StrUtil.listStr(ai.resourceShareGroupList); + aiEntity.applicationId = ai.applicationId; + aiEntity.allocationTime = ai.allocationTime; + if (ai.resourceType == ResourceType.Limit) { + aiEntity.ltUsed = ((LimitAllocationItem) ai).used; + } else if (ai.resourceType == ResourceType.Label) { + aiEntity.llLabel = ((LabelAllocationItem) ai).label; + } else if (ai.resourceType == ResourceType.Range) { + aiEntity.rrUsed = StrUtil.listInt(((RangeAllocationItem) ai).used); + } + return aiEntity; + } + + private void updateAllocationItemEntity(AllocationItem aiEntity, + org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem ai) { + aiEntity.resourceShareGroupList = StrUtil.listStr(ai.resourceShareGroupList); + aiEntity.allocationTime = ai.allocationTime; + if (ai.resourceType == ResourceType.Limit) { + aiEntity.ltUsed = ((LimitAllocationItem) ai).used; + } else if (ai.resourceType == ResourceType.Label) { + aiEntity.llLabel = ((LabelAllocationItem) ai).label; + } else if (ai.resourceType == ResourceType.Range) { + aiEntity.rrUsed = StrUtil.listInt(((RangeAllocationItem) ai).used); + } + } + + private void updateResourceEntity(Resource resourceEntity, org.onap.ccsdk.sli.adaptors.rm.data.Resource resource) { + if (resource.resourceType == ResourceType.Limit) { + resourceEntity.ltUsed = ((LimitResource) resource).used; + } else if (resource.resourceType == ResourceType.Label) { + resourceEntity.llLabel = ((LabelResource) resource).label; + resourceEntity.llReferenceCount = ((LabelResource) resource).referenceCount; + } else if (resource.resourceType == ResourceType.Range) { + resourceEntity.rrUsed = StrUtil.listInt(((RangeResource) resource).used); + } + } + + private org.onap.ccsdk.sli.adaptors.rm.data.Resource createResourceWithItems(Resource rEntity) { + org.onap.ccsdk.sli.adaptors.rm.data.Resource r = createResource(rEntity); + + if (r != null) { + List<AllocationItem> aiEntityList = allocationItemJdbcDao.getAllocationItems(rEntity.id); + r.allocationItems = new ArrayList<>(); + for (AllocationItem aiEntity : aiEntityList) { + org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem ai = createAllocationItem(r, aiEntity); + r.allocationItems.add(ai); + } + + List<ResourceLoad> rlEntityList = resourceLoadJdbcDao.getResourceLoads(rEntity.id); + r.resourceLoadList = new ArrayList<>(); + for (ResourceLoad rlEntity : rlEntityList) { + org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad rl = createResourceLoad(r, rlEntity); + r.resourceLoadList.add(rl); + } + } + return r; + } + + private org.onap.ccsdk.sli.adaptors.rm.data.Resource createResource(Resource resourceEntity) { + if (resourceEntity == null) { + return null; + } + + org.onap.ccsdk.sli.adaptors.rm.data.Resource r = null; + ResourceType type = ResourceType.valueOf(resourceEntity.type); + if (type == ResourceType.Limit) { + LimitResource l = new LimitResource(); + l.used = resourceEntity.ltUsed; + r = l; + } else if (type == ResourceType.Label) { + LabelResource l = new LabelResource(); + l.label = resourceEntity.llLabel; + l.referenceCount = resourceEntity.llReferenceCount; + r = l; + } else if (type == ResourceType.Range) { + RangeResource rr = new RangeResource(); + rr.used = StrUtil.listInt(resourceEntity.rrUsed, "Invalid data found in DB in for Resource Id: " + + resourceEntity.id + ": RESOURCE.RR_USED: " + resourceEntity.rrUsed); + r = rr; + } + + if (r != null) { + r.resourceType = type; + r.resourceKey = new ResourceKey(); + r.resourceKey.assetId = resourceEntity.assetId; + r.resourceKey.resourceName = resourceEntity.name; + } + + return r; + } + + private org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem createAllocationItem( + org.onap.ccsdk.sli.adaptors.rm.data.Resource r, AllocationItem aiEntity) { + if (r == null || aiEntity == null) { + return null; + } + + org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem ai = null; + if (r.resourceType == ResourceType.Limit) { + LimitAllocationItem lai = new LimitAllocationItem(); + lai.used = aiEntity.ltUsed; + ai = lai; + } else if (r.resourceType == ResourceType.Label) { + LabelAllocationItem lai = new LabelAllocationItem(); + lai.label = aiEntity.llLabel; + ai = lai; + } else if (r.resourceType == ResourceType.Range) { + RangeAllocationItem rai = new RangeAllocationItem(); + rai.used = StrUtil.listInt(aiEntity.rrUsed, "Invalid data found in DB in for Allocation Item Id: " + + aiEntity.id + ": ALLOCATION_ITEM.RR_USED: " + aiEntity.rrUsed); + ai = rai; + } + + if (ai != null) { + ai.resourceType = r.resourceType; + ai.resourceKey = r.resourceKey; + ai.resourceSetId = aiEntity.resourceSetId; + ai.resourceUnionId = aiEntity.resourceUnionId; + if (aiEntity.resourceShareGroupList != null) { + ai.resourceShareGroupList = new HashSet<>(StrUtil.listStr(aiEntity.resourceShareGroupList)); + } + ai.applicationId = aiEntity.applicationId; + ai.allocationTime = aiEntity.allocationTime; + } + + return ai; + } + + private org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad createResourceLoad( + org.onap.ccsdk.sli.adaptors.rm.data.Resource r, ResourceLoad rlEntity) { + if (rlEntity == null) { + return null; + } + + org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad rl = new org.onap.ccsdk.sli.adaptors.rm.data.ResourceLoad(); + rl.resourceKey = r.resourceKey; + rl.applicationId = rlEntity.applicationId; + rl.resourceLoadTime = rlEntity.loadTime; + rl.resourceExpirationTime = rlEntity.expirationTime; + + return rl; + } + + private static boolean eq(Object o1, Object o2) { + return o1 == null ? o2 == null : o1.equals(o2); + } + + public void setResourceJdbcDao(ResourceJdbcDao resourceJdbcDao) { + this.resourceJdbcDao = resourceJdbcDao; + } + + public void setResourceLoadJdbcDao(ResourceLoadJdbcDao resourceLoadJdbcDao) { + this.resourceLoadJdbcDao = resourceLoadJdbcDao; + } + + public void setAllocationItemJdbcDao(AllocationItemJdbcDao allocationItemJdbcDao) { + this.allocationItemJdbcDao = allocationItemJdbcDao; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceJdbcDao.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceJdbcDao.java new file mode 100644 index 000000000..d4d9a0543 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceJdbcDao.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +import java.util.List; + +public interface ResourceJdbcDao { + + Resource getResource(String assetId, String resourceName); + + List<Resource> queryResources(String assetIdFilter, String resourceName); + + List<Resource> getResourceSet(String resourceSetId); + + List<Resource> getResourceUnion(String resourceUnionId); + + List<Resource> getResourceSetForAsset(String resourceSetId, String assetId); + + List<Resource> getResourceUnionForAsset(String resourceUnionId, String assetId); + + void add(Resource r); + + void delete(long id); + + void update(Resource r); +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceJdbcDaoImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceJdbcDaoImpl.java new file mode 100644 index 000000000..f9de42802 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceJdbcDaoImpl.java @@ -0,0 +1,183 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collections; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; + +public class ResourceJdbcDaoImpl implements ResourceJdbcDao { + + private static final String baseSelectResourceQuery = "SELECT * FROM RESOURCE WHERE resource_id IN (\n"; + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(ResourceJdbcDaoImpl.class); + + private static final String RESOURCE_SQL = "SELECT * FROM RESOURCE WHERE asset_id = ? AND resource_name = ?"; + + private static final String RESOURCE_QUERY_1_SQL = + "SELECT * FROM RESOURCE WHERE asset_id LIKE ? AND resource_name = ?"; + + private static final String RESOURCE_SET_SQL = baseSelectResourceQuery + + "SELECT DISTINCT resource_id FROM ALLOCATION_ITEM WHERE resource_set_id = ?)"; + + private static final String RESOURCE_UNION_SQL = baseSelectResourceQuery + + "SELECT DISTINCT resource_id FROM ALLOCATION_ITEM WHERE resource_union_id = ?)"; + + private static final String RESOURCE_SET_FOR_ASSET_SQL = baseSelectResourceQuery + + "SELECT DISTINCT resource_id FROM ALLOCATION_ITEM WHERE resource_set_id = ?) AND asset_id = ?"; + + private static final String RESOURCE_UNION_FOR_ASSET_SQL = baseSelectResourceQuery + + "SELECT DISTINCT resource_id FROM ALLOCATION_ITEM WHERE resource_union_id = ?) AND asset_id = ?"; + + private static final String INSERT_SQL = "INSERT INTO RESOURCE (\n" + + " asset_id, resource_name, resource_type, lt_used, ll_label, ll_reference_count, rr_used)\n" + + "VALUES (?, ?, ?, ?, ?, ?, ?)"; + + private static final String UPDATE_SQL = "UPDATE RESOURCE SET\n" + + " lt_used = ?, ll_label = ?, ll_reference_count = ?, rr_used = ?\nWHERE resource_id = ?"; + + private static final String DELETE_SQL = "DELETE FROM RESOURCE WHERE resource_id = ?"; + + private JdbcTemplate jdbcTemplate; + private ResourceRowMapper resourceRowMapper = new ResourceRowMapper(); + + @Override + public Resource getResource(String assetId, String resourceName) { + if (assetId == null || assetId.trim().length() == 0 || resourceName == null + || resourceName.trim().length() == 0) { + return null; + } + + List<Resource> ll = jdbcTemplate.query(RESOURCE_SQL, new Object[] {assetId, resourceName}, resourceRowMapper); + return ll.isEmpty() ? null : ll.get(0); + } + + @Override + public List<Resource> queryResources(String assetIdFilter, String resourceName) { + if (assetIdFilter == null || assetIdFilter.trim().length() == 0 || resourceName == null + || resourceName.trim().length() == 0) { + return Collections.emptyList(); + } + + + return jdbcTemplate.query(RESOURCE_QUERY_1_SQL, new Object[] {assetIdFilter, resourceName}, resourceRowMapper); + } + + @Override + public List<Resource> getResourceSet(String resourceSetId) { + if (resourceSetId == null) { + return Collections.emptyList(); + } + + return jdbcTemplate.query(RESOURCE_SET_SQL, new Object[] {resourceSetId}, resourceRowMapper); + } + + @Override + public List<Resource> getResourceUnion(String resourceUnionId) { + if (resourceUnionId == null) { + return Collections.emptyList(); + } + + return jdbcTemplate.query(RESOURCE_UNION_SQL, new Object[] {resourceUnionId}, resourceRowMapper); + } + + @Override + public List<Resource> getResourceSetForAsset(String resourceSetId, String assetId) { + if (resourceSetId == null) { + return Collections.emptyList(); + } + + return jdbcTemplate.query(RESOURCE_SET_FOR_ASSET_SQL, new Object[] {resourceSetId, assetId}, resourceRowMapper); + } + + @Override + public List<Resource> getResourceUnionForAsset(String resourceUnionId, String assetId) { + if (resourceUnionId == null) { + return Collections.emptyList(); + } + + return jdbcTemplate.query(RESOURCE_UNION_FOR_ASSET_SQL, new Object[] {resourceUnionId, assetId}, + resourceRowMapper); + } + + @Override + public void add(final Resource r) { + PreparedStatementCreator psc = dbc -> { + PreparedStatement ps = dbc.prepareStatement(INSERT_SQL, new String[] {"resource_id"}); + ps.setString(1, r.assetId); + ps.setString(2, r.name); + ps.setString(3, r.type); + ps.setLong(4, r.ltUsed); + ps.setString(5, r.llLabel); + ps.setInt(6, r.llReferenceCount); + ps.setString(7, r.rrUsed); + return ps; + }; + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(psc, keyHolder); + r.id = keyHolder.getKey().longValue(); + } + + @Override + public void update(Resource r) { + Long ltUsed = r.ltUsed <= 0 ? null : r.ltUsed; + Integer llRefCount = r.llReferenceCount <= 0 ? null : r.llReferenceCount; + jdbcTemplate.update(UPDATE_SQL, ltUsed, r.llLabel, llRefCount, r.rrUsed, r.id); + } + + @Override + public void delete(long id) { + jdbcTemplate.update(DELETE_SQL, id); + } + + private static class ResourceRowMapper implements RowMapper<Resource> { + + @Override + public Resource mapRow(ResultSet rs, int arg1) throws SQLException { + Resource r = new Resource(); + r.id = rs.getLong("resource_id"); + r.assetId = rs.getString("asset_id"); + r.name = rs.getString("resource_name"); + r.type = rs.getString("resource_type"); + r.ltUsed = rs.getLong("lt_used"); + r.llLabel = rs.getString("ll_label"); + r.llReferenceCount = rs.getInt("ll_reference_count"); + r.rrUsed = rs.getString("rr_used"); + return r; + } + } + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceLoad.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceLoad.java new file mode 100644 index 000000000..0f45bbfcb --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceLoad.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +import java.util.Date; + +public class ResourceLoad { + + public long id; + public long resourceId; + public String applicationId; + public Date loadTime; + public Date expirationTime; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceLoadJdbcDao.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceLoadJdbcDao.java new file mode 100644 index 000000000..789670c4b --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceLoadJdbcDao.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +import java.util.List; + +public interface ResourceLoadJdbcDao { + + void add(ResourceLoad rl); + + List<ResourceLoad> getResourceLoads(long resourceId); + + void update(ResourceLoad rl); + + void delete(long id); + +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceLoadJdbcDaoImpl.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceLoadJdbcDaoImpl.java new file mode 100644 index 000000000..632a5fbec --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/dao/jdbc/ResourceLoadJdbcDaoImpl.java @@ -0,0 +1,112 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.dao.jdbc; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Collections; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; + +public class ResourceLoadJdbcDaoImpl implements ResourceLoadJdbcDao { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(ResourceJdbcDaoImpl.class); + + private static final String INSERT_SQL = "INSERT INTO RESOURCE_LOAD (\n" + + " resource_id, application_id, resource_load_time, resource_expiration_time)\nVALUES (?, ?, ?, ?)"; + + private static final String UPDATE_SQL = "UPDATE RESOURCE_LOAD SET\n" + + " resource_load_time = ?, resource_expiration_time = ?\nWHERE resource_id = ?"; + + private static final String DELETE_SQL = "DELETE FROM RESOURCE_LOAD WHERE resource_load_id = ?"; + + private static final String GET_SQL = "SELECT * FROM RESOURCE_LOAD WHERE resource_id = ?"; + + private JdbcTemplate jdbcTemplate; + private ResourceLoadRowMapper resourceLoadRowMapper = new ResourceLoadRowMapper(); + + @Override + public void add(final ResourceLoad rl) { + PreparedStatementCreator psc = new PreparedStatementCreator() { + + @Override + public PreparedStatement createPreparedStatement(Connection dbc) throws SQLException { + PreparedStatement ps = dbc.prepareStatement(INSERT_SQL, new String[] { "resource_load_id" }); + ps.setLong(1, rl.resourceId); + ps.setString(2, rl.applicationId); + ps.setTimestamp(3, new Timestamp(rl.loadTime.getTime())); + ps.setTimestamp(4, new Timestamp(rl.expirationTime.getTime())); + return ps; + } + }; + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcTemplate.update(psc, keyHolder); + rl.id = keyHolder.getKey().longValue(); + } + + @Override + public void update(ResourceLoad rl) { + jdbcTemplate.update(UPDATE_SQL, rl.loadTime, rl.expirationTime, rl.id); + } + + @Override + public void delete(long id) { + jdbcTemplate.update(DELETE_SQL, id); + } + + @Override + public List<ResourceLoad> getResourceLoads(long resourceId) { + if (resourceId <= 0) + return Collections.emptyList(); + + return jdbcTemplate.query(GET_SQL, new Object[] { resourceId }, resourceLoadRowMapper); + } + + private static class ResourceLoadRowMapper implements RowMapper<ResourceLoad> { + + @Override + public ResourceLoad mapRow(ResultSet rs, int n) throws SQLException { + ResourceLoad rl = new ResourceLoad(); + rl.id = rs.getLong("allocation_item_id"); + rl.resourceId = rs.getLong("resource_id"); + rl.applicationId = rs.getString("application_id"); + rl.loadTime = rs.getTimestamp("resource_load_time"); + rl.expirationTime = rs.getTimestamp("resource_expiration_time"); + return rl; + } + } + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationAction.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationAction.java new file mode 100644 index 000000000..edc1916b5 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationAction.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public enum AllocationAction { + Fail, Succeed_DoNothing, Succeed_Allocate +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationItem.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationItem.java new file mode 100644 index 000000000..f8e6a75a1 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationItem.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.Date; +import java.util.Set; + +public abstract class AllocationItem { + + public ResourceKey resourceKey; + public ResourceType resourceType; + public String resourceSetId; + public String resourceUnionId; + public Set<String> resourceShareGroupList; + public String applicationId; + public Date allocationTime; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationOutcome.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationOutcome.java new file mode 100644 index 000000000..048f4f4ac --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationOutcome.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class AllocationOutcome { + + public AllocationStatus status = null; + public AllocationRequest request = null; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationRequest.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationRequest.java new file mode 100644 index 000000000..29b493683 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationRequest.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.Set; + +public class AllocationRequest { + + public String applicationId = null; + public String resourceUnionId = null; + public String resourceSetId = null; + public Set<String> resourceShareGroupList = null; + public String resourceName = null; + public String assetId = null; + public AllocationAction missingResourceAction = AllocationAction.Succeed_Allocate; + public AllocationAction expiredResourceAction = AllocationAction.Succeed_Allocate; + public String endPointPosition = null; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationStatus.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationStatus.java new file mode 100644 index 000000000..bef9a1114 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/AllocationStatus.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public enum AllocationStatus { + + Success, Failure, NotTried, ResourceNotFound, ResourceExpired +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/InitAction.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/InitAction.java new file mode 100644 index 000000000..f6fc7c9b3 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/InitAction.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public enum InitAction { + CheckInit("Initialize if needed"), ForceInit("Always Initialize"), NoInit("No initialization"); + + private String str; + + private InitAction(String str) { + this.str = str; + } + + public String getInitActionStr() { + return str; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelAllocationItem.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelAllocationItem.java new file mode 100644 index 000000000..d41bfd62a --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelAllocationItem.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class LabelAllocationItem extends AllocationItem { + + public String label; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelAllocationOutcome.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelAllocationOutcome.java new file mode 100644 index 000000000..9c9f9145d --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelAllocationOutcome.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class LabelAllocationOutcome extends AllocationOutcome { + + public String allocatedLabel = null; + public String currentLabel = null; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelAllocationRequest.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelAllocationRequest.java new file mode 100644 index 000000000..97751fc01 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelAllocationRequest.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class LabelAllocationRequest extends AllocationRequest { + + public String label = null; + public boolean check = false; + public boolean allocate = false; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelResource.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelResource.java new file mode 100644 index 000000000..d09dba267 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LabelResource.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class LabelResource extends Resource { + + public static final String BLOCKED = "__BLOCKED__"; + + public String label; + public int referenceCount; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitAllocationItem.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitAllocationItem.java new file mode 100644 index 000000000..ad1674f7b --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitAllocationItem.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class LimitAllocationItem extends AllocationItem { + + public long used; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitAllocationOutcome.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitAllocationOutcome.java new file mode 100644 index 000000000..d635e3605 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitAllocationOutcome.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class LimitAllocationOutcome extends AllocationOutcome { + + public long allocatedCount = 0; + public long used = 0; + public long limit = 0; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitAllocationRequest.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitAllocationRequest.java new file mode 100644 index 000000000..06c0e8393 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitAllocationRequest.java @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class LimitAllocationRequest extends AllocationRequest { + + public long checkCount = 0; + public long allocateCount = 0; + public long checkLimit = -1; + public boolean replace = false; + public boolean strict = false; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitResource.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitResource.java new file mode 100644 index 000000000..2fd9b6cae --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/LimitResource.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class LimitResource extends Resource { + + public long used = 0; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiAssetAllocationOutcome.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiAssetAllocationOutcome.java new file mode 100644 index 000000000..2d7b11c31 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiAssetAllocationOutcome.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.List; + +public class MultiAssetAllocationOutcome extends AllocationOutcome { + + public List<String> goodAssetIdList; + public List<AllocationOutcome> allocationOutcomeList; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiAssetAllocationRequest.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiAssetAllocationRequest.java new file mode 100644 index 000000000..366201f35 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiAssetAllocationRequest.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.List; + +public class MultiAssetAllocationRequest extends AllocationRequest { + + public List<String> assetIdList = null; + public AllocationRequest allocationRequest = null; + public int requestedCount = 0; + public boolean sequential = false; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiResourceAllocationOutcome.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiResourceAllocationOutcome.java new file mode 100644 index 000000000..f71c247da --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiResourceAllocationOutcome.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.List; + +public class MultiResourceAllocationOutcome extends AllocationOutcome { + + public List<AllocationOutcome> allocationOutcomeList; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiResourceAllocationRequest.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiResourceAllocationRequest.java new file mode 100644 index 000000000..3244c2340 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/MultiResourceAllocationRequest.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.List; + +public class MultiResourceAllocationRequest extends AllocationRequest { + + public List<AllocationRequest> allocationRequestList = null; + public boolean stopOnFirstFailure = true; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/Range.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/Range.java new file mode 100644 index 000000000..16be77f5b --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/Range.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class Range { + + public int min = 0; + public int max = 0; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeAllocationItem.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeAllocationItem.java new file mode 100644 index 000000000..8e62ef653 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeAllocationItem.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.SortedSet; + +public class RangeAllocationItem extends AllocationItem { + + public SortedSet<Integer> used; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeAllocationOutcome.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeAllocationOutcome.java new file mode 100644 index 000000000..3b675c221 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeAllocationOutcome.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.SortedSet; + +public class RangeAllocationOutcome extends AllocationOutcome { + + public SortedSet<Integer> allocated = null; + public SortedSet<Integer> used = null; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeAllocationRequest.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeAllocationRequest.java new file mode 100644 index 000000000..a7948b02c --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeAllocationRequest.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.List; +import java.util.SortedSet; + +public class RangeAllocationRequest extends AllocationRequest { + + public List<Range> rangeList = null; + public boolean check = false; + public boolean allocate = false; + public boolean replace = false; + public SortedSet<Integer> requestedNumbers = null; + public SortedSet<Integer> excludeNumbers = null; + public int requestedCount = 1; + public boolean sequential = false; + public boolean reverseOrder = false; + public boolean forceNewNumbers = false; + public boolean nextInSequence = false; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeResource.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeResource.java new file mode 100644 index 000000000..c39cb37ea --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/RangeResource.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.SortedSet; + +public class RangeResource extends Resource { + + public SortedSet<Integer> used; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ReleaseRequest.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ReleaseRequest.java new file mode 100644 index 000000000..dba6a172f --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ReleaseRequest.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.Set; + +public class ReleaseRequest { + + public String resourceUnionId = null; + public String resourceSetId = null; + public String assetId = null; + public String resourceName = null; + public int releaseAmount = 0; + public Set<Integer> releaseNumbers = null; + + public static ReleaseRequest resourceSet(String resourceSetId) { + ReleaseRequest rr = new ReleaseRequest(); + rr.resourceSetId = resourceSetId; + return rr; + } + + public static ReleaseRequest resourceUnion(String resourceUnionId) { + ReleaseRequest rr = new ReleaseRequest(); + rr.resourceUnionId = resourceUnionId; + return rr; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/Resource.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/Resource.java new file mode 100644 index 000000000..59706f4d5 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/Resource.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.Collection; + +public abstract class Resource { + + public ResourceKey resourceKey; + public ResourceType resourceType; + public Collection<AllocationItem> allocationItems; + public Collection<ResourceLoad> resourceLoadList; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ResourceKey.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ResourceKey.java new file mode 100644 index 000000000..b1f8d5910 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ResourceKey.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public class ResourceKey { + + public String assetId; + public String resourceName; + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || !(o instanceof ResourceKey)) + return false; + ResourceKey rk = (ResourceKey) o; + if (assetId == null || resourceName == null) + return false; + return assetId.equals(rk.assetId) && resourceName.equals(rk.resourceName); + } + + @Override + public int hashCode() { + return (int) ((long) System.identityHashCode(assetId) + (long) System.identityHashCode(resourceName)); + } + + @Override + public String toString() { + return "(" + assetId + ", " + resourceName + ")"; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ResourceLoad.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ResourceLoad.java new file mode 100644 index 000000000..1ff1962af --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ResourceLoad.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +import java.util.Date; + +public class ResourceLoad { + + public ResourceKey resourceKey; + public String applicationId; + public Date resourceLoadTime; + public Date resourceExpirationTime; +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ResourceType.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ResourceType.java new file mode 100644 index 000000000..60896e492 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/data/ResourceType.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.data; + +public enum ResourceType { + Limit, Label, Range +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/LabelUtil.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/LabelUtil.java new file mode 100644 index 000000000..a67a50b31 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/LabelUtil.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.util; + +import java.util.ArrayList; +import java.util.Date; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelResource; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceKey; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; + +public class LabelUtil { + + public static boolean checkLabel(LabelResource l, LabelAllocationRequest req) { + if (req.check && req.label != null && l.allocationItems != null && !l.allocationItems.isEmpty()) { + for (AllocationItem ai : l.allocationItems) { + LabelAllocationItem lai = (LabelAllocationItem) ai; + if (!eq(req.resourceUnionId, lai.resourceUnionId) && !eq(req.label, lai.label)) { + return false; + } + } + } + return true; + } + + public static String allocateLabel(LabelResource l, LabelAllocationRequest req) { + if (!req.allocate) { + return null; + } + + LabelAllocationItem lai = (LabelAllocationItem) ResourceUtil.getAllocationItem(l, req.resourceSetId); + if (lai == null) { + lai = new LabelAllocationItem(); + lai.resourceType = ResourceType.Label; + lai.resourceKey = new ResourceKey(); + lai.resourceKey.assetId = req.assetId; + lai.resourceKey.resourceName = req.resourceName; + lai.applicationId = req.applicationId; + lai.resourceSetId = req.resourceSetId; + lai.resourceUnionId = req.resourceUnionId; + lai.resourceShareGroupList = req.resourceShareGroupList; + + if (l.allocationItems == null) { + l.allocationItems = new ArrayList<>(); + } + l.allocationItems.add(lai); + } + + lai.label = req.label; + lai.allocationTime = new Date(); + + recalculate(l); + + return lai.label; + } + + public static void recalculate(LabelResource l) { + l.label = null; + l.referenceCount = 0; + if (l.allocationItems != null) { + for (AllocationItem ai : l.allocationItems) { + LabelAllocationItem lai = (LabelAllocationItem) ai; + if (lai.label != null) { + l.referenceCount++; + if (l.label == null) { + l.label = lai.label; + } else if (!l.label.equals(lai.label)) { + l.label = "__BLOCKED__"; + } + } + } + } + } + + private static boolean eq(Object o1, Object o2) { + return o1 == null ? o2 == null : o1.equals(o2); + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/LimitUtil.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/LimitUtil.java new file mode 100644 index 000000000..2e36c9661 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/LimitUtil.java @@ -0,0 +1,355 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.util; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitResource; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceKey; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LimitUtil { + + private static final Logger log = LoggerFactory.getLogger(LimitUtil.class); + + public static boolean checkLimit(LimitResource l, LimitAllocationRequest req) { + if (req.checkCount <= 0) { + return true; + } + + long checkCount = req.checkCount; + long currentUsage = 0; + if (req.resourceSetId != null) { + LimitAllocationItem lai = (LimitAllocationItem) ResourceUtil.getAllocationItem(l, req.resourceSetId); + if (lai != null) { + currentUsage = lai.used; + } + } + if (!req.replace) { + checkCount += currentUsage; + } + + long used = calculateLimitUsage(l, 0, null, null); + long wouldUse = calculateLimitUsage(l, checkCount, req.resourceUnionId, req.resourceShareGroupList); + + // If usage is not increasing by this request, only check the limit if + // strictCheck is true. + if (wouldUse <= used && !req.strict) { + return true; + } + + return wouldUse <= req.checkLimit; + } + + private static long calculateLimitUsage( + LimitResource l, + long checkCount, + String resourceUnionId, + Set<String> resourceShareGroupList) { + if ((l.allocationItems == null || l.allocationItems.isEmpty()) && + (resourceUnionId == null || resourceUnionId.length() == 0)) { + return 0; + } + + long t1 = System.currentTimeMillis(); + boolean logit = false; + String rn = "Resource: " + l.resourceKey.resourceName + " - " + l.resourceKey.assetId; + + // In order to best utilize the resource, we need to take not the sum of all allocation items, but + // instead the maximum usage that could happen at any moment of time (given not all allocation items are active + // at the same time), also taking into account possible resource sharing. + // Thus we need to find all combinations of allocation items that can be active at the same time (allocation + // items with the same first union cannot be active at the same time), compute the usage for each (again, + // taking into account resource sharing), and take the maximum. + // + // Example: + // Let's have the following allocation items: + // ai1: sdid1, vrf1 - usage 5 + // ai2: sdid2, vrf1 - usage 10 + // ai3: sdid3, vrf2 - usage 15 + // ai4: sdid1, vrf3 - usage 20 + // ai5: sdid3, vrf1 - usage 25 + // The following combinations of active allocation items are possible: + // 1) ai1, ai2, ai3 + // 2) ai1, ai2, ai5 + // 3) ai2, ai3, ai4 + // 4) ai2, ai3, ai5 + // Here is how we calculate the usage for combination 1: + // ai1 and ai2 contain the same resource union vrf1, so they share the resource - we take the max of usage, + // so we have: + // max(5, 10) + 15 = 25 + // Similarly, we calculate the usage of the other combinations: + // 2) max(5, 10, 25) = 25 + // 3) 10 + 15 + 20 = 45 + // 4) max(10, 25) + 15 = 40 + // So, the result in this case is: + // max(25, 25, 45, 40) = 45 + // + // We might have a problem with this approach, if we have a lot of combinations. Assuming we have at most 2 + // allocation items with the same resource union (sdid), the number of combinations would be + // 2 ^ n + // where n is the number of allocation items that have the same resource union (sdid). That would be + // the number of change orders currently in progress. + // + // Here is one optimization that we can do: + // If we have allocation items that have all resource unions the same, we don't need to generate combinations + // with each of them, we can just take the one of them with the maximum usage, as it is clear that the others + // will not lead to a bigger usage. + // For example, if we had the following allocation items: + // ai1: sdid1, vrf1 - usage 10 + // ai2: sdid1, vrf1 - usage 20 + // We only need to take the combinations with ai2, as they will always lead to bigger usage than the remaining + // combinations with ai1. + + // First, group the allocation items by the first resource union, using the LimitUsage structure + int regularChangeCount = 0; + Map<String/* resourceUnionId */, List<LimitUsage>> limitUsageMap = new HashMap<>(); + if (l.allocationItems != null) { + for (AllocationItem ai : l.allocationItems) { + LimitAllocationItem lai = (LimitAllocationItem) ai; + boolean regularChange = + addLimitUsage(limitUsageMap, lai.resourceUnionId, lai.resourceShareGroupList, lai.used); + if (regularChange) { + regularChangeCount++; + } + } + } + if (checkCount > 0 && resourceUnionId != null) { + boolean regularChange = addLimitUsage(limitUsageMap, resourceUnionId, resourceShareGroupList, checkCount); + if (regularChange) { + regularChangeCount++; + } + } + + // Generate all the combinations, containing one LimitUsage object for each firstResourceUnion + int significantChangeCount = 0; + List<List<LimitUsage>> allCombinations = new ArrayList<>(); + for (String firstResourceUnion : limitUsageMap.keySet()) { + List<LimitUsage> limitUsageList = limitUsageMap.get(firstResourceUnion); + if (limitUsageList.size() > 1) { + significantChangeCount++; + } + if (allCombinations.isEmpty()) { + for (LimitUsage limitUsage : limitUsageList) { + List<LimitUsage> newCombination = new ArrayList<>(); + newCombination.add(limitUsage); + allCombinations.add(newCombination); + } + } else { + if (limitUsageList.size() == 1) { + // No new combinations are generated - just add this one to all combinations we have until now + for (List<LimitUsage> combination : allCombinations) { + combination.add(limitUsageList.get(0)); + } + } else { + // We have to duplicate each of the current combinations for each element of limitUsageList + List<List<LimitUsage>> newAllCombinations = new ArrayList<>(); + for (List<LimitUsage> combination : allCombinations) { + for (LimitUsage limitUsage : limitUsageList) { + List<LimitUsage> newCombination = new ArrayList<>(combination); + newCombination.add(limitUsage); + newAllCombinations.add(newCombination); + } + } + allCombinations = newAllCombinations; + } + } + } + + // Now, go through all combinations and calculate its usage, get the maximum + long maxUsage = 0; + for (List<LimitUsage> combination : allCombinations) { + long usage = calculateUsage(combination); + if (usage > maxUsage) { + maxUsage = usage; + } + } + + long t2 = System.currentTimeMillis(); + if (logit) { + log.debug(rn + ": Calculating usage completed:"); + log.debug(rn + ": Regular changes: " + regularChangeCount); + log.debug(rn + ": Significant changes: " + significantChangeCount); + log.debug(rn + ": Combinations: " + allCombinations.size()); + log.debug(rn + ": Usage: " + maxUsage); + log.debug(rn + ": Time: " + (t2 - t1)); + } + + return maxUsage; + } + + private static boolean addLimitUsage( + Map<String/* resourceUnionId */, List<LimitUsage>> limitUsageMap, + String resourceUnionId, + Set<String> resourceShareGroupList, + long used) { + List<LimitUsage> limitUsageList = limitUsageMap.get(resourceUnionId); + if (limitUsageList == null) { + limitUsageList = new ArrayList<>(); + limitUsageMap.put(resourceUnionId, limitUsageList); + } + // See if we already have the same shareResourceUnionSet in the list. In such case just update the usage + // to the bigger value. + LimitUsage limitUsage = null; + for (LimitUsage limitUsage1 : limitUsageList) { + if ((limitUsage1.resourceShareGroupList == null || limitUsage1.resourceShareGroupList.isEmpty()) && + (resourceShareGroupList == null || resourceShareGroupList.isEmpty())) { + limitUsage = limitUsage1; + break; + } + if (limitUsage1.resourceShareGroupList != null && + limitUsage1.resourceShareGroupList.equals(resourceShareGroupList)) { + limitUsage = limitUsage1; + break; + } + } + if (limitUsage != null) { + if (limitUsage.usage < used) { + limitUsage.usage = used; + } + return true; + } + + limitUsage = new LimitUsage(); + limitUsage.resourceUnion = resourceUnionId; + limitUsage.resourceShareGroupList = resourceShareGroupList; + limitUsage.usage = used; + limitUsageList.add(limitUsage); + return false; + } + + private static class LimitUsage { + + @SuppressWarnings("unused") + public String resourceUnion; + public Set<String> resourceShareGroupList; + public long usage; + } + + private static boolean hasCommonSharedResource(LimitUsage limitUsage1, LimitUsage limitUsage2) { + if (limitUsage1.resourceShareGroupList == null || limitUsage1.resourceShareGroupList.isEmpty()) { + return false; + } + if (limitUsage2.resourceShareGroupList == null || limitUsage2.resourceShareGroupList.isEmpty()) { + return false; + } + + for (String resourceUnion : limitUsage1.resourceShareGroupList) { + if (limitUsage2.resourceShareGroupList.contains(resourceUnion)) { + return true; + } + } + + return false; + } + + private static long calculateUsage(List<LimitUsage> combination) { + // All LimitUsage objects that have a common value in their sharedResourceUnionSet reuse the resource, so + // split the combination in sets that have common value. Then the usage of each set will be the maximum of + // the usages of the LimitUsage objects in the set. The usage of the combination will be the sum of the usages + // of all sets. + List<List<LimitUsage>> sharedSets = new ArrayList<>(); + for (LimitUsage limitUsage : combination) { + // See if we can put limitUsage in any of the existing sets - is it has a common resource union with + // any of the LimitUsage objects in a set. + boolean found = false; + for (List<LimitUsage> sharedSet : sharedSets) { + for (LimitUsage limitUsage1 : sharedSet) { + if (hasCommonSharedResource(limitUsage, limitUsage1)) { + found = true; + break; + } + } + if (found) { + sharedSet.add(limitUsage); + break; + } + } + if (!found) { + // Start a new set + List<LimitUsage> newSharedSet = new ArrayList<>(); + newSharedSet.add(limitUsage); + sharedSets.add(newSharedSet); + } + } + + long sum = 0; + for (List<LimitUsage> sharedSet : sharedSets) { + float max = 0; + for (LimitUsage limitUsage : sharedSet) { + if (max < limitUsage.usage) { + max = limitUsage.usage; + } + } + sum += max; + } + + return sum; + } + + public static long allocateLimit(LimitResource l, LimitAllocationRequest req) { + if (req.allocateCount <= 0) { + return 0; + } + long uu = l.used; + + LimitAllocationItem lai = (LimitAllocationItem) ResourceUtil.getAllocationItem(l, req.resourceSetId); + if (lai == null) { + lai = new LimitAllocationItem(); + lai.resourceType = ResourceType.Limit; + lai.resourceKey = new ResourceKey(); + lai.resourceKey.assetId = req.assetId; + lai.resourceKey.resourceName = req.resourceName; + lai.applicationId = req.applicationId; + lai.resourceSetId = req.resourceSetId; + lai.resourceUnionId = req.resourceUnionId; + lai.resourceShareGroupList = req.resourceShareGroupList; + lai.used = req.allocateCount; + + if (l.allocationItems == null) { + l.allocationItems = new ArrayList<>(); + } + l.allocationItems.add(lai); + } else { + lai.used = req.replace ? req.allocateCount : lai.used + req.allocateCount; + } + + lai.allocationTime = new Date(); + + recalculate(l); + + return l.used - uu; + } + + public static void recalculate(LimitResource l) { + l.used = calculateLimitUsage(l, 0, null, null); + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/RangeUtil.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/RangeUtil.java new file mode 100644 index 000000000..2e378f1aa --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/RangeUtil.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.util; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.Range; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeResource; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceKey; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; + +public class RangeUtil { + + public static void recalculate(RangeResource r) { + r.used = new TreeSet<>(); + if (r.allocationItems != null) { + for (AllocationItem ai : r.allocationItems) { + RangeAllocationItem rai = (RangeAllocationItem) ai; + if (rai.used != null) { + r.used.addAll(rai.used); + } + } + } + } + + public static boolean checkRange(RangeResource r, RangeAllocationRequest req, int num) { + if (req.excludeNumbers != null && req.excludeNumbers.contains(num)) { + return false; + } + + if (req.rangeList != null && !req.rangeList.isEmpty()) { + boolean good = false; + for (Range range : req.rangeList) { + if (num < range.min || num > range.max) { + continue; + } + + boolean found = false; + if (r.allocationItems != null) { + for (AllocationItem ai : r.allocationItems) { + RangeAllocationItem rai = (RangeAllocationItem) ai; + if (!eq(req.resourceUnionId, rai.resourceUnionId) && rai.used != null + && rai.used.contains(num)) { + if (!overlap(rai.resourceShareGroupList, req.resourceShareGroupList)) { + found = true; + break; + } + } + if (!req.replace && eq(req.resourceSetId, rai.resourceSetId) && rai.used != null + && rai.used.contains(num)) { + found = true; + break; + } + if (req.forceNewNumbers && rai.used.contains(num)) { + found = true; + break; + } + } + } + + if (!found) { + good = true; + break; + } + } + + return good; + } + + return true; + } + + public static SortedSet<Integer> getUsed(RangeResource r, String resourceUnionId) { + SortedSet<Integer> used = new TreeSet<>(); + if (r.allocationItems != null) { + for (AllocationItem ai : r.allocationItems) { + RangeAllocationItem rai = (RangeAllocationItem) ai; + if (eq(resourceUnionId, rai.resourceUnionId) && rai.used != null) { + used.addAll(rai.used); + } + } + } + return used; + } + + public static void allocateRange(RangeResource rr, SortedSet<Integer> requestedNumbers, + RangeAllocationRequest req) { + if (!req.allocate) { + return; + } + + RangeAllocationItem rai = (RangeAllocationItem) ResourceUtil.getAllocationItem(rr, req.resourceSetId); + if (rai == null) { + rai = new RangeAllocationItem(); + rai.resourceType = ResourceType.Range; + rai.resourceKey = new ResourceKey(); + rai.resourceKey.assetId = req.assetId; + rai.resourceKey.resourceName = req.resourceName; + rai.applicationId = req.applicationId; + rai.resourceSetId = req.resourceSetId; + rai.resourceUnionId = req.resourceUnionId; + rai.resourceShareGroupList = req.resourceShareGroupList; + rai.used = requestedNumbers; + + if (rr.allocationItems == null) { + rr.allocationItems = new ArrayList<>(); + } + rr.allocationItems.add(rai); + } else if (req.replace) { + rai.used = requestedNumbers; + } else { + rai.used.addAll(requestedNumbers); + } + + rai.allocationTime = new Date(); + + recalculate(rr); + } + + private static boolean eq(Object o1, Object o2) { + return o1 == null ? o2 == null : o1.equals(o2); + } + + private static boolean overlap(Set<String> s1, Set<String> s2) { + if (s1 == null || s1.isEmpty() || s2 == null || s2.isEmpty()) { + return false; + } + for (String ss1 : s1) { + if (s2.contains(ss1)) { + return true; + } + } + return false; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/ResourceUtil.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/ResourceUtil.java new file mode 100644 index 000000000..3db63804b --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/rm/util/ResourceUtil.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.rm.util; + +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelResource; +import org.onap.ccsdk.sli.adaptors.rm.data.LimitResource; +import org.onap.ccsdk.sli.adaptors.rm.data.RangeResource; +import org.onap.ccsdk.sli.adaptors.rm.data.Resource; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; + +public class ResourceUtil { + + public static AllocationItem getAllocationItem(Resource r, String resourceSetId) { + if (r.allocationItems != null) { + for (AllocationItem ai : r.allocationItems) { + if (ai.resourceSetId != null && ai.resourceSetId.equals(resourceSetId)) { + return ai; + } + } + } + return null; + } + + public static void recalculate(Resource r) { + if (r == null) { + return; + } + + if (r.resourceType == ResourceType.Limit) { + LimitUtil.recalculate((LimitResource) r); + } else if (r.resourceType == ResourceType.Range) { + RangeUtil.recalculate((RangeResource) r); + } else if (r.resourceType == ResourceType.Label) { + LabelUtil.recalculate((LabelResource) r); + } + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/db/CachedDataSourceWrap.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/db/CachedDataSourceWrap.java new file mode 100644 index 000000000..3fa3952f2 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/db/CachedDataSourceWrap.java @@ -0,0 +1,156 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.util.db; + +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CachedDataSourceWrap implements DataSource { + + private static final Logger log = LoggerFactory.getLogger(CachedDataSourceWrap.class); + + private ThreadLocal<ConnectionWrap> con = new ThreadLocal<>(); + private ThreadLocal<Boolean> autoCommit = new ThreadLocal<>(); + + private DataSource dataSource; + + @Override + public PrintWriter getLogWriter() throws SQLException { + return dataSource.getLogWriter(); + } + + @Override + public void setLogWriter(PrintWriter out) throws SQLException { + dataSource.setLogWriter(out); + } + + @Override + public void setLoginTimeout(int seconds) throws SQLException { + dataSource.setLoginTimeout(seconds); + } + + @Override + public int getLoginTimeout() throws SQLException { + return dataSource.getLoginTimeout(); + } + + @Override + public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { + return dataSource.getParentLogger(); + } + + @Override + public <T> T unwrap(Class<T> iface) throws SQLException { + return dataSource.unwrap(iface); + } + + @Override + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return dataSource.isWrapperFor(iface); + } + + @Override + public Connection getConnection() throws SQLException { + if (con.get() == null) { + Connection c = dataSource.getConnection(); + + ConnectionWrap cc = new ConnectionWrap(c); + con.set(cc); + + autoCommit.set(c.getAutoCommit()); + c.setAutoCommit(false); + + log.info("Got new DB connection: " + c); + } else { + log.info("Using thread DB connection: " + con.get().getCon()); + } + + return con.get(); + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + if (con.get() == null) { + Connection c = dataSource.getConnection(username, password); + + ConnectionWrap cc = new ConnectionWrap(c); + con.set(cc); + + autoCommit.set(c.getAutoCommit()); + c.setAutoCommit(false); + + log.info("Got new DB connection: " + c); + } else { + log.info("Using thread DB connection: " + con.get().getCon()); + } + + return con.get(); + } + + public void releaseConnection() { + if (con.get() != null) { + try { + con.get().setAutoCommit(autoCommit.get()); + con.get().realClose(); + + log.info("DB Connection released: " + con.get().getCon()); + } catch (SQLException e) { + log.warn("Failed to release DB connection", e); + } finally { + con.remove(); + } + } + } + + public void commit() { + if (con.get() != null) { + try { + con.get().commit(); + + log.info("DB Connection committed: " + con.get().getCon()); + } catch (Exception e) { + log.warn("Failed to commit DB connection", e); + } + } + } + + public void rollback() { + if (con.get() != null) { + try { + con.get().rollback(); + + log.info("DB Connection rolled back: " + con.get().getCon()); + } catch (Exception e) { + log.warn("Failed to roll back DB connection", e); + } + } + } + + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/db/ConnectionWrap.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/db/ConnectionWrap.java new file mode 100644 index 000000000..7d2554806 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/db/ConnectionWrap.java @@ -0,0 +1,338 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.util.db; + +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.NClob; +import java.sql.PreparedStatement; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Savepoint; +import java.sql.Statement; +import java.sql.Struct; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executor; + +public class ConnectionWrap implements Connection { + + private Connection cc; + + public ConnectionWrap(Connection cc) { + super(); + this.cc = cc; + } + + public Connection getCon() { + return cc; + } + + public void realClose() throws SQLException { + cc.close(); + } + + @Override + public <T> T unwrap(Class<T> iface) throws SQLException { + return cc.unwrap(iface); + } + + @Override + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return cc.isWrapperFor(iface); + } + + @Override + public Statement createStatement() throws SQLException { + return cc.createStatement(); + } + + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException { + return cc.prepareStatement(sql); + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + return cc.prepareCall(sql); + } + + @Override + public String nativeSQL(String sql) throws SQLException { + return cc.nativeSQL(sql); + } + + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException { + cc.setAutoCommit(autoCommit); + } + + @Override + public boolean getAutoCommit() throws SQLException { + return cc.getAutoCommit(); + } + + @Override + public void commit() throws SQLException { + cc.commit(); + } + + @Override + public void rollback() throws SQLException { + cc.rollback(); + } + + @Override + public void close() throws SQLException { + } + + @Override + public boolean isClosed() throws SQLException { + return cc.isClosed(); + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + return cc.getMetaData(); + } + + @Override + public void setReadOnly(boolean readOnly) throws SQLException { + cc.setReadOnly(readOnly); + } + + @Override + public boolean isReadOnly() throws SQLException { + return cc.isReadOnly(); + } + + @Override + public void setCatalog(String catalog) throws SQLException { + cc.setCatalog(catalog); + } + + @Override + public String getCatalog() throws SQLException { + return cc.getCatalog(); + } + + @Override + public void setTransactionIsolation(int level) throws SQLException { + cc.setTransactionIsolation(level); + } + + @Override + public int getTransactionIsolation() throws SQLException { + return cc.getTransactionIsolation(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return cc.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + cc.clearWarnings(); + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { + return cc.createStatement(resultSetType, resultSetConcurrency); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) + throws SQLException { + return cc.prepareStatement(sql, resultSetType, resultSetConcurrency); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return cc.prepareCall(sql, resultSetType, resultSetConcurrency); + } + + @Override + public Map<String, Class<?>> getTypeMap() throws SQLException { + return cc.getTypeMap(); + } + + @Override + public void setTypeMap(Map<String, Class<?>> map) throws SQLException { + cc.setTypeMap(map); + } + + @Override + public void setHoldability(int holdability) throws SQLException { + cc.setHoldability(holdability); + } + + @Override + public int getHoldability() throws SQLException { + return cc.getHoldability(); + } + + @Override + public Savepoint setSavepoint() throws SQLException { + return cc.setSavepoint(); + } + + @Override + public Savepoint setSavepoint(String name) throws SQLException { + return cc.setSavepoint(name); + } + + @Override + public void rollback(Savepoint savepoint) throws SQLException { + cc.rollback(savepoint); + } + + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + cc.releaseSavepoint(savepoint); + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) + throws SQLException { + return cc.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement( + String sql, + int resultSetType, + int resultSetConcurrency, + int resultSetHoldability) throws SQLException { + return cc.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public CallableStatement prepareCall( + String sql, + int resultSetType, + int resultSetConcurrency, + int resultSetHoldability) throws SQLException { + return cc.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { + return cc.prepareStatement(sql, autoGeneratedKeys); + } + + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { + return cc.prepareStatement(sql, columnIndexes); + } + + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { + return cc.prepareStatement(sql, columnNames); + } + + @Override + public Clob createClob() throws SQLException { + return cc.createClob(); + } + + @Override + public Blob createBlob() throws SQLException { + return cc.createBlob(); + } + + @Override + public NClob createNClob() throws SQLException { + return cc.createNClob(); + } + + @Override + public SQLXML createSQLXML() throws SQLException { + return cc.createSQLXML(); + } + + @Override + public boolean isValid(int timeout) throws SQLException { + return cc.isValid(timeout); + } + + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException { + cc.setClientInfo(name, value); + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + cc.setClientInfo(properties); + } + + @Override + public String getClientInfo(String name) throws SQLException { + return cc.getClientInfo(name); + } + + @Override + public Properties getClientInfo() throws SQLException { + return cc.getClientInfo(); + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + return cc.createArrayOf(typeName, elements); + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + return cc.createStruct(typeName, attributes); + } + + @Override + public void setSchema(String schema) throws SQLException { + cc.setSchema(schema); + } + + @Override + public String getSchema() throws SQLException { + return cc.getSchema(); + } + + @Override + public void abort(Executor executor) throws SQLException { + cc.abort(executor); + } + + @Override + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { + cc.setNetworkTimeout(executor, milliseconds); + } + + @Override + public int getNetworkTimeout() throws SQLException { + return cc.getNetworkTimeout(); + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/db/DataSourceWrap.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/db/DataSourceWrap.java new file mode 100644 index 000000000..2aebb83e3 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/db/DataSourceWrap.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.util.db; + +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; + +import javax.sql.DataSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DataSourceWrap implements DataSource { + + private static final Logger log = LoggerFactory.getLogger(DataSourceWrap.class); + + private DataSource dataSource; + + @Override + public PrintWriter getLogWriter() throws SQLException { + return dataSource.getLogWriter(); + } + + @Override + public void setLogWriter(PrintWriter out) throws SQLException { + dataSource.setLogWriter(out); + } + + @Override + public void setLoginTimeout(int seconds) throws SQLException { + dataSource.setLoginTimeout(seconds); + } + + @Override + public int getLoginTimeout() throws SQLException { + return dataSource.getLoginTimeout(); + } + + @Override + public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { + return dataSource.getParentLogger(); + } + + @Override + public <T> T unwrap(Class<T> iface) throws SQLException { + return dataSource.unwrap(iface); + } + + @Override + public boolean isWrapperFor(Class<?> iface) throws SQLException { + return dataSource.isWrapperFor(iface); + } + + @Override + public Connection getConnection() throws SQLException { + Connection c = dataSource.getConnection(); + + log.debug("getConnection: " + c.getClass().getName()); + + c.setAutoCommit(true); + return c; + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + Connection c = dataSource.getConnection(username, password); + + log.debug("getConnection: " + c.getClass().getName()); + + c.setAutoCommit(true); + return c; + } + + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/expr/ExpressionEvaluator.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/expr/ExpressionEvaluator.java new file mode 100644 index 000000000..8092a7515 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/expr/ExpressionEvaluator.java @@ -0,0 +1,271 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.util.expr; + +import java.util.Map; + +public class ExpressionEvaluator { + + public static long evalLong(String expr, Map<String, String> vars) { + return (long) evalFloat(expr, vars); + } + + public static float evalFloat(String expr, Map<String, String> vars) { + expr = expr.trim(); + int sl = expr.length(); + if (sl == 0) { + throw new IllegalArgumentException("Cannot interpret empty string."); + } + + // Remove parentheses if any + if (expr.charAt(0) == '(' && expr.charAt(sl - 1) == ')') { + return evalFloat(expr.substring(1, sl - 1), vars); + } + + // Look for operators in the order of least priority + String[] sss = findOperator(expr, "-", true); + if (sss != null) { + return evalFloat(sss[0], vars) - evalFloat(sss[1], vars); + } + + sss = findOperator(expr, "+", true); + if (sss != null) { + return evalFloat(sss[0], vars) + evalFloat(sss[1], vars); + } + + sss = findOperator(expr, "/", true); + if (sss != null) { + return evalFloat(sss[0], vars) / evalFloat(sss[1], vars); + } + + sss = findOperator(expr, "*", true); + if (sss != null) { + return evalFloat(sss[0], vars) * evalFloat(sss[1], vars); + } + + // Check if expr is a number + try { + return Float.valueOf(expr); + } catch (Exception e) { + } + + // Must be a variable + String v = vars.get(expr); + try { + return Float.valueOf(v); + } catch (Exception e) { + } + return 0; + } + + public static String evalString(String expr, Map<String, String> vars) { + expr = expr.trim(); + int sl = expr.length(); + if (sl == 0) { + throw new IllegalArgumentException("Cannot interpret empty string."); + } + + // Remove parentheses if any + if (expr.charAt(0) == '(' && expr.charAt(sl - 1) == ')') { + return evalString(expr.substring(1, sl - 1), vars); + } + + // Look for operators in the order of least priority + String[] sss = findOperator(expr, "+", true); + if (sss != null) { + return evalString(sss[0], vars) + evalString(sss[1], vars); + } + + // Check if expr is a number + try { + return Float.valueOf(expr).toString(); + } catch (Exception e) { + } + + // Check for quotes + if (expr.charAt(0) == '"' && expr.charAt(sl - 1) == '"') { + return expr.substring(1, sl - 1); + } + if (expr.charAt(0) == '\'' && expr.charAt(sl - 1) == '\'') { + return expr.substring(1, sl - 1); + } + + // Must be a variable + String v = vars.get(expr); + return v != null ? v : ""; + } + + public static boolean evalBoolean(String expr, Map<String, String> vars) { + expr = expr.trim(); + int sl = expr.length(); + if (sl == 0) { + throw new IllegalArgumentException("Cannot interpret empty string."); + } + + if (expr.equalsIgnoreCase("true")) { + return true; + } + + if (expr.equalsIgnoreCase("false")) { + return false; + } + + // Remove parentheses if any + if (expr.charAt(0) == '(' && expr.charAt(sl - 1) == ')') { + return evalBoolean(expr.substring(1, sl - 1), vars); + } + + // Look for operators in the order of least priority + String[] sss = findOperator(expr, "or", true); + if (sss != null) { + return evalBoolean(sss[0], vars) || evalBoolean(sss[1], vars); + } + + sss = findOperator(expr, "and", true); + if (sss != null) { + return evalBoolean(sss[0], vars) && evalBoolean(sss[1], vars); + } + + sss = findOperator(expr, "not", true); + if (sss != null) { + return !evalBoolean(sss[1], vars); + } + + sss = findOperator(expr, "!=", false); + if (sss == null) { + sss = findOperator(expr, "<>", false); + } + if (sss != null) { + return !evalString(sss[0], vars).equals(evalString(sss[1], vars)); + } + + sss = findOperator(expr, "==", false); + if (sss == null) { + sss = findOperator(expr, "=", false); + } + if (sss != null) { + return evalString(sss[0], vars).equals(evalString(sss[1], vars)); + } + + sss = findOperator(expr, ">=", false); + if (sss != null) { + return evalLong(sss[0], vars) >= evalLong(sss[1], vars); + } + + sss = findOperator(expr, ">", false); + if (sss != null) { + return evalLong(sss[0], vars) > evalLong(sss[1], vars); + } + + sss = findOperator(expr, "<=", false); + if (sss != null) { + return evalLong(sss[0], vars) <= evalLong(sss[1], vars); + } + + sss = findOperator(expr, "<", false); + if (sss != null) { + return evalLong(sss[0], vars) < evalLong(sss[1], vars); + } + + throw new IllegalArgumentException("Cannot interpret '" + expr + "': Invalid expression."); + } + + private static String[] findOperator(String s, String op, boolean delimiterRequired) { + int opl = op.length(); + int sl = s.length(); + String delimiters = " \0\t\r\n()"; + int pcount = 0; + int qcount = 0; + for (int i = 0; i < sl; i++) { + char c = s.charAt(i); + if (c == '(' && qcount == 0) { + pcount++; + } else if (c == ')' && qcount == 0) { + pcount--; + if (pcount < 0) { + throw new IllegalArgumentException("Cannot interpret '" + s + "': Parentheses do not match."); + } + } else if (c == '\'') { + qcount = (qcount + 1) % 2; + } else if (i <= sl - opl && pcount == 0 && qcount == 0) { + String ss = s.substring(i, i + opl); + if (ss.equalsIgnoreCase(op)) { + boolean found = true; + if (delimiterRequired) { + // Check for delimiter before and after to make sure it is not part of another word + char chbefore = '\0'; + if (i > 0) { + chbefore = s.charAt(i - 1); + } + char chafter = '\0'; + if (i < sl - opl) { + chafter = s.charAt(i + opl); + } + found = delimiters.indexOf(chbefore) >= 0 && delimiters.indexOf(chafter) >= 0; + } + if (found) { + // We've found the operator, split the string + String[] sss = new String[2]; + sss[0] = s.substring(0, i); + sss[1] = s.substring(i + opl); + return sss; + } + } + } + } + if (pcount > 0) { + throw new IllegalArgumentException("Cannot interpret '" + s + "': Parentheses do not match."); + } + if (qcount > 0) { + throw new IllegalArgumentException("Cannot interpret '" + s + "': No closing '."); + } + return null; + } + + @SuppressWarnings("unused") + private static Object parseObject(String s) { + s = s.trim(); + int sl = s.length(); + if (sl == 0) { + throw new IllegalArgumentException("Cannot interpret empty string."); + } + if (s.equalsIgnoreCase("null")) { + return null; + } + if (s.charAt(0) == '\'') { + if (sl < 2 || s.charAt(sl - 1) != '\'') { + throw new IllegalArgumentException("Cannot interpret '" + s + "': No closing '."); + } + return s.substring(1, sl - 1); + } + // Not in quotes - must be a number + try { + return Long.valueOf(s); + } catch (Exception e) { + } + try { + return Double.valueOf(s); + } catch (Exception e) { + throw new IllegalArgumentException("Cannot interpret '" + s + "': Invalid number."); + } + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/speed/SpeedUtil.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/speed/SpeedUtil.java new file mode 100644 index 000000000..0d1359cf3 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/speed/SpeedUtil.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.util.speed; + +public class SpeedUtil { + + private long unitFactor = 1000; + + public long convertToKbps(long maxSpeed, String unit) { + if (unit.equalsIgnoreCase("kbps")) { + return maxSpeed; + } + if (unit.equalsIgnoreCase("Mbps")) { + return maxSpeed * unitFactor; + } + if (unit.equalsIgnoreCase("Gbps")) { + return maxSpeed * unitFactor * unitFactor; + } + return 0; + } + + public long convertToMbps(long maxSpeed, String unit) { + if (unit.equalsIgnoreCase("kbps")) { + return maxSpeed / unitFactor; + } + if (unit.equalsIgnoreCase("Mbps")) { + return maxSpeed; + } + if (unit.equalsIgnoreCase("Gbps")) { + return maxSpeed * unitFactor; + } + return 0; + } + + public void setUnitFactor(long unitFactor) { + this.unitFactor = unitFactor; + } +} diff --git a/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/str/StrUtil.java b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/str/StrUtil.java new file mode 100644 index 000000000..126ec94e5 --- /dev/null +++ b/resource-assignment/provider/src/main/java/org/onap/ccsdk/sli/adaptors/util/str/StrUtil.java @@ -0,0 +1,306 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.util.str; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StrUtil { + + private static final Logger log = LoggerFactory.getLogger(StrUtil.class); + + public static final String INDENT_STR = " "; + + public static void indent(StringBuilder ss, int ind) { + for (int i = 0; i < ind; i++) + ss.append(INDENT_STR); + } + + public static void info(Logger log, Object o) { + if (log.isInfoEnabled()) { + StringBuilder ss = new StringBuilder(); + struct(ss, o); + log.info(ss.toString()); + } + } + + public static void debug(Logger log, Object o) { + if (log.isDebugEnabled()) { + StringBuilder ss = new StringBuilder(); + struct(ss, o); + log.debug(ss.toString()); + } + } + + public static void struct(StringBuilder ss, Object o) { + struct(ss, o, 0); + } + + public static void struct(StringBuilder ss, Object o, int ind) { + if (o == null) { + ss.append("null"); + return; + } + + if (isSimple(o)) { + ss.append(o); + return; + } + + Class<? extends Object> cls = o.getClass(); + + if (cls.isEnum()) { + ss.append(o); + return; + } + + if (cls.isArray()) { + int n = Array.getLength(o); + if (n == 0) { + ss.append("[]"); + return; + } + + Object o1 = Array.get(o, 0); + if (isSimple(o1)) { + ss.append('[').append(o1); + for (int i = 1; i < n; i++) { + o1 = Array.get(o, i); + ss.append(", ").append(o1); + } + ss.append(']'); + return; + } + + ss.append('\n'); + indent(ss, ind + 1); + ss.append('['); + struct(ss, o1, ind + 1); + for (int i = 1; i < n; i++) { + o1 = Array.get(o, i); + struct(ss, o1, ind + 1); + } + ss.append('\n'); + indent(ss, ind + 1); + ss.append(']'); + return; + } + + if (o instanceof Collection<?>) { + Collection<?> ll = (Collection<?>) o; + + int n = ll.size(); + if (n == 0) { + ss.append("[]"); + return; + } + + Iterator<?> ii = ll.iterator(); + Object o1 = ii.next(); + if (isSimple(o1)) { + ss.append('[').append(o1); + while (ii.hasNext()) { + o1 = ii.next(); + ss.append(", ").append(o1); + } + ss.append(']'); + return; + } + + ss.append('\n'); + indent(ss, ind + 1); + ss.append('['); + struct(ss, o1, ind + 1); + while (ii.hasNext()) { + o1 = ii.next(); + struct(ss, o1, ind + 1); + } + ss.append('\n'); + indent(ss, ind + 1); + ss.append(']'); + return; + + } + + if (o instanceof Map<?, ?>) { + Map<?, ?> mm = (Map<?, ?>) o; + + int n = mm.size(); + if (n == 0) { + ss.append("{}"); + return; + } + + ss.append('{'); + + for (Object k : mm.keySet()) { + ss.append('\n'); + indent(ss, ind + 1); + ss.append(k).append(": "); + + Object o1 = mm.get(k); + struct(ss, o1, ind + 2); + } + + ss.append('\n'); + indent(ss, ind); + ss.append('}'); + + return; + } + + Field[] fields = cls.getFields(); + + if (fields.length == 0) { + ss.append(o); + return; + } + + ss.append('\n'); + indent(ss, ind + 1); + ss.append('<').append(cls.getSimpleName()).append("> {"); + for (Field f : fields) { + ss.append('\n'); + indent(ss, ind + 2); + ss.append(f.getName()).append(": "); + Object v = null; + try { + v = f.get(o); + } catch (IllegalAccessException e) { + v = "*** Cannot obtain value *** : " + e.getMessage(); + } + struct(ss, v, ind + 2); + } + ss.append('\n'); + indent(ss, ind + 1); + ss.append('}'); + } + + public static SortedSet<Integer> listInt(String ss, String warning) { + if (ss == null || ss.length() == 0) + return null; + + SortedSet<Integer> ll = new TreeSet<Integer>(); + String[] str = ss.split(","); + for (String s : str) { + try { + int i1 = s.indexOf('-'); + int start; + int end; + if (i1 > 0) { + String s1 = s.substring(0, i1); + String s2 = s.substring(i1 + 1); + start = Integer.parseInt(s1); + end = Integer.parseInt(s2); + } else + start = end = Integer.parseInt(s); + for (int i = start; i <= end; i++) + ll.add(i); + } catch (NumberFormatException e) { + // Skip this - bad data in DB + log.warn(warning + " [" + s + "].", e); + } + } + return ll; + } + + public static String listInt(SortedSet<Integer> ll) { + if (ll == null || ll.size() == 0) + return null; + + StringBuilder sb = new StringBuilder(2000); + Iterator<Integer> i = ll.iterator(); + int n = i.next(); + int start = n; + int end = n; + boolean first = true; + while (i.hasNext()) { + n = i.next(); + if (n != end + 1) { + if (!first) + sb.append(','); + first = false; + + if (start == end) + sb.append(start); + else if (start == end - 1) + sb.append(start).append(',').append(end); + else + sb.append(start).append('-').append(end); + + start = n; + } + end = n; + } + + if (!first) + sb.append(','); + + if (start == end) + sb.append(start); + else if (start == end - 1) + sb.append(start).append(',').append(end); + else + sb.append(start).append('-').append(end); + + return sb.toString(); + } + + public static List<String> listStr(String s) { + if (s == null || s.length() == 0) + return null; + String[] ss = s.split(","); + return Arrays.asList(ss); + } + + public static String listStr(Collection<String> ll) { + if (ll == null || ll.isEmpty()) + return null; + StringBuilder ss = new StringBuilder(1000); + Iterator<String> i = ll.iterator(); + ss.append(i.next()); + while (i.hasNext()) + ss.append(',').append(i.next()); + return ss.toString(); + } + + private static boolean isSimple(Object o) { + if (o == null) + return true; + + if (o instanceof Number || o instanceof String || o instanceof Boolean || o instanceof Date) + return true; + + return false; + } +} diff --git a/resource-assignment/provider/src/main/resources/OSGI-INF/blueprint/resource-assignment-blueprint.xml b/resource-assignment/provider/src/main/resources/OSGI-INF/blueprint/resource-assignment-blueprint.xml new file mode 100755 index 000000000..77c316d2a --- /dev/null +++ b/resource-assignment/provider/src/main/resources/OSGI-INF/blueprint/resource-assignment-blueprint.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <reference id="dblib.dataSource" interface="javax.sql.DataSource" filter="(objectClass=org.onap.ccsdk.sli.core.dblib.DbLibService)"/> + + <service ref="resourceAllocator" interface="org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator"/> + + <service ref="resourceLockNode" interface="org.onap.ccsdk.sli.adaptors.ra.ResourceLockNode"/> + +</blueprint> diff --git a/resource-assignment/provider/src/main/resources/OSGI-INF/blueprint/resource-assignment.xml b/resource-assignment/provider/src/main/resources/OSGI-INF/blueprint/resource-assignment.xml new file mode 100755 index 000000000..7fcc70c54 --- /dev/null +++ b/resource-assignment/provider/src/main/resources/OSGI-INF/blueprint/resource-assignment.xml @@ -0,0 +1,129 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <!-- JDBC setup --> + + <bean id="rm.dataSource" class="org.onap.ccsdk.sli.adaptors.util.db.DataSourceWrap"> + <property name="dataSource" ref="dblib.dataSource" /> + </bean> + + <bean id="lock.dataSource" class="org.onap.ccsdk.sli.adaptors.util.db.CachedDataSourceWrap"> + <property name="dataSource" ref="rm.dataSource" /> + </bean> + + <bean id="rm.jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> + <property name="dataSource" ref="rm.dataSource" /> + </bean> + + <bean id="lock.jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> + <property name="dataSource" ref="lock.dataSource" /> + </bean> + + <!-- Resource Lock Configuration --> + + <bean id="resourceLockDao" class="org.onap.ccsdk.sli.adaptors.lock.dao.ResourceLockDaoImpl"> + <property name="jdbcTemplate" ref="lock.jdbcTemplate" /> + </bean> + + <bean id="lockHelper" class="org.onap.ccsdk.sli.adaptors.lock.comp.LockHelperImpl"> + <property name="resourceLockDao" ref="resourceLockDao" /> + <property name="retryCount" value="10" /> + <property name="lockWait" value="5" /> <!-- Seconds --> + </bean> + + <!-- RM Configuration --> + + <bean id="resourceJdbcDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.ResourceJdbcDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="allocationItemJdbcDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.AllocationItemJdbcDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="resourceLoadJdbcDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.ResourceLoadJdbcDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="resourceDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.ResourceDaoImpl"> + <property name="resourceJdbcDao" ref="resourceJdbcDao" /> + <property name="allocationItemJdbcDao" ref="allocationItemJdbcDao" /> + <property name="resourceLoadJdbcDao" ref="resourceLoadJdbcDao" /> + </bean> + + <bean id="resourceManager" class="org.onap.ccsdk.sli.adaptors.rm.comp.ResourceManagerImpl"> + <property name="lockHelper" ref="lockHelper" /> + <property name="resourceDao" ref="resourceDao" /> + <property name="lockTimeout" value="600" /> <!-- Seconds --> + </bean> + + <!-- Rule DAO Configuration --> + + <bean id="resourceRuleDao" class="org.onap.ccsdk.sli.adaptors.ra.rule.dao.ResourceRuleDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="rangeRuleDao" class="org.onap.ccsdk.sli.adaptors.ra.rule.dao.RangeRuleDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <!-- ResourceAllocator Configuration --> + + <bean id="resourceAllocator" class="org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator"> + <property name="resourceManager" ref="resourceManager" /> + <property name="endPointAllocator" ref="endPointAllocator" /> + <property name="speedUtil" ref="speedUtil" /> + </bean> + + <bean id="resourceLockNode" class="org.onap.ccsdk.sli.adaptors.ra.ResourceLockNode"> + <property name="lockHelper" ref="lockHelper" /> + </bean> + + <bean id="speedUtil" class="org.onap.ccsdk.sli.adaptors.util.speed.SpeedUtil" /> + + <!-- EndPointAllocator Configuration --> + + <bean id="endPointAllocator" class="org.onap.ccsdk.sli.adaptors.ra.comp.EndPointAllocatorImpl"> + <property name="resourceManager" ref="resourceManager" /> + <property name="allocationRuleMap"> + <map> + <entry key="DEFAULT"> + <list> + <ref component-id="dbAllocationRule" /> + </list> + </entry> + </map> + </property> + </bean> + + <!-- Resource Allocation Rule Configuration --> + + <bean id="dbAllocationRule" class="org.onap.ccsdk.sli.adaptors.ra.alloc.DbAllocationRule"> + <property name="resourceRuleDao" ref="resourceRuleDao" /> + <property name="rangeRuleDao" ref="rangeRuleDao" /> + </bean> + +</blueprint> diff --git a/resource-assignment/provider/src/main/resources/org/opendaylight/blueprint/resource-assignment-blueprint.xml b/resource-assignment/provider/src/main/resources/org/opendaylight/blueprint/resource-assignment-blueprint.xml new file mode 100755 index 000000000..77c316d2a --- /dev/null +++ b/resource-assignment/provider/src/main/resources/org/opendaylight/blueprint/resource-assignment-blueprint.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <reference id="dblib.dataSource" interface="javax.sql.DataSource" filter="(objectClass=org.onap.ccsdk.sli.core.dblib.DbLibService)"/> + + <service ref="resourceAllocator" interface="org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator"/> + + <service ref="resourceLockNode" interface="org.onap.ccsdk.sli.adaptors.ra.ResourceLockNode"/> + +</blueprint> diff --git a/resource-assignment/provider/src/main/resources/org/opendaylight/blueprint/resource-assignment.xml b/resource-assignment/provider/src/main/resources/org/opendaylight/blueprint/resource-assignment.xml new file mode 100755 index 000000000..7fcc70c54 --- /dev/null +++ b/resource-assignment/provider/src/main/resources/org/opendaylight/blueprint/resource-assignment.xml @@ -0,0 +1,129 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <!-- JDBC setup --> + + <bean id="rm.dataSource" class="org.onap.ccsdk.sli.adaptors.util.db.DataSourceWrap"> + <property name="dataSource" ref="dblib.dataSource" /> + </bean> + + <bean id="lock.dataSource" class="org.onap.ccsdk.sli.adaptors.util.db.CachedDataSourceWrap"> + <property name="dataSource" ref="rm.dataSource" /> + </bean> + + <bean id="rm.jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> + <property name="dataSource" ref="rm.dataSource" /> + </bean> + + <bean id="lock.jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> + <property name="dataSource" ref="lock.dataSource" /> + </bean> + + <!-- Resource Lock Configuration --> + + <bean id="resourceLockDao" class="org.onap.ccsdk.sli.adaptors.lock.dao.ResourceLockDaoImpl"> + <property name="jdbcTemplate" ref="lock.jdbcTemplate" /> + </bean> + + <bean id="lockHelper" class="org.onap.ccsdk.sli.adaptors.lock.comp.LockHelperImpl"> + <property name="resourceLockDao" ref="resourceLockDao" /> + <property name="retryCount" value="10" /> + <property name="lockWait" value="5" /> <!-- Seconds --> + </bean> + + <!-- RM Configuration --> + + <bean id="resourceJdbcDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.ResourceJdbcDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="allocationItemJdbcDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.AllocationItemJdbcDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="resourceLoadJdbcDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.ResourceLoadJdbcDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="resourceDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.ResourceDaoImpl"> + <property name="resourceJdbcDao" ref="resourceJdbcDao" /> + <property name="allocationItemJdbcDao" ref="allocationItemJdbcDao" /> + <property name="resourceLoadJdbcDao" ref="resourceLoadJdbcDao" /> + </bean> + + <bean id="resourceManager" class="org.onap.ccsdk.sli.adaptors.rm.comp.ResourceManagerImpl"> + <property name="lockHelper" ref="lockHelper" /> + <property name="resourceDao" ref="resourceDao" /> + <property name="lockTimeout" value="600" /> <!-- Seconds --> + </bean> + + <!-- Rule DAO Configuration --> + + <bean id="resourceRuleDao" class="org.onap.ccsdk.sli.adaptors.ra.rule.dao.ResourceRuleDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="rangeRuleDao" class="org.onap.ccsdk.sli.adaptors.ra.rule.dao.RangeRuleDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <!-- ResourceAllocator Configuration --> + + <bean id="resourceAllocator" class="org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator"> + <property name="resourceManager" ref="resourceManager" /> + <property name="endPointAllocator" ref="endPointAllocator" /> + <property name="speedUtil" ref="speedUtil" /> + </bean> + + <bean id="resourceLockNode" class="org.onap.ccsdk.sli.adaptors.ra.ResourceLockNode"> + <property name="lockHelper" ref="lockHelper" /> + </bean> + + <bean id="speedUtil" class="org.onap.ccsdk.sli.adaptors.util.speed.SpeedUtil" /> + + <!-- EndPointAllocator Configuration --> + + <bean id="endPointAllocator" class="org.onap.ccsdk.sli.adaptors.ra.comp.EndPointAllocatorImpl"> + <property name="resourceManager" ref="resourceManager" /> + <property name="allocationRuleMap"> + <map> + <entry key="DEFAULT"> + <list> + <ref component-id="dbAllocationRule" /> + </list> + </entry> + </map> + </property> + </bean> + + <!-- Resource Allocation Rule Configuration --> + + <bean id="dbAllocationRule" class="org.onap.ccsdk.sli.adaptors.ra.alloc.DbAllocationRule"> + <property name="resourceRuleDao" ref="resourceRuleDao" /> + <property name="rangeRuleDao" ref="rangeRuleDao" /> + </bean> + +</blueprint> diff --git a/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/DataSetup.java b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/DataSetup.java new file mode 100644 index 000000000..9aa3f26c4 --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/DataSetup.java @@ -0,0 +1,108 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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 jtest.org.onap.ccsdk.sli.adaptors.ra; + +import java.util.Date; +import jtest.util.org.onap.ccsdk.sli.adaptors.ra.TestDb; +import jtest.util.org.onap.ccsdk.sli.adaptors.ra.TestTable; + +public class DataSetup { + + private TestDb testDb; + + private TestTable resource = null; + private TestTable allocationItem = null; + + private static final String[] RESOURCE_COLUMNS = + {"asset_id", "resource_name", "resource_type", "lt_used", "rr_used"}; + + private static final String[] ALLOCATION_ITEM_COLUMNS = {"resource_id", "application_id", "resource_set_id", + "resource_union_id", "resource_share_group_list", "lt_used", "rr_used", "allocation_time"}; + + private void initTables() { + if (resource == null) { + resource = testDb.table("RESOURCE", "resource_id", RESOURCE_COLUMNS); + } + if (allocationItem == null) { + allocationItem = testDb.table("ALLOCATION_ITEM", "allocation_item_id", ALLOCATION_ITEM_COLUMNS); + } + } + + public void cleanup() { + initTables(); + allocationItem.delete("true"); + resource.delete("true"); + } + + public void setupLimitItem(String resourceName, String assetId, String resourceSetId, String resourceUnionId, + long used) { + initTables(); + + Long rid = resource.getId("asset_id = '" + assetId + "' AND resource_name = '" + resourceName + "'"); + if (rid == null) { + resource.add(assetId, resourceName, "Limit", used, null); + rid = resource.getLastId(); + } + allocationItem.add(rid, "SDNC", resourceSetId, resourceUnionId, null, used, null, new Date()); + } + + public void setupRangeItem(String resourceName, String assetId, String resourceSetId, String resourceUnionId, + String resourceShareGroup, String used) { + initTables(); + + Long rid = resource.getId("asset_id = '" + assetId + "' AND resource_name = '" + resourceName + "'"); + if (rid == null) { + resource.add(assetId, resourceName, "Range", null, used); + rid = resource.getLastId(); + } + allocationItem.add(rid, "SDNC", resourceSetId, resourceUnionId, resourceShareGroup, null, used, new Date()); + } + + public void setupRangeItem(String resourceName, String assetId, String resourceSetId, String resourceUnionId, + String used) { + setupRangeItem(resourceName, assetId, resourceSetId, resourceUnionId, null, used); + } + + public boolean checkRangeItem(String resourceName, String assetId, String resourceSetId, String used) { + String where = "resource_id = (SELECT resource_id FROM RESOURCE WHERE resource_name = '" + resourceName + + "' AND asset_id = '" + assetId + "') AND resource_set_id = '" + resourceSetId + "'"; + Object usedInDb = allocationItem.getColumn("rr_used", where); + return used.equals(usedInDb); + } + + public boolean checkLimitItem(String resourceName, String assetId, String resourceSetId, int used) { + String where = "resource_id = (SELECT resource_id FROM RESOURCE WHERE resource_name = '" + resourceName + + "' AND asset_id = '" + assetId + "') AND resource_set_id = '" + resourceSetId + "' AND lt_used = " + + used; + return allocationItem.exists(where); + } + + public boolean checkItemNotThere(String resourceName, String assetId, String resourceSetId) { + String where = "resource_id = (SELECT resource_id FROM RESOURCE WHERE resource_name = '" + resourceName + + "' AND asset_id = '" + assetId + "') AND resource_set_id = '" + resourceSetId + "'"; + return !allocationItem.exists(where); + } + + public void setTestDb(TestDb testDb) { + this.testDb = testDb; + } +} diff --git a/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestGetResource.java b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestGetResource.java new file mode 100644 index 000000000..04ee38115 --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestGetResource.java @@ -0,0 +1,222 @@ +package jtest.org.onap.ccsdk.sli.adaptors.ra; + +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"classpath:test-context.xml"}) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestGetResource { + + private static final Logger log = LoggerFactory.getLogger(TestGetResource.class); + + @Autowired(required = true) + private ResourceAllocator resourceAllocator; + + @Autowired(required = true) + private DataSetup dataSetup; + + private void setupResourceData() { + dataSetup.cleanup(); + + String targetId = "GBLOND2025MG2"; + String assetId = "Device::" + targetId; + String resourceName = "internal-vlan"; + + for (int i = 0; i < 5; i++) { + String entityId = "TEST" + i; + + String resourceUnion = "EVC::" + entityId; + String resourceSet = resourceUnion + "::1"; + + dataSetup.setupRangeItem(resourceName, assetId, resourceSet, resourceUnion, String.valueOf(i)); + } + + for (int i = 0; i < 5; i++) { + String entityId = "TEST" + (i + 10); + + String resourceUnion = "EVC::SVLAN::" + entityId; + String resourceSet = resourceUnion + "::1"; + + dataSetup.setupRangeItem(resourceName, assetId, resourceSet, resourceUnion, String.valueOf(10 + i)); + } + + for (int i = 0; i < 5; i++) { + String entityId = "TEST" + (i + 20); + + String resourceUnion = "EVC::" + entityId; + String resourceSet = resourceUnion + "::1"; + String resourceShareGroup = "SHARE1"; + + dataSetup.setupRangeItem(resourceName, assetId, resourceSet, resourceUnion, resourceShareGroup, + String.valueOf(20 + i)); + } + + for (int i = 0; i < 5; i++) { + String entityId = "TEST" + (i + 30); + + String resourceUnion = "EVC::SVLAN::" + entityId; + String resourceSet = resourceUnion + "::1"; + String resourceShareGroup = "SHARE1"; + + dataSetup.setupRangeItem(resourceName, assetId, resourceSet, resourceUnion, resourceShareGroup, + String.valueOf(30 + i)); + } + } + + @Test + public void test001() throws Exception { + + String t = "001"; + log.info("============== get-resource node " + t + " ================================"); + log.info("=== Test query for resource target - no additional criteria"); + + setupResourceData(); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-target-id", "GBLOND2025MG2"); + ctx.setAttribute("ra-input.resource-target-type", "Device"); + + ctx.setAttribute("ra-input.resource-name", "internal-vlan"); + + QueryStatus st = resourceAllocator.query("NetworkCapacity", false, null, null, "ra-output", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list_length"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-name"), "internal-vlan"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-type"), "Device"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-id"), "GBLOND2025MG2"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocated"), + "0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34"); + } + + @Test + public void test002() throws Exception { + + String t = "002"; + log.info("============== get-resource node " + t + " ================================"); + log.info("=== Test query for resource target - with resource entity condition"); + + setupResourceData(); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-target-id", "GBLOND2025MG2"); + ctx.setAttribute("ra-input.resource-target-type", "Device"); + + ctx.setAttribute("ra-input.resource-name", "internal-vlan"); + + ctx.setAttribute("ra-input.resource-entity-type-filter", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id-filter", "SVLAN%"); + + QueryStatus st = resourceAllocator.query("NetworkCapacity", false, null, null, "ra-output", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list_length"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-name"), "internal-vlan"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-type"), "Device"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-id"), "GBLOND2025MG2"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocated"), + "10, 11, 12, 13, 14, 30, 31, 32, 33, 34"); + } + + @Test + public void test003() throws Exception { + + String t = "003"; + log.info("============== get-resource node " + t + " ================================"); + log.info("=== Test query for resource target - with resource share group condition"); + + setupResourceData(); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-target-id", "GBLOND2025MG2"); + ctx.setAttribute("ra-input.resource-target-type", "Device"); + + ctx.setAttribute("ra-input.resource-name", "internal-vlan"); + + ctx.setAttribute("ra-input.resource-share-group-filter", "SHARE1"); + + QueryStatus st = resourceAllocator.query("NetworkCapacity", false, null, null, "ra-output", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list_length"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-name"), "internal-vlan"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-type"), "Device"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-id"), "GBLOND2025MG2"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocated"), + "20, 21, 22, 23, 24, 30, 31, 32, 33, 34"); + } + + @Test + public void test004() throws Exception { + + String t = "004"; + log.info("============== get-resource node " + t + " ================================"); + log.info("=== Test query for resource target - with resource share group condition NULL"); + + setupResourceData(); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-target-id", "GBLOND2025MG2"); + ctx.setAttribute("ra-input.resource-target-type", "Device"); + + ctx.setAttribute("ra-input.resource-name", "internal-vlan"); + + ctx.setAttribute("ra-input.resource-share-group-filter", "null"); + + QueryStatus st = resourceAllocator.query("NetworkCapacity", false, null, null, "ra-output", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list_length"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-name"), "internal-vlan"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-type"), "Device"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-id"), "GBLOND2025MG2"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocated"), + "0, 1, 2, 3, 4, 10, 11, 12, 13, 14"); + } + + @Test + public void test005() throws Exception { + + String t = "005"; + log.info("============== get-resource node " + t + " ================================"); + log.info("=== Test query for resource target - with both resource entity and resource share group conditions"); + + setupResourceData(); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-target-id", "GBLOND2025MG2"); + ctx.setAttribute("ra-input.resource-target-type", "Device"); + + ctx.setAttribute("ra-input.resource-name", "internal-vlan"); + + ctx.setAttribute("ra-input.resource-entity-type-filter", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id-filter", "SVLAN%"); + ctx.setAttribute("ra-input.resource-share-group-filter", "null"); + + QueryStatus st = resourceAllocator.query("NetworkCapacity", false, null, null, "ra-output", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list_length"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-name"), "internal-vlan"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-type"), "Device"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-id"), "GBLOND2025MG2"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocated"), "10, 11, 12, 13, 14"); + } +} diff --git a/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestLockHelper.java b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestLockHelper.java new file mode 100644 index 000000000..a9389b279 --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestLockHelper.java @@ -0,0 +1,61 @@ +package jtest.org.onap.ccsdk.sli.adaptors.ra; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.lock.comp.LockHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import static org.junit.Assert.assertNotNull; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { "classpath:test-context.xml" }) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestLockHelper { + + private static final Logger log = LoggerFactory.getLogger(TestLockHelper.class); + + @Autowired + private LockHelper lockHelper; + + @Test + public void test1() throws Exception { + LockThread t1 = new LockThread("req1"); + LockThread t2 = new LockThread("req2"); + LockThread t3 = new LockThread("req3"); + + t1.start(); + t2.start(); + t3.start(); + + t1.join(); + t2.join(); + t3.join(); + assertNotNull(t1); + } + + private class LockThread extends Thread { + private String requester; + + public LockThread(String requester) { + this.requester = requester; + } + + @Override + public void run() { + lockHelper.lock("resource1", requester, 20); + + try { + Thread.sleep(500); + } catch (InterruptedException e) { + log.warn("Thread interrupted: " + e.getMessage(), e); + } + + lockHelper.unlock("resource1", false); + } + } +} diff --git a/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestQueryResource.java b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestQueryResource.java new file mode 100644 index 000000000..f31a3859a --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestQueryResource.java @@ -0,0 +1,157 @@ +package jtest.org.onap.ccsdk.sli.adaptors.ra; + +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"classpath:test-context.xml"}) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestQueryResource { + + private static final Logger log = LoggerFactory.getLogger(TestQueryResource.class); + + @Autowired(required = true) + private ResourceAllocator resourceAllocator; + + @Autowired(required = true) + private DataSetup dataSetup; + + private void setupResourceData() { + dataSetup.cleanup(); + + for (int k = 0; k < 6; k++) { + String assetId = "Port::TESTPORT-" + (k / 2 + 1) + "-" + (k + 1); + + for (int i = 0; i < 5; i++) { + String entityId = "TEST-" + i + "-" + (k / 2 + 1); + + String resourceUnion = "EVC::" + entityId; + String resourceSet = resourceUnion + "::1"; + + dataSetup.setupRangeItem("test-range-1", assetId, resourceSet, resourceUnion, String.valueOf(i)); + } + } + + for (int k = 0; k < 6; k++) { + String assetId = "Port::TESTPORT-" + (k / 2 + 1) + "-" + (k + 1); + + for (int i = 0; i < 5; i++) { + String entityId = "TEST-" + i + "-" + (k / 2 + 1); + + String resourceUnion = "EVC::" + entityId; + String resourceSet = resourceUnion + "::1"; + + dataSetup.setupLimitItem("test-limit-1", assetId, resourceSet, resourceUnion, (i + 1) * 100); + } + } + } + + @Test + public void test001() throws Exception { + + String t = "001"; + log.info("============== query node " + t + " ================================"); + log.info("=== Test query for resources - with resource target condition - range"); + + setupResourceData(); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-target-id-filter", "TESTPORT-1-%"); + ctx.setAttribute("ra-input.resource-target-type-filter", "Port"); + + ctx.setAttribute("ra-input.resource-name", "test-range-1"); + + QueryStatus st = resourceAllocator.query("NetworkCapacity", false, null, null, "ra-output", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list_length"), "2"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-name"), "test-range-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-type"), "Port"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-id"), "TESTPORT-1-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocated"), "0, 1, 2, 3, 4"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].resource-name"), "test-range-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].resource-target-type"), "Port"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].resource-target-id"), "TESTPORT-1-2"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocated"), "0, 1, 2, 3, 4"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list_length"), "5"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[0].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[0].resource-entity-id"), "TEST-0-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[0].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[0].allocated"), "0"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[1].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[1].resource-entity-id"), "TEST-1-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[1].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[1].allocated"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[2].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[2].resource-entity-id"), "TEST-2-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[2].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[2].allocated"), "2"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[3].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[3].resource-entity-id"), "TEST-3-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[3].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[3].allocated"), "3"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[4].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[4].resource-entity-id"), "TEST-4-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[4].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[1].allocation-data-list[4].allocated"), "4"); + } + + @Test + public void test002() throws Exception { + + String t = "002"; + log.info("============== query node " + t + " ================================"); + log.info("=== Test query for resources - with resource target condition - limit"); + + setupResourceData(); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-target-id-filter", "TESTPORT-%-1"); + ctx.setAttribute("ra-input.resource-target-type-filter", "Port"); + + ctx.setAttribute("ra-input.resource-name", "test-limit-1"); + + QueryStatus st = resourceAllocator.query("NetworkCapacity", false, null, null, "ra-output", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list_length"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-name"), "test-limit-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-type"), "Port"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].resource-target-id"), "TESTPORT-1-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocated"), "1500"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list_length"), "5"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[0].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[0].resource-entity-id"), "TEST-0-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[0].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[0].allocated"), "100"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[1].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[1].resource-entity-id"), "TEST-1-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[1].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[1].allocated"), "200"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[2].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[2].resource-entity-id"), "TEST-2-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[2].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[2].allocated"), "300"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[3].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[3].resource-entity-id"), "TEST-3-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[3].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[3].allocated"), "400"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[4].resource-entity-type"), "EVC"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[4].resource-entity-id"), "TEST-4-1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[4].resource-entity-version"), "1"); + Assert.assertEquals(ctx.getAttribute("ra-output.resource-list[0].allocation-data-list[4].allocated"), "500"); + } +} diff --git a/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestRelease.java b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestRelease.java new file mode 100644 index 000000000..88ec586e8 --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestRelease.java @@ -0,0 +1,420 @@ +package jtest.org.onap.ccsdk.sli.adaptors.ra; + +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"classpath:test-context.xml"}) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestRelease { + + private static final Logger log = LoggerFactory.getLogger(TestRelease.class); + + @Autowired(required = true) + private ResourceAllocator resourceAllocator; + + @Autowired(required = true) + private DataSetup dataSetup; + + private void setupResourceData() { + dataSetup.cleanup(); + + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-1::1", "EVC::TEST-1", "1"); + + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-2::1", "EVC::TEST-2", "2"); + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-2::2", "EVC::TEST-2", "2"); + + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "EVC::TEST-3", "3"); + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "EVC::TEST-3", "4"); + + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::1", "EVC::TEST-4", "5"); + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::2", "EVC::TEST-4", "5"); + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::3", "EVC::TEST-4", "6"); + + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-1::1", "EVC::TEST-1", "1"); + + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "EVC::TEST-3", "3"); + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "EVC::TEST-3", "4"); + + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-5::1", "EVC::TEST-5", "5"); + + dataSetup.setupRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-6::1", "EVC::TEST-6", "6-20"); + + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-1::1", "EVC::TEST-1", 100); + + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-2::1", "EVC::TEST-2", 200); + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-2::2", "EVC::TEST-2", 200); + + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "EVC::TEST-3", 300); + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "EVC::TEST-3", 400); + + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::1", "EVC::TEST-4", 500); + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::2", "EVC::TEST-4", 500); + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::3", "EVC::TEST-4", 600); + + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-1::1", "EVC::TEST-1", 100); + + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "EVC::TEST-3", 300); + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "EVC::TEST-3", 400); + + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-5::1", "EVC::TEST-5", 500); + + dataSetup.setupLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-6::1", "EVC::TEST-6", 1000); + } + + @Test + public void test001() throws Exception { + + String t = "001"; + log.info("============== release node " + t + " ================================"); + log.info("=== Test release - with resource set"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::1", "5")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::2", "5")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::3", "6")); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::1", 500)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::2", 500)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::3", 600)); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-4"); + ctx.setAttribute("ra-input.resource-entity-version", "2"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::1", "5")); + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::2", "5")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::3", "6")); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::1", 500)); + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::2", 500)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::3", 600)); + } + + @Test + public void test002() throws Exception { + + String t = "002"; + log.info("============== query node " + t + " ================================"); + log.info("=== Test release - with resource union"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::1", "5")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::2", "5")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::3", "6")); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::1", 500)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::2", 500)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::3", 600)); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-4"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::1", "5")); + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::2", "5")); + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-4::3", "6")); + + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::1", 500)); + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::2", 500)); + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-4::3", 600)); + } + + @Test + public void test003() throws Exception { + + String t = "003"; + log.info("============== release node " + t + " ================================"); + log.info("=== Test release - with resource set on 2 ports"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "4")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "4")); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::2", 400)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::2", 400)); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-3"); + ctx.setAttribute("ra-input.resource-entity-version", "1"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "4")); + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "4")); + + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::2", 400)); + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::2", 400)); + } + + @Test + public void test004() throws Exception { + + String t = "004"; + log.info("============== release node " + t + " ================================"); + log.info("=== Test release - with resource union on 2 ports"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "4")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "4")); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::2", 400)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::2", 400)); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-3"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "3")); + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "4")); + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "3")); + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "4")); + + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::1", 300)); + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::2", 400)); + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::1", 300)); + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::2", 400)); + } + + @Test + public void test005() throws Exception { + + String t = "005"; + log.info("============== release node " + t + " ================================"); + log.info("=== Test release - with resource set and asset"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "4")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "4")); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::2", 400)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::2", 400)); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-3"); + ctx.setAttribute("ra-input.resource-entity-version", "1"); + + ctx.setAttribute("ra-input.resource-target-type", "Port"); + ctx.setAttribute("ra-input.resource-target-id", "TESTPORT-1"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "4")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "4")); + + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::2", 400)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::2", 400)); + } + + @Test + public void test006() throws Exception { + + String t = "006"; + log.info("============== release node " + t + " ================================"); + log.info("=== Test release - with resource union on 2 ports"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "4")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "4")); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::2", 400)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::2", 400)); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-3"); + + ctx.setAttribute("ra-input.resource-target-type", "Port"); + ctx.setAttribute("ra-input.resource-target-id", "TESTPORT-1"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::1", "3")); + Assert.assertFalse(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-1", "EVC::TEST-3::2", "4")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::1", "3")); + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-3::2", "4")); + + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::1", 300)); + Assert.assertFalse(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-1", "EVC::TEST-3::2", 400)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::1", 300)); + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-3::2", 400)); + } + + @Test + public void test007() throws Exception { + + String t = "007"; + log.info("============== release node " + t + " ================================"); + log.info("=== Test release - partial release of range"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-6::1", "6-20")); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-6"); + ctx.setAttribute("ra-input.resource-entity-version", "1"); + + ctx.setAttribute("ra-input.resource-target-type", "Port"); + ctx.setAttribute("ra-input.resource-target-id", "TESTPORT-2"); + + ctx.setAttribute("ra-input.resource-name", "test-range-1"); + ctx.setAttribute("ra-input.range-release-numbers", "7,9,15-17"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-6::1", "6,8,10-14,18-20")); + } + + @Test + public void test008() throws Exception { + + String t = "008"; + log.info("============== release node " + t + " ================================"); + log.info("=== Test release - partial release of range, but release all numbers"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkRangeItem("test-range-1", "Port::TESTPORT-2", "EVC::TEST-6::1", "6-20")); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-6"); + ctx.setAttribute("ra-input.resource-entity-version", "1"); + + ctx.setAttribute("ra-input.resource-target-type", "Port"); + ctx.setAttribute("ra-input.resource-target-id", "TESTPORT-2"); + + ctx.setAttribute("ra-input.resource-name", "test-range-1"); + ctx.setAttribute("ra-input.range-release-numbers", "6-25"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertTrue(dataSetup.checkItemNotThere("test-range-1", "Port::TESTPORT-2", "EVC::TEST-6::1")); + } + + @Test + public void test009() throws Exception { + + String t = "009"; + log.info("============== release node " + t + " ================================"); + log.info("=== Test release - partial release of limit"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-6::1", 1000)); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-6"); + ctx.setAttribute("ra-input.resource-entity-version", "1"); + + ctx.setAttribute("ra-input.resource-target-type", "Port"); + ctx.setAttribute("ra-input.resource-target-id", "TESTPORT-2"); + + ctx.setAttribute("ra-input.resource-name", "test-limit-1"); + ctx.setAttribute("ra-input.limit-release-amount", "200"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-6::1", 800)); + } + + @Test + public void test010() throws Exception { + + String t = "010"; + log.info("============== release node " + t + " ================================"); + log.info("=== Test release - partial release of limit, but release big number"); + + setupResourceData(); + + Assert.assertTrue(dataSetup.checkLimitItem("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-6::1", 1000)); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.resource-entity-type", "EVC"); + ctx.setAttribute("ra-input.resource-entity-id", "TEST-6"); + ctx.setAttribute("ra-input.resource-entity-version", "1"); + + ctx.setAttribute("ra-input.resource-target-type", "Port"); + ctx.setAttribute("ra-input.resource-target-id", "TESTPORT-2"); + + ctx.setAttribute("ra-input.resource-name", "test-limit-1"); + ctx.setAttribute("ra-input.limit-release-amount", "2000"); + + QueryStatus st = resourceAllocator.release("NETWORK-CAPACITY", null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + Assert.assertTrue(dataSetup.checkItemNotThere("test-limit-1", "Port::TESTPORT-2", "EVC::TEST-6::1")); + } +} diff --git a/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestReserve.java b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestReserve.java new file mode 100644 index 000000000..dbf0c4aac --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestReserve.java @@ -0,0 +1,964 @@ +package jtest.org.onap.ccsdk.sli.adaptors.ra; + +import static org.junit.Assert.assertNotNull; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceEntity; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceRequest; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceResponse; +import org.onap.ccsdk.sli.adaptors.ra.comp.ResourceTarget; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationStatus; +import org.onap.ccsdk.sli.adaptors.rm.data.Range; +import org.onap.ccsdk.sli.adaptors.rm.data.ResourceType; +import org.onap.ccsdk.sli.adaptors.util.str.StrUtil; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import jtest.util.org.onap.ccsdk.sli.adaptors.ra.TestTable; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { "classpath:test-context.xml" }) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestReserve { + + private static final Logger log = LoggerFactory.getLogger(TestReserve.class); + + private JdbcTemplate jdbcTemplate; + + private static final String[] RESOURCE_COLUMNS = { "asset_id", "resource_name", "resource_type", "lt_used" }; + + private static final String[] ALLOCATION_ITEM_COLUMNS = { "resource_id", "application_id", "resource_set_id", + "resource_union_id", "resource_share_group_list", "lt_used", "allocation_time" }; + + @Autowired + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Autowired(required = true) + private ResourceAllocator resourceAllocator; + + /* + * @Autowired(required = true) private ResourceAllocatorApi + * resourceAllocatorApi; + */ + + @Autowired(required = true) + private DataSetup dataSetup; + + @Test + public void test001() throws Exception { + String t = "001"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test successful response - new start - all resources available"); + + // String service1 = "reserve" + t + "/service1"; + + dataSetup.cleanup(); + + TestTable resource = new TestTable(jdbcTemplate, "RESOURCE", "resource_id", RESOURCE_COLUMNS); + TestTable allocationItem = new TestTable(jdbcTemplate, "ALLOCATION_ITEM", "allocation_item_id", + ALLOCATION_ITEM_COLUMNS); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "ADIG"); + ctx.setAttribute("ra-input.check-only", "false"); + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + ctx.setAttribute("ra-input.reservation-entity-id", "ICOREPVCID-123456"); + ctx.setAttribute("ra-input.reservation-entity-data.service-speed", "100"); + ctx.setAttribute("ra-input.reservation-entity-data.service-speed-unit", "Mbps"); + + ctx.setAttribute("ra-input.reservation-target-data.vnf-type", "VPE"); + ctx.setAttribute("ra-input.reservation-target-data.vpe-name", "mdt300vpe54"); + ctx.setAttribute("ra-input.reservation-target-id", "mdt300vpe54"); + ctx.setAttribute("ra-input.reservation-target-type", "VNF"); + + ctx.setAttribute("ra-input.reservation-target-data.max-vpe-bandwidth-mbps", "5000"); + + QueryStatus st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + resource.print(); + allocationItem.print(); + + ctx.setAttribute("ra-input.service-model", "ADIG"); + ctx.setAttribute("ra-input.check-only", "false"); + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + ctx.setAttribute("ra-input.reservation-entity-id", "ICOREPVCID-123456"); + ctx.setAttribute("ra-input.reservation-entity-data.service-speed", "100"); + ctx.setAttribute("ra-input.reservation-entity-data.service-speed-unit", "Mbps"); + + ctx.setAttribute("ra-input.reservation-target-data.service-speed", "100"); + ctx.setAttribute("ra-input.reservation-target-data.service-speed-unit", "Mbps"); + ctx.setAttribute("ra-input.reservation-target-id", "ICORESITEID-123456"); + ctx.setAttribute("ra-input.reservation-target-type", "Port"); + + st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + ctx.setAttribute("ra-input.service-model", "ADIG"); + ctx.setAttribute("ra-input.check-only", "false"); + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + ctx.setAttribute("ra-input.reservation-entity-id", "ICOREPVCID-123456"); + ctx.setAttribute("ra-input.reservation-entity-data.service-speed", "100"); + ctx.setAttribute("ra-input.reservation-entity-data.service-speed-unit", "Mbps"); + + ctx.setAttribute("ra-input.reservation-target-data.vnf-type", "VPE"); + ctx.setAttribute("ra-input.reservation-target-data.vpe-name", "mdt300vpe54"); + ctx.setAttribute("ra-input.reservation-target-id", "mdt300vpe54"); + ctx.setAttribute("ra-input.reservation-target-type", "AffinityLink"); + + st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + resource.print(); + allocationItem.print(); + + /* Query Using ReservationEntityId using ServiceLogicContext */ + ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "ADIG"); + ctx.setAttribute("ra-input.reservation-entity-id", "ICOREPVCID-123456"); + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + + st = resourceAllocator.query("NetworkCapacity", false, null, null, null, null, ctx); + Assert.assertTrue(st == QueryStatus.SUCCESS); + + /* Query Using ReservationTargetId using ServiceLogicContext */ + ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "ADIG"); + ctx.setAttribute("ra-input.reservation-target-id", "ICORESITEID-123456"); + ctx.setAttribute("ra-input.reservation-target-type", "Port"); + ctx.setAttribute("ra-input.resource-name", "Bandwidth"); + + st = resourceAllocator.query("NetworkCapacity", false, null, null, null, null, ctx); + Assert.assertTrue(st == QueryStatus.SUCCESS); + + log.info("======================== Query Using ResourceEntity=============================="); + /* Query Using ResourceEntity bean */ + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = "ICOREPVCID-123456"; + sd.resourceEntityType = "SI"; + + ResourceRequest rr = new ResourceRequest(); + rr.serviceModel = "ADIG"; + rr.resourceName = "cust-vlan-id"; + rr.requestType = "New"; + rr.rangeMaxOverride = -1; + rr.rangeMinOverride = -1; + + List<ResourceResponse> rsList = new ArrayList<>(); + resourceAllocator.query(sd, null, null, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + + log.info("======================== release Using ResourceEntity=============================="); + rsList = new ArrayList<>(); + AllocationStatus status = resourceAllocator.release(sd); + Assert.assertTrue(status == AllocationStatus.Success); + + log.info("======================== Query Using ResourceEntity=============================="); + rsList = new ArrayList<>(); + resourceAllocator.query(sd, null, null, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + + } + + @Test + public void test002() throws Exception { + String t = "002"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test successful response - new start - all resources available"); + + Map<String, String> data = new HashMap<>(); + data.put("service-speed", "100"); + data.put("service-speed-unit", "Mbps"); + + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = "ICOREPVCID-123456"; + sd.resourceEntityType = "SI"; + sd.data = data; + + data = new HashMap<>(); + data.put("vnf-type", "VPE"); + data.put("vpe-name", "mdt300vpe54"); + data.put("max-vpe-bandwidth-mbps", "5000"); + + ResourceTarget rt = new ResourceTarget(); + rt.resourceTargetId = "mdt300vpe54"; + rt.resourceTargetType = "VNF"; + rt.data = data; + + ResourceRequest rr = new ResourceRequest(); + rr.serviceModel = "ADIG"; + // rr.resourceName = "cust-vlan-id"; + rr.requestType = "New"; + rr.rangeMaxOverride = -1; + rr.rangeMinOverride = -1; + rr.applicationId = "myapp"; + + List<ResourceResponse> rsList = new ArrayList<>(); + + resourceAllocator.reserve(sd, rt, rr, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + + log.info("======================== Query + t =============================="); + rsList = new ArrayList<>(); + resourceAllocator.query(sd, null, rr, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + assertNotNull(rsList); + + } + + @Test + public void test003() throws Exception { + String t = "003"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test successful response - new start - all resources available"); + + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VNF"; + + ResourceTarget rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + ResourceRequest rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL"; + rr.resourceName = "VPE-Cust"; + // rr.requestType = "New"; + // rr.rangeMaxOverride = 5; + // rr.rangeMinOverride = 5; + + List<ResourceResponse> rsList = new ArrayList<>(); + resourceAllocator.reserve(sd, rt, rr, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + + log.info("======================== Query + t =============================="); + rsList = new ArrayList<>(); + resourceAllocator.query(sd, null, rr, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + assertNotNull(sd); + + } + + @Test + public void test004() throws Exception { + String t = "004"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test successful response - new start - all resources available"); + + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VNF"; + + ResourceTarget rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + List<ResourceRequest> rrs = new ArrayList<>(); + ResourceRequest rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL"; + rr.resourceName = "VPE-Cust"; + rrs.add(rr); + + rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL"; + rr.resourceName = "VPE-Core1"; + rrs.add(rr); + + rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL"; + rr.resourceName = "VPE-Core2"; + rrs.add(rr); + + List<ResourceResponse> rsList = new ArrayList<>(); + // resourceAllocator.reserve(sd, rt, rrs, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + + log.info("======================== Query + t =============================="); + rsList = new ArrayList<>(); + resourceAllocator.query(sd, null, rr, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + assertNotNull(rr); + + } + + @Test + public void test005() throws Exception { + String t = "005"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test successful response - new start - all resources available"); + + // String service1 = "reserve" + t + "/service1"; + + dataSetup.cleanup(); + + TestTable resource = new TestTable(jdbcTemplate, "RESOURCE", "resource_id", RESOURCE_COLUMNS); + TestTable allocationItem = new TestTable(jdbcTemplate, "ALLOCATION_ITEM", "allocation_item_id", + ALLOCATION_ITEM_COLUMNS); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "MY-SERV-MODEL-1"); + ctx.setAttribute("ra-input.check-only", "false"); + ctx.setAttribute("ra-input.reservation-entity-type", "VPE-Cust"); + ctx.setAttribute("ra-input.reservation-entity-id", "gblond2003me6"); + + ctx.setAttribute("ra-input.reservation-target-id", "MDTWNJ21A5"); + ctx.setAttribute("ra-input.reservation-target-type", "Site"); + + ctx.setAttribute("ra-input.resource-name", "cust-vlan-id"); + + QueryStatus st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + resource.print(); + allocationItem.print(); + + ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "MY-SERV-MODEL-1"); + ctx.setAttribute("ra-input.check-only", "false"); + ctx.setAttribute("ra-input.reservation-entity-type", "VPE-Core1"); + ctx.setAttribute("ra-input.reservation-entity-id", "gblond2003me6"); + + ctx.setAttribute("ra-input.reservation-target-id", "MDTWNJ21A5"); + ctx.setAttribute("ra-input.reservation-target-type", "Site"); + + ctx.setAttribute("ra-input.resource-name", "vlan-id-inner"); + + st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + resource.print(); + allocationItem.print(); + + ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "MY-SERV-MODEL-1"); + ctx.setAttribute("ra-input.check-only", "false"); + ctx.setAttribute("ra-input.reservation-entity-type", "VPE-Core2"); + ctx.setAttribute("ra-input.reservation-entity-id", "gblond2003me6"); + + ctx.setAttribute("ra-input.reservation-target-id", "MDTWNJ21A5"); + ctx.setAttribute("ra-input.reservation-target-type", "Site"); + + ctx.setAttribute("ra-input.resource-name", "vlan-id-inner"); + ctx.setAttribute("ra-input.replace", "false"); + + st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + + resource.print(); + allocationItem.print(); + + /* Query Using ReservationEntityId using ServiceLogicContext */ + ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "MY-SERV-MODEL-1"); + ctx.setAttribute("ra-input.reservation-entity-id", "gblond2003me6"); + ctx.setAttribute("ra-input.reservation-entity-type", "VPE-Core1"); + + st = resourceAllocator.query("NetworkCapacity", false, null, null, null, null, ctx); + Assert.assertTrue(st == QueryStatus.SUCCESS); + + /* Query Using ReservationTargetId using ServiceLogicContext */ + ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "MY-SERV-MODEL-1"); + ctx.setAttribute("ra-input.reservation-target-id", "MDTWNJ21A5"); + ctx.setAttribute("ra-input.reservation-target-type", "Site"); + ctx.setAttribute("ra-input.resource-name", "vlan-id-inner"); + + st = resourceAllocator.query("NetworkCapacity", false, null, null, null, null, ctx); + Assert.assertTrue(st == QueryStatus.SUCCESS); + + log.info("======================== Query Using ResourceEntity=============================="); + /* Query Using ResourceEntity bean */ + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VPE-Core1"; + + ResourceRequest rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL-1"; + rr.resourceName = "vlan-id-inner"; + rr.requestType = "New"; + rr.rangeMaxOverride = -1; + rr.rangeMinOverride = -1; + + List<ResourceResponse> rsList = new ArrayList<>(); + resourceAllocator.query(sd, null, null, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + + /* + * log. + * info("======================== release Using ResourceEntity==============================" + * ); rsList = new ArrayList<ResourceResponse>(); AllocationStatus status = + * resourceAllocator.release(sd); Assert.assertTrue(status == + * AllocationStatus.Success); + * + * + * log. + * info("======================== Query Using ResourceEntity==============================" + * ); rsList = new ArrayList<ResourceResponse>(); resourceAllocator.query(sd, + * null, null, rsList); + * + * + * rsList.forEach(r -> { StrUtil.info(log, r); }); + */ + + } + + @Test + public void test006() throws Exception { + String t = "006"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test successful response - new start - all resources available"); + + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VPE-Cust"; + + ResourceTarget rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + ResourceRequest rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL-1"; + rr.resourceName = "cust-vlan-id"; + + List<ResourceResponse> rsList = new ArrayList<>(); + resourceAllocator.reserve(sd, rt, rr, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + + log.info("======================== Query + t =============================="); + rsList = new ArrayList<>(); + resourceAllocator.query(sd, null, rr, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + assertNotNull(rsList); + + } + + @Test + public void test007() throws Exception { + String t = "007"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test successful response - new start - all resources available"); + + dataSetup.cleanup(); + + TestTable resource = new TestTable(jdbcTemplate, "RESOURCE", "resource_id", RESOURCE_COLUMNS); + TestTable allocationItem = new TestTable(jdbcTemplate, "ALLOCATION_ITEM", "allocation_item_id", + ALLOCATION_ITEM_COLUMNS); + + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VPE"; + sd.resourceEntityVersion = "1"; + + ResourceTarget rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + ResourceRequest rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL"; + // rr.resourceName = "vlan-id-outer"; + rr.endPointPosition = "VPE-Cust"; + rr.rangeMaxOverride = -1; + rr.rangeMinOverride = -1; + rr.applicationId = "myapp"; + + List<ResourceResponse> rsList = new ArrayList<>(); + resourceAllocator.reserve(sd, rt, rr, rsList); + + // VPE-Core1 + sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VPE"; + sd.resourceEntityVersion = "1"; + + rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL"; + // rr.resourceName = "vlan-id-filter"; + rr.endPointPosition = "VPE-Core1"; + rr.rangeMaxOverride = -1; + rr.rangeMinOverride = -1; + rr.applicationId = "myapp"; + + rsList = new ArrayList<>(); + resourceAllocator.reserve(sd, rt, rr, rsList); + + // VPE-Core2 + sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VPE"; + sd.resourceEntityVersion = "1"; + + rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL"; + // rr.resourceName = "vlan-id-filter"; + rr.endPointPosition = "VPE-Core2"; + rr.rangeMaxOverride = -1; + rr.rangeMinOverride = -1; + rr.applicationId = "myapp"; + + rsList = new ArrayList<>(); + resourceAllocator.reserve(sd, rt, rr, rsList); + + // VPE-Core3 + sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VPE"; + sd.resourceEntityVersion = "1"; + + rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL"; + // rr.resourceName = "vlan-id-filter"; + rr.endPointPosition = "VPE-Core3"; + rr.rangeMaxOverride = -1; + rr.rangeMinOverride = -1; + rr.applicationId = "myapp"; + + rsList = new ArrayList<>(); + resourceAllocator.reserve(sd, rt, rr, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + + resource.print(); + allocationItem.print(); + + log.info("======================== Query + t =============================="); + rsList = new ArrayList<>(); + resourceAllocator.query(sd, null, rr, rsList); + + rsList.forEach(r -> { + StrUtil.info(log, r); + }); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.reservation-entity-id", "gblond2003me6"); + ctx.setAttribute("ra-input.reservation-entity-type", "VPE"); + + QueryStatus st = resourceAllocator.release("NetworkCapacity", "gblond2003me6", ctx); + Assert.assertTrue(st == QueryStatus.SUCCESS); + + } + + @Test + public void test008() throws Exception { + String t = "008"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test range-force-new-numbers = false"); + + String entityId = "reserve" + t; + String targetId = "port-id-1"; + String resourceName = "cust-vlan-id"; + + String assetId = "VNF::" + targetId; + String resourceUnion = "SI::" + entityId; + String resourceSet1 = resourceUnion + "::1"; + String resourceSet2 = resourceUnion + "::2"; + + dataSetup.cleanup(); + + dataSetup.setupRangeItem(resourceName, assetId, resourceSet1, resourceUnion, "201"); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "ADIG"); + ctx.setAttribute("ra-input.check-only", "false"); + + ctx.setAttribute("ra-input.resource-name", resourceName); + ctx.setAttribute("ra-input.range-force-new-numbers", "false"); + + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + ctx.setAttribute("ra-input.reservation-entity-id", entityId); + ctx.setAttribute("ra-input.reservation-entity-version", "2"); + + ctx.setAttribute("ra-input.reservation-target-id", targetId); + ctx.setAttribute("ra-input.reservation-target-type", "VNF"); + + QueryStatus st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + Assert.assertTrue(dataSetup.checkRangeItem(resourceName, assetId, resourceSet1, "201")); + Assert.assertTrue(dataSetup.checkRangeItem(resourceName, assetId, resourceSet2, "201")); + + Assert.assertEquals(ctx.getAttribute("resource-list_length"), "1"); + Assert.assertEquals(ctx.getAttribute("resource-list[0].resource-name"), "cust-vlan-id"); + Assert.assertEquals(ctx.getAttribute("resource-list[0].resource-target-type"), "VNF"); + Assert.assertEquals(ctx.getAttribute("resource-list[0].resource-target-id"), "port-id-1"); + Assert.assertEquals(ctx.getAttribute("resource-list[0].status"), "Success"); + Assert.assertEquals(ctx.getAttribute("resource-list[0].allocated"), "201"); + Assert.assertEquals(ctx.getAttribute("resource-list[0].used"), "201"); + Assert.assertEquals(ctx.getAttribute("resource-list[0].range-list_length"), "1"); + Assert.assertEquals(ctx.getAttribute("resource-list[0].range-list[0].min"), "2"); + Assert.assertEquals(ctx.getAttribute("resource-list[0].range-list[0].max"), "1000"); + } + + @Test + public void test009() throws Exception { + String t = "009"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test range-force-new-numbers = true"); + + String entityId = "reserve" + t; + String targetId = "port-id-1"; + String resourceName = "cust-vlan-id"; + + String assetId = "VNF::" + targetId; + String resourceUnion = "SI::" + entityId; + String resourceSet1 = resourceUnion + "::1"; + String resourceSet2 = resourceUnion + "::2"; + + dataSetup.cleanup(); + + dataSetup.setupRangeItem(resourceName, assetId, resourceSet1, resourceUnion, "201"); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "ADIG"); + ctx.setAttribute("ra-input.check-only", "false"); + + ctx.setAttribute("ra-input.resource-name", resourceName); + ctx.setAttribute("ra-input.range-force-new-numbers", "true"); + + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + ctx.setAttribute("ra-input.reservation-entity-id", entityId); + ctx.setAttribute("ra-input.reservation-entity-version", "2"); + + ctx.setAttribute("ra-input.reservation-target-id", targetId); + ctx.setAttribute("ra-input.reservation-target-type", "VNF"); + + QueryStatus st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + Assert.assertTrue(dataSetup.checkRangeItem(resourceName, assetId, resourceSet1, "201")); + Assert.assertFalse(dataSetup.checkRangeItem(resourceName, assetId, resourceSet2, "201")); + } + + @Test + public void test0010_vlantag_with_resourcemodel() throws Exception { + + String t = "0010"; + log.info("============== reserve " + t + " ================================"); + + dataSetup.cleanup(); + + TestTable resource = new TestTable(jdbcTemplate, "RESOURCE", "resource_id", RESOURCE_COLUMNS); + TestTable allocationItem = new TestTable(jdbcTemplate, "ALLOCATION_ITEM", "allocation_item_id", + ALLOCATION_ITEM_COLUMNS); + + ResourceEntity sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VNF"; + sd.resourceEntityVersion = "1"; + + ResourceTarget rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + ResourceRequest rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL_3456"; + rr.resourceName = "vlan-id-outer"; + rr.endPointPosition = "VPE-Core1"; + rr.rangeMaxOverride = 3901; + rr.rangeMinOverride = 3900; + rr.resourceType = ResourceType.Range; + rr.applicationId = "myapp"; + + List<ResourceResponse> rsList = new ArrayList<>(); + resourceAllocator.reserve(sd, rt, rr, rsList); + + resource.print(); + allocationItem.print(); + + Range range = new Range(); + range.min = 3900; + range.max = 3901; + + sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VNF"; + sd.resourceEntityVersion = "1"; + + rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL_3456"; + rr.resourceName = "vlan-id-outer"; + rr.endPointPosition = "VPE-Core2"; + rr.rangeMaxOverride = -1; + rr.rangeMinOverride = -1; + rr.rangeOverrideList = Arrays.asList(range); + rr.resourceType = ResourceType.Range; + rr.applicationId = "myapp"; + + rsList = new ArrayList<>(); + resourceAllocator.reserve(sd, rt, rr, rsList); + + resource.print(); + allocationItem.print(); + + sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VNF"; + sd.resourceEntityVersion = "1"; + + rt = new ResourceTarget(); + rt.resourceTargetId = "MDTWNJ21A5"; + rt.resourceTargetType = "Site"; + + Range range1 = new Range(); + range1.min = 3900; + range1.max = 3901; + + Range range2 = new Range(); + range2.min = 3904; + range2.max = 3905; + + rr = new ResourceRequest(); + rr.serviceModel = "MY-SERV-MODEL_3456"; + rr.resourceName = "vlan-id-outer"; + rr.endPointPosition = "VPE-Core3"; + rr.rangeMaxOverride = -1; + rr.rangeMinOverride = -1; + rr.rangeOverrideList = new ArrayList<>(); + rr.rangeOverrideList.add(range1); + rr.rangeOverrideList.add(range2); + rr.applicationId = "myapp"; + rr.resourceType = ResourceType.Range; + + rsList = new ArrayList<>(); + AllocationStatus status = resourceAllocator.reserve(sd, rt, rr, rsList); + Assert.assertTrue(status == AllocationStatus.Success); + + resource.print(); + allocationItem.print(); + + sd = new ResourceEntity(); + sd.resourceEntityId = "gblond2003me6"; + sd.resourceEntityType = "VNF"; + sd.resourceEntityVersion = "1"; + + rr = new ResourceRequest(); + rr.endPointPosition = "VPE-Core2"; + status = resourceAllocator.release(sd, rr); + Assert.assertTrue(status == AllocationStatus.Success); + + resource.print(); + allocationItem.print(); + + } + + @Test + public void test011() throws Exception { + String t = "011"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test range-next-in-sequence = true"); + + String entityId = "reserve" + t; + String targetId = "port-id-1"; + String resourceName = "vlan-id-filter"; + + String assetId = "Site::" + targetId; + String resourceUnion = "SI::" + entityId; + String resourceSet = resourceUnion + "::1"; + + dataSetup.cleanup(); + dataSetup.setupRangeItem(resourceName, assetId, resourceSet, resourceUnion, "1002,1004,1006,1008"); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "MY-SERV-MODEL"); + ctx.setAttribute("ra-input.endpoint-position", "VPE-Core2"); + ctx.setAttribute("ra-input.check-only", "false"); + + ctx.setAttribute("ra-input.resource-name", resourceName); + ctx.setAttribute("ra-input.range-next-in-sequence", "true"); + + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + ctx.setAttribute("ra-input.reservation-entity-id", entityId + "_test"); + ctx.setAttribute("ra-input.reservation-entity-version", "1"); + + ctx.setAttribute("ra-input.reservation-target-id", targetId); + ctx.setAttribute("ra-input.reservation-target-type", "Site"); + + QueryStatus st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + Assert.assertTrue(dataSetup.checkRangeItem(resourceName, assetId, "SI::" + entityId + "_test::VPE-Core2::1", "1009")); + } + + @Test + public void test012() throws Exception { + String t = "012"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test range-next-in-sequence = false"); + + String entityId = "reserve" + t; + String targetId = "port-id-1"; + String resourceName = "vlan-id-filter"; + + String assetId = "Site::" + targetId; + String resourceUnion = "SI::" + entityId; + String resourceSet = resourceUnion + "::1"; + + dataSetup.cleanup(); + dataSetup.setupRangeItem(resourceName, assetId, resourceSet, resourceUnion, "1002,1004,1006,1008"); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "MY-SERV-MODEL"); + ctx.setAttribute("ra-input.endpoint-position", "VPE-Core2"); + ctx.setAttribute("ra-input.check-only", "false"); + + ctx.setAttribute("ra-input.resource-name", resourceName); + ctx.setAttribute("ra-input.range-next-in-sequence", "false"); + + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + ctx.setAttribute("ra-input.reservation-entity-id", entityId + "_test"); + ctx.setAttribute("ra-input.reservation-entity-version", "1"); + + ctx.setAttribute("ra-input.reservation-target-id", targetId); + ctx.setAttribute("ra-input.reservation-target-type", "Site"); + + QueryStatus st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + Assert.assertTrue(dataSetup.checkRangeItem(resourceName, assetId, "SI::" + entityId + "_test::VPE-Core2::1", "1003")); + } + + @Test + public void test013() throws Exception { + String t = "013"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test range-next-in-sequence = true - multiple ranges"); + + String entityId = "reserve" + t; + String targetId = "port-id-1"; + String resourceName = "vlan-id-filter"; + + String assetId = "Site::" + targetId; + String resourceUnion = "SI::" + entityId; + String resourceSet = resourceUnion + "::1"; + + dataSetup.cleanup(); + dataSetup.setupRangeItem(resourceName, assetId, resourceSet, resourceUnion, "1002,1004,1006,1008,2205-2221"); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "MY-SERV-MODEL"); + ctx.setAttribute("ra-input.endpoint-position", "VPE-Core2"); + ctx.setAttribute("ra-input.check-only", "false"); + + ctx.setAttribute("ra-input.resource-name", resourceName); + ctx.setAttribute("ra-input.range-next-in-sequence", "true"); + + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + ctx.setAttribute("ra-input.reservation-entity-id", entityId + "_test"); + ctx.setAttribute("ra-input.reservation-entity-version", "1"); + + ctx.setAttribute("ra-input.reservation-target-id", targetId); + ctx.setAttribute("ra-input.reservation-target-type", "Site"); + + QueryStatus st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + Assert.assertTrue(dataSetup.checkRangeItem(resourceName, assetId, "SI::" + entityId + "_test::VPE-Core2::1", "2222")); + } + + @Test + public void test014() throws Exception { + String t = "014"; + log.info("============== reserve " + t + " ================================"); + log.info("=== Test range-next-in-sequence = true - no previously reserved numbers"); + + String entityId = "reserve" + t; + String targetId = "port-id-1"; + String resourceName = "vlan-id-filter"; + + String assetId = "Site::" + targetId; + + dataSetup.cleanup(); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("ra-input.service-model", "MY-SERV-MODEL"); + ctx.setAttribute("ra-input.endpoint-position", "VPE-Core2"); + ctx.setAttribute("ra-input.check-only", "false"); + + ctx.setAttribute("ra-input.resource-name", resourceName); + ctx.setAttribute("ra-input.range-next-in-sequence", "true"); + + ctx.setAttribute("ra-input.reservation-entity-type", "SI"); + ctx.setAttribute("ra-input.reservation-entity-id", entityId + "_test"); + ctx.setAttribute("ra-input.reservation-entity-version", "1"); + + ctx.setAttribute("ra-input.reservation-target-id", targetId); + ctx.setAttribute("ra-input.reservation-target-type", "Site"); + + QueryStatus st = resourceAllocator.reserve("NetworkCapacity", null, null, null, ctx); + + Assert.assertTrue(st == QueryStatus.SUCCESS); + Assert.assertTrue(dataSetup.checkRangeItem(resourceName, assetId, "SI::" + entityId + "_test::VPE-Core2::1", "1002")); + } +} diff --git a/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestResourceLockNode.java b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestResourceLockNode.java new file mode 100644 index 000000000..dc0761c20 --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/ra/TestResourceLockNode.java @@ -0,0 +1,39 @@ +package jtest.org.onap.ccsdk.sli.adaptors.ra; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.onap.ccsdk.sli.adaptors.ra.ResourceLockNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { "classpath:test-context.xml" }) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestResourceLockNode { + + @SuppressWarnings("unused") + private static final Logger log = LoggerFactory.getLogger(TestResourceLockNode.class); + + @Autowired + private ResourceLockNode resourceLockNode; + + @Test + public void test1() throws Exception { + Map<String, String> paramMap = new HashMap<>(); + paramMap.put("resource-name", "test-resource-1"); + paramMap.put("lock-requester", "SDNA"); + + resourceLockNode.lockResource(paramMap, null); + resourceLockNode.unlockResource(paramMap, null); + Assert.assertNotNull(paramMap); + } +} diff --git a/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/rm/util/LabelUtilTest.java b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/rm/util/LabelUtilTest.java new file mode 100644 index 000000000..eb903ecdc --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/org/onap/ccsdk/sli/adaptors/rm/util/LabelUtilTest.java @@ -0,0 +1,45 @@ +package jtest.org.onap.ccsdk.sli.adaptors.rm.util; + +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.rm.data.AllocationItem; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelAllocationRequest; +import org.onap.ccsdk.sli.adaptors.rm.data.LabelResource; +import org.onap.ccsdk.sli.adaptors.rm.util.LabelUtil; + +import java.util.Date; + +import static org.junit.Assert.*; + +public class LabelUtilTest { + + @Test + public void testLabelUtils() { + LabelAllocationRequest req = new LabelAllocationRequest(); + req.check = true; + req.allocate = true; + req.label = "testLabel"; + req.resourceUnionId = "123"; + req.applicationId = "testApp"; + req.assetId = "asset1"; + req.resourceName = "resource1"; + req.resourceSetId = "set1"; + + + + LabelResource resource = new LabelResource(); + resource.label = "testLabel"; + + LabelUtil.allocateLabel(resource, req); + LabelUtil.checkLabel(resource, req); + LabelUtil.recalculate(resource); + + + + + + + + } + + +}
\ No newline at end of file diff --git a/resource-assignment/provider/src/test/java/jtest/util/org/onap/ccsdk/sli/adaptors/ra/TestDb.java b/resource-assignment/provider/src/test/java/jtest/util/org/onap/ccsdk/sli/adaptors/ra/TestDb.java new file mode 100644 index 000000000..6446240dc --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/util/org/onap/ccsdk/sli/adaptors/ra/TestDb.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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 jtest.util.org.onap.ccsdk.sli.adaptors.ra; + +import org.springframework.jdbc.core.JdbcTemplate; + +public class TestDb { + + private JdbcTemplate jdbcTemplate; + + public TestTable table(String tableName, String idName, String... columnList) { + return new TestTable(jdbcTemplate, tableName, idName, columnList); + } + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } +} diff --git a/resource-assignment/provider/src/test/java/jtest/util/org/onap/ccsdk/sli/adaptors/ra/TestTable.java b/resource-assignment/provider/src/test/java/jtest/util/org/onap/ccsdk/sli/adaptors/ra/TestTable.java new file mode 100644 index 000000000..e2541f393 --- /dev/null +++ b/resource-assignment/provider/src/test/java/jtest/util/org/onap/ccsdk/sli/adaptors/ra/TestTable.java @@ -0,0 +1,135 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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 jtest.util.org.onap.ccsdk.sli.adaptors.ra; + +import java.sql.ResultSetMetaData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.rowset.SqlRowSet; + +public class TestTable { + + private String tableName; + private String[] columnList; + private String idName; + + private String insertSql; + + private JdbcTemplate jdbcTemplate; + + private static final Logger log = LoggerFactory.getLogger(TestTable.class); + + public TestTable(JdbcTemplate jdbcTemplate, String tableName, String idName, String... columnList) { + this.jdbcTemplate = jdbcTemplate; + this.tableName = tableName; + this.idName = idName; + this.columnList = columnList; + createInsertSql(); + } + + public TestTable(JdbcTemplate jdbcTemplate, String tableName) { + this.jdbcTemplate = jdbcTemplate; + this.tableName = tableName; + } + + private void createInsertSql() { + StringBuilder ss = new StringBuilder(); + ss.append("INSERT INTO ").append(tableName).append(" ("); + for (String s : columnList) + ss.append(s).append(", "); + ss.setLength(ss.length() - 2); + ss.append(") VALUES ("); + for (int i = 0; i < columnList.length; i++) + ss.append("?, "); + ss.setLength(ss.length() - 2); + ss.append(")"); + insertSql = ss.toString(); + } + + public void add(Object... values) { + jdbcTemplate.update(insertSql, values); + } + + public void update(String updateSql, Object... values) { + jdbcTemplate.update(updateSql, values); + } + + public long getLastId() { + return jdbcTemplate.queryForObject("SELECT max(" + idName + ") FROM " + tableName, Long.class); + } + + public Long getId(String where) { + String selectSql = "SELECT " + idName + " FROM " + tableName + " WHERE " + where; + SqlRowSet rs = jdbcTemplate.queryForRowSet(selectSql); + if (rs.first()) + return rs.getLong(idName); + return null; + } + + public Object getColumn(String columnName, String where) { + String selectSql = "SELECT " + columnName + " FROM " + tableName + " WHERE " + where; + SqlRowSet rs = jdbcTemplate.queryForRowSet(selectSql); + if (rs.first()) + return rs.getObject(columnName); + return null; + } + + public boolean exists(String where) { + String selectSql = "SELECT * FROM " + tableName + " WHERE " + where; + SqlRowSet rs = jdbcTemplate.queryForRowSet(selectSql); + return rs.first(); + } + + public void delete(String where) { + jdbcTemplate.update("DELETE FROM " + tableName + " WHERE " + where); + } + + public void print() { + + jdbcTemplate.query("SELECT * FROM " + tableName, + (rs, rowNum) -> { + String row = "Table Data for " + tableName +"\n"; + String col = ""; + + final ResultSetMetaData meta = rs.getMetaData(); + final int columnCount = meta.getColumnCount(); + + do { + col = ""; + + for (int column = 1; column <= columnCount; ++column) { + Object obj = rs.getObject(column); + if(!rs.wasNull()) { + col = col + obj + ","; + } + } + col = col.trim().length() == 0 ? "" : (col.trim().substring(0, col.trim().length() - 1)); + row = row + col + "\n"; + } while (rs.next()); + + return row; + }).forEach(row -> { + log.info(row); + }); + } +}
\ No newline at end of file diff --git a/resource-assignment/provider/src/test/resources/log4j.properties b/resource-assignment/provider/src/test/resources/log4j.properties new file mode 100644 index 000000000..34dcdfb68 --- /dev/null +++ b/resource-assignment/provider/src/test/resources/log4j.properties @@ -0,0 +1,26 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +log4j.rootLogger=INFO, A1 +log4j.appender.A1=org.apache.log4j.ConsoleAppender +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%d{ISO8601} %5p %t %X{UUID} %c{3}:%L - %m%n +log4j.logger.org.hibernate=INFO diff --git a/resource-assignment/provider/src/test/resources/sql/data.sql b/resource-assignment/provider/src/test/resources/sql/data.sql new file mode 100644 index 000000000..236a16d18 --- /dev/null +++ b/resource-assignment/provider/src/test/resources/sql/data.sql @@ -0,0 +1,180 @@ +--- +-- ============LICENSE_START======================================================= +-- openECOMP : SDN-C +-- ================================================================================ +-- 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========================================================= +--- + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, equipment_level, equipment_expression, + allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Bandwidth', 'L3SDN', 'IPAG-TOA', 'true', 'Port', 'true', + 'service-speed-kbps', '0.5 * max-port-speed', '0.9 * max-port-speed'); + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, equipment_level, equipment_expression, + allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Bandwidth', 'L3SDN', 'VCE-Cust', 'true', 'Server', 'true', + 'service-speed-kbps', '0.6 * max-server-speed * number-primary-servers', 'max-server-speed * number-primary-servers'); + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, equipment_level, + equipment_expression, allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Connection', 'L3SDN', 'VCE-Cust', 'true', 'Server', + 'true', '1', '40', '40'); + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, equipment_level, equipment_expression, + allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Bandwidth', 'L3SDN', 'VPE-Cust', 'true', 'Port', 'true', + 'service-speed-kbps', '0.5 * max-port-speed', '0.9 * max-port-speed'); + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, + equipment_level, equipment_expression, allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Bandwidth', 'L3AVPN-EVC', 'VPE-Cust', 'true', 'Port', 'true', 'service-speed-kbps', '8000000', '8000000'); + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, + equipment_level, equipment_expression, allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Connection', 'L3AVPN-EVC', 'VPE-Cust', 'true', 'Port', 'true', '1', '200', '200'); + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, + equipment_level, equipment_expression, allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Bandwidth', 'L3AVPN-PORT', 'VPE-Cust', 'true', 'Port', 'true', 'service-speed-kbps', '8000000', '8000000'); + +insert into RESOURCE_THRESHOLD ( + resource_rule_id, threshold_expression, threshold_message) +values ( + (select resource_rule_id from RESOURCE_RULE where resource_name = 'Bandwidth' and equipment_level = 'Server'), + '0.5 * max-server-speed * number-primary-servers', + 'The provisioned access bandwidth is at or exceeds 50% of the total server capacity.'); + +insert into RESOURCE_THRESHOLD ( + resource_rule_id, threshold_expression, threshold_message) +values ( + (select resource_rule_id from RESOURCE_RULE where resource_name = 'Bandwidth' and equipment_level = 'Server'), + '0.7 * max-server-speed * number-primary-servers', + 'The provisioned access bandwidth is at or exceeds 70% of the total server capacity.'); + +INSERT INTO RANGE_RULE ( + range_name, service_model, end_point_position, equipment_level, equipment_expression, ranges) +VALUES ( + 'subinterface-id', 'L3AVPN-EVC', 'VPE-Cust', 'Port', 'true', '100-3999'); + +INSERT INTO RANGE_RULE ( + range_name, service_model, end_point_position, equipment_level, equipment_expression, ranges) +VALUES ( + 'vlan-id-inner', 'L3AVPN-EVC', 'VPE-Cust', 'Port', 'true', '2-4091'); + +INSERT INTO RANGE_RULE ( + range_name, service_model, end_point_position, equipment_level, equipment_expression, ranges) +VALUES ( + 'bundle-id', 'L3AVPN-PORT', 'VPE-Cust', 'Port', 'true', '1-99999'); + +INSERT INTO MAX_PORT_SPEED ( + image_file_name, end_point_position, interface_name, max_speed, unit) +VALUES ( + 'JUNIPER_VPE_IMAGE_FILENAME', 'VPE-Cust', 'ae0', 5000, 'Mpbs'); + +INSERT INTO MAX_SERVER_SPEED (server_model, evc_count, max_speed, unit, description) +VALUES ('ALL', 5, 1600, 'Mbps', 'Max speed, when there are <=5 EVC on server'); + +INSERT INTO MAX_SERVER_SPEED (server_model, evc_count, max_speed, unit, description) +VALUES ('ALL', 10, 1400, 'Mbps', 'Max speed, when there are 6 to 10 (including 10) EVC on server'); + +INSERT INTO MAX_SERVER_SPEED (server_model, evc_count, max_speed, unit, description) +VALUES ('ALL', 15, 1000, 'Mbps', 'Max speed, when there are 11 to 15 (including 15) EVC on server'); + +INSERT INTO MAX_SERVER_SPEED (server_model, evc_count, max_speed, unit, description) +VALUES ('ALL', 20, 700, 'Mbps', 'Max speed, when there are 16 to 20 (including 20) EVC on server'); + +INSERT INTO MAX_SERVER_SPEED (server_model, evc_count, max_speed, unit, description) +VALUES ('ALL', 10000, 500, 'Mbps', 'Max speed, when there are 21 or more EVC on server'); + +INSERT INTO PARAMETERS (name, value, category, memo) +VALUES ('homing.pserver.sparing.ratio', '1:1', 'homing', + 'Ratio of primary to backup servers within any of the AIC sites. Used in RA to calculate the max allowed bw in an AIC site.'); + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, equipment_level, equipment_expression, + allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'PortBandwidth', 'ADIG', 'VPE', 'true', 'Port', 'true', + 'service-speed-mbps', 'service-speed-mbps', 'service-speed-mbps'); + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, equipment_level, equipment_expression, + allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Bandwidth', 'ADIG', 'VPE', 'true', 'VNF', 'vnf-type = "VPE"', + 'service-speed-mbps', '0.5 * max-vpe-bandwidth-mbps', '0.9 * max-vpe-bandwidth-mbps'); + + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, equipment_level, equipment_expression, + allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Bandwidth', 'ADIG', 'VPE', 'true', 'AffinityLink', 'true', + 'service-speed-mbps', '9999999999', '9999999999'); + +INSERT INTO RESOURCE_RULE ( + resource_name, service_model, end_point_position, service_expression, equipment_level, equipment_expression, + allocation_expression, soft_limit_expression, hard_limit_expression) +VALUES ( + 'Connection', 'ADIG', 'VPE', 'true', 'VNF', 'true', + '1', '200', '200'); + +INSERT INTO RANGE_RULE ( + range_name, service_model, end_point_position, equipment_level, equipment_expression, ranges) +VALUES ( + 'cust-vlan-id', 'ADIG', 'VPE', 'VNF', 'true', '2-1000'); + +INSERT INTO RANGE_RULE ( + range_name, service_model, end_point_position, equipment_level, equipment_expression, ranges) +VALUES ( + 'vlan-id-inner', 'ADIG', 'VPE', 'VNF', 'true', '1002-2000'); + + +INSERT INTO RANGE_RULE ( + range_name, service_model, end_point_position, equipment_level, equipment_expression, ranges) +VALUES ( + 'vlan-id-outer', 'MY-SERV-MODEL', 'VPE-Cust', 'Site', 'true', '2-1000'); + +INSERT INTO RANGE_RULE ( + range_name, service_model, end_point_position, equipment_level, equipment_expression, ranges) +VALUES ( + 'vlan-id-filter', 'MY-SERV-MODEL', 'VPE-Core1', 'Site', 'true', '1002-2000'); + +INSERT INTO RANGE_RULE ( + range_name, service_model, end_point_position, equipment_level, equipment_expression, ranges) +VALUES ( + 'vlan-id-filter', 'MY-SERV-MODEL', 'VPE-Core2', 'Site', 'true', '1002-2000,2200-4000'); + +INSERT INTO RANGE_RULE ( + range_name, service_model, end_point_position, equipment_level, equipment_expression, ranges) +VALUES ( + 'vlan-id-filter', 'MY-SERV-MODEL', 'VPE-Core3', 'Site', 'true', '400-600'); +
\ No newline at end of file diff --git a/resource-assignment/provider/src/test/resources/sql/schema.sql b/resource-assignment/provider/src/test/resources/sql/schema.sql new file mode 100644 index 000000000..275337e44 --- /dev/null +++ b/resource-assignment/provider/src/test/resources/sql/schema.sql @@ -0,0 +1,201 @@ +--- +-- ============LICENSE_START======================================================= +-- openECOMP : SDN-C +-- ================================================================================ +-- 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========================================================= +--- + +CREATE TABLE RESOURCE_LOCK ( + resource_lock_id SERIAL PRIMARY KEY, + resource_name VARCHAR(50) NOT NULL UNIQUE, + lock_holder VARCHAR(100) NOT NULL, + lock_count SMALLINT NOT NULL, + lock_time DATETIME NOT NULL, + expiration_time DATETIME NOT NULL +); + +CREATE TABLE RESOURCE ( + resource_id SERIAL PRIMARY KEY, + asset_id VARCHAR(50) NOT NULL, + resource_name VARCHAR(50) NOT NULL, + resource_type VARCHAR(10) NOT NULL, + lt_used BIGINT, + ll_label VARCHAR(50), + ll_reference_count SMALLINT, + rr_used VARCHAR(4000) +); + +ALTER TABLE RESOURCE ADD CONSTRAINT c1_resource CHECK (resource_type IN ('Limit', 'Label', 'Range')); +CREATE UNIQUE INDEX ak1_resource ON RESOURCE (asset_id, resource_name); + +CREATE TABLE RESOURCE_LOAD ( + resource_load_id SERIAL PRIMARY KEY, + resource_id BIGINT NOT NULL REFERENCES resource (resource_id), + application_id VARCHAR(20) NOT NULL, + resource_load_time DATETIME NOT NULL, + resource_expiration_time DATETIME +); + +CREATE INDEX i1_resource_load ON RESOURCE_LOAD (resource_id); +CREATE UNIQUE INDEX ak1_resource_load ON RESOURCE_LOAD (resource_id, application_id); + +CREATE TABLE ALLOCATION_ITEM ( + allocation_item_id SERIAL PRIMARY KEY, + resource_id BIGINT NOT NULL REFERENCES resource (resource_id), + application_id VARCHAR(50) NOT NULL, + resource_set_id VARCHAR(50) NOT NULL, + resource_union_id VARCHAR(50) NOT NULL, + resource_share_group_list VARCHAR(200), + lt_used BIGINT, + ll_label VARCHAR(50), + rr_used VARCHAR(200), + allocation_time DATETIME NOT NULL +); + +CREATE INDEX i1_allocation_item ON allocation_item (resource_id); +CREATE UNIQUE INDEX ak1_allocation_item ON allocation_item (resource_id, resource_set_id); + +CREATE TABLE RESOURCE_RULE ( + resource_rule_id SERIAL PRIMARY KEY, + resource_name VARCHAR(50) NOT NULL, + service_model VARCHAR(50) NOT NULL, + end_point_position VARCHAR(50) NOT NULL, + service_expression VARCHAR(2000) NOT NULL, + equipment_level VARCHAR(50) NOT NULL, + equipment_expression VARCHAR(2000) NOT NULL, + allocation_expression VARCHAR(2000) NOT NULL, + soft_limit_expression VARCHAR(2000) NOT NULL, + hard_limit_expression VARCHAR(2000) NOT NULL +); + +CREATE TABLE RESOURCE_THRESHOLD ( + resource_threshold_id bigint(20) unsigned NOT NULL AUTO_INCREMENT, + resource_rule_id bigint(20) NOT NULL, + threshold_expression varchar(2000) NOT NULL, + threshold_message varchar(2000) NOT NULL, + PRIMARY KEY (resource_threshold_id) +); + +CREATE TABLE RANGE_RULE ( + range_rule_id SERIAL PRIMARY KEY, + range_name VARCHAR(50) NOT NULL, + service_model VARCHAR(50) NOT NULL, + end_point_position VARCHAR(50) NOT NULL, + equipment_level VARCHAR(50) NOT NULL, + equipment_expression VARCHAR(2000) NOT NULL, + ranges VARCHAR(100) NOT NULL +); + +CREATE TABLE MAX_PORT_SPEED ( + max_port_speed_id SERIAL PRIMARY KEY, + image_file_name VARCHAR(50) NOT NULL, + end_point_position VARCHAR(50) NOT NULL, + interface_name VARCHAR(100) NOT NULL, + max_speed BIGINT NOT NULL, + unit VARCHAR(10) NOT NULL +); + +CREATE TABLE MAX_SERVER_SPEED ( + max_server_speed_id SERIAL PRIMARY KEY, + server_model VARCHAR(50) NOT NULL, + evc_count SMALLINT NOT NULL, + max_speed BIGINT NOT NULL, + unit VARCHAR(10) NOT NULL, + description VARCHAR(500) +); + +CREATE TABLE SERVICE_RESOURCE ( + service_resource_id SERIAL PRIMARY KEY, + service_instance_id VARCHAR(80) NOT NULL, + service_status VARCHAR(10) NOT NULL, + service_change_number SMALLINT NOT NULL, + resource_set_id VARCHAR(100) NOT NULL, + resource_union_id VARCHAR(100) NOT NULL +); + +ALTER TABLE SERVICE_RESOURCE ADD CONSTRAINT C1_SERVICE_RESOURCE CHECK (service_status IN ('Active', 'Pending')); +CREATE INDEX i1_service_resource ON SERVICE_RESOURCE (service_instance_id); +CREATE UNIQUE INDEX ak1_service_resource ON SERVICE_RESOURCE (service_instance_id, service_change_number); + +CREATE TABLE VPE_POOL ( + vpe_name VARCHAR(20) NOT NULL, + ipv4_oam_address VARCHAR(20) NOT NULL, + loopback0_ipv4_address VARCHAR(20) NOT NULL, + provisioning_status VARCHAR(10) NOT NULL, + aic_site_id VARCHAR(100) NOT NULL, + availability_zone VARCHAR(100) NOT NULL, + vlan_id_outer VARCHAR(20) NOT NULL, + vendor VARCHAR(20) NOT NULL, + physical_intf_name VARCHAR(40) NOT NULL, + physical_intf_speed VARCHAR(20) NOT NULL, + physical_intf_units VARCHAR(20) NOT NULL, + vpe_uuid VARCHAR(80) DEFAULT NULL, + vpe_id VARCHAR(80) DEFAULT NULL, + image_filename VARCHAR(100) DEFAULT NULL, + PRIMARY KEY (aic_site_id, vpe_name, availability_zone) +); + +CREATE TABLE VPLSPE_POOL ( + vplspe_name varchar(20) NOT NULL, + aic_site_id varchar(100) NOT NULL, + availability_zone varchar(100) NOT NULL, + physical_intf_name varchar(40) NOT NULL, + physical_intf_speed varchar(20) NOT NULL, + physical_intf_units varchar(20) NOT NULL, + loopback0_ipv4_address varchar(20) NOT NULL, + vlan_id_outer varchar(20) NOT NULL, + vplspe_uuid varchar(80) DEFAULT NULL, + image_filename varchar(100) DEFAULT NULL, + provisioning_status varchar(10) DEFAULT NULL, + vendor varchar(20) DEFAULT NULL, + PRIMARY KEY (vplspe_name, aic_site_id, availability_zone, physical_intf_name) +); + +CREATE TABLE VPE_LOCK ( + vpe_name varchar(20) NOT NULL, + vpn_lock varchar(20) NOT NULL, + PRIMARY KEY (vpe_name) +); + +CREATE TABLE PARAMETERS ( + name varchar(100) PRIMARY KEY, + value varchar(24) NOT NULL, + category varchar(24) NOT NULL, + memo varchar(128) +); + +CREATE TABLE PSERVER ( + hostname varchar(255) NOT NULL, + ptnii_equip_name varchar(255), + number_of_cpus varchar(255), + disk_in_gigabytes varchar(255), + ram_in_megabytes varchar(255), + equip_type varchar(255), + equip_vendor varchar(255), + equip_model varchar(255), + fqdn varchar(255), + pserver_selflink varchar(255), + ipv4_oam_address varchar(15), + serial_number varchar(255), + pserver_id varchar(255), + internet_topology varchar(40), + aic_site_id varchar(100), + in_maint varchar(5), + pserver_name2 varchar(255), + purpose varchar(255), + PRIMARY KEY (hostname) +); diff --git a/resource-assignment/provider/src/test/resources/test-context.xml b/resource-assignment/provider/src/test/resources/test-context.xml new file mode 100644 index 000000000..ecebec723 --- /dev/null +++ b/resource-assignment/provider/src/test/resources/test-context.xml @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:jdbc="http://www.springframework.org/schema/jdbc" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.1.xsd + http://www.springframework.org/schema/jdbc + http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-3.1.xsd + "> + + <context:annotation-config /> + + <!-- JDBC setup --> + + <bean id="test.dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" + lazy-init="false" primary="true"> + <property name="driverClassName" value="org.h2.Driver" /> + <property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=MySQL" /> + </bean> + + <jdbc:initialize-database data-source="test.dataSource"> + <jdbc:script location="sql/schema.sql" /> + <jdbc:script location="sql/data.sql" /> + </jdbc:initialize-database> + + <bean id="lock.dataSource" class="org.onap.ccsdk.sli.adaptors.util.db.CachedDataSourceWrap"> + <property name="dataSource" ref="test.dataSource" /> + </bean> + + <bean id="rm.jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" primary="true"> + <property name="dataSource" ref="test.dataSource" /> + </bean> + + <bean id="lock.jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> + <property name="dataSource" ref="lock.dataSource" /> + </bean> + + <bean id="testDb" class="jtest.util.org.onap.ccsdk.sli.adaptors.ra.TestDb"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="dataSetup" class="jtest.org.onap.ccsdk.sli.adaptors.ra.DataSetup"> + <property name="testDb" ref="testDb" /> + </bean> + + <!-- Resource Lock Configuration --> + + <bean id="resourceLockDao" class="org.onap.ccsdk.sli.adaptors.lock.dao.ResourceLockDaoImpl"> + <property name="jdbcTemplate" ref="lock.jdbcTemplate" /> + </bean> + + <bean id="lockHelper" class="org.onap.ccsdk.sli.adaptors.lock.comp.LockHelperImpl"> + <property name="resourceLockDao" ref="resourceLockDao" /> + <property name="retryCount" value="10" /> + <property name="lockWait" value="5" /> <!-- Seconds --> + </bean> + + <!-- RM Configuration --> + + <bean id="resourceJdbcDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.ResourceJdbcDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="allocationItemJdbcDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.AllocationItemJdbcDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="resourceLoadJdbcDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.ResourceLoadJdbcDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="resourceDao" class="org.onap.ccsdk.sli.adaptors.rm.dao.jdbc.ResourceDaoImpl"> + <property name="resourceJdbcDao" ref="resourceJdbcDao" /> + <property name="allocationItemJdbcDao" ref="allocationItemJdbcDao" /> + <property name="resourceLoadJdbcDao" ref="resourceLoadJdbcDao" /> + </bean> + + <bean id="resourceManager" class="org.onap.ccsdk.sli.adaptors.rm.comp.ResourceManagerImpl"> + <property name="lockHelper" ref="lockHelper" /> + <property name="resourceDao" ref="resourceDao" /> + <property name="lockTimeout" value="600" /> <!-- Seconds --> + </bean> + + <!-- Rule DAO Configuration --> + + <bean id="resourceRuleDao" class="org.onap.ccsdk.sli.adaptors.ra.rule.dao.ResourceRuleDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <bean id="rangeRuleDao" class="org.onap.ccsdk.sli.adaptors.ra.rule.dao.RangeRuleDaoImpl"> + <property name="jdbcTemplate" ref="rm.jdbcTemplate" /> + </bean> + + <!-- ResourceAllocator Configuration --> + + <bean id="resourceAllocator" class="org.onap.ccsdk.sli.adaptors.ra.ResourceAllocator"> + <property name="resourceManager" ref="resourceManager" /> + <property name="endPointAllocator" ref="endPointAllocator" /> + <property name="speedUtil" ref="speedUtil" /> + </bean> + + <bean id="resourceLockNode" class="org.onap.ccsdk.sli.adaptors.ra.ResourceLockNode"> + <property name="lockHelper" ref="lockHelper" /> + </bean> + + <bean id="speedUtil" class="org.onap.ccsdk.sli.adaptors.util.speed.SpeedUtil" /> + + <!-- EndPointAllocator Configuration --> + + <bean id="endPointAllocator" class="org.onap.ccsdk.sli.adaptors.ra.comp.EndPointAllocatorImpl"> + <property name="resourceManager" ref="resourceManager" /> + <property name="allocationRuleMap"> + <map> + <entry key="DEFAULT"> + <list> + <ref bean="dbAllocationRule" /> + </list> + </entry> + </map> + </property> + </bean> + + <!-- Resource Allocation Rule Configuration --> + + <bean id="dbAllocationRule" class="org.onap.ccsdk.sli.adaptors.ra.alloc.DbAllocationRule"> + <property name="resourceRuleDao" ref="resourceRuleDao" /> + <property name="rangeRuleDao" ref="rangeRuleDao" /> + </bean> + +</beans> diff --git a/saltstack-adapter/.pydevproject b/saltstack-adapter/.pydevproject new file mode 100644 index 000000000..d001f0aea --- /dev/null +++ b/saltstack-adapter/.pydevproject @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?eclipse-pydev version="1.0"?><pydev_project> +<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property> +<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python interpreter</pydev_property> +</pydev_project> diff --git a/saltstack-adapter/README.md b/saltstack-adapter/README.md new file mode 100644 index 000000000..9c00457b3 --- /dev/null +++ b/saltstack-adapter/README.md @@ -0,0 +1,137 @@ +This source repository contains the code for the CCSDK plugins. + +To compile this code: + +1. Make sure your local Maven settings file ($HOME/.m2/settings.xml) contains references to the ONAP repositories and OpenDaylight repositories. See example-settings.xml for an example. + +2. To compile, run "mvn clean install". + + +***SaltStack Adaptor:*** CCSDK SLI ADAPTORS to support SaltStack server: + +***Connection from CCSDK SLI ADAPTOR Adaptor to SaltStack server:*** + +Create an Adaptor to communicate with the SaltStack server: +1) SaltStack server doesn’t expose any REST API unlike Chef. +2) SSH based communication with the SaltStack server, one command at a time (preferred). This will mean that SaltStack server should have it’s SSH enabled. +3) Create a REST-wrap around SaltStack server like is done for Ansible server. + +***SSH based communication:*** +1) Adaptor can execute commands on the Salt Master and bring back the result and put to the context memory for DG based analysis. (https://docs.saltstack.com/en/latest/ref/modules/all/index.html#all-salt-modules). +2) This can be useful for several reasons, for instance it might be useful to know the interfaces in the minions before executing certain network config based commands. This can simple be done by running, 'salt '*' network.interfaces' on server. +3) SaltStack Server, Output module support: The json-out outputter can be used to display the return data in JSON format. So the DG can put this onto context memory for execution. https://docs.saltstack.com/en/latest/ref/output/all/index.html#all-salt-output +4) Since the command execution on server might take time, a thread can be spawn to make a single SSH command execution in a SYNC manner. The thread executes the command and brings back the result and puts to the context memory for DG’s access. +5) For some specific executions operations like configure and upgrade, each configuration execution on the server will be handled by 2 or more SSH command execution. (1 for sending configuration and another for verifying the result). This will give the DGs and Saltstack adaptor with more control on the SaltStack server. + +***SaltState (SLS) file for execution on the SaltStack server:*** + The desired SLS file can be executed by one of the following three ways: +1) The SLS file for VNF configuration can be assumed to be already on the server, similar to Ansible. In this case, no addition requirements are necessary. We would already know the name of SLS file to execute so the configuration is performed on the VNF. +2) SLS file creation using DG: Create a DG to parse the configuration and create an SLS file using adaptors such as FileRecorder. Then this SLS file can be passed to the adaptor, so the adaptor can send the configuration to server. The adaptor can also send a SLS file to the Saltstack server and then run the command to execute it. +3) Third option is for the configuration SLS file that is to be sent to the VNF after instantiation is attached at the design time. This SLS formula- SaltStack file can be picked up and stored in the DB, as part of UEB listener. This can then be sent to adaptor using DGs. + +***Requirements and benefits of the chosen SSH method:*** +1) The SaltStack server should have it’s SSH enabled. +2) Via ssh user account we should have the access to run saltstack command. +3) Such execution method will give the DGs and adaptor with more refined control on the SaltStack server. +================================================================================================================== + + +***Defining Saltstack server properties:*** Can be done with 2 different methods. +1) Saltstack server details are found in the property file named saltstack-adapter.properties. Param has to be given with following types. + "org.onap.appc.adapter.saltstack.clientType"; -> Supported types are (BASIC || SSH_CERT || BOTH). + "org.onap.appc.adapter.saltstack.host"; -> Saltstack server's host name IP address. + "org.onap.appc.adapter.saltstack.port"; -> Saltstack server's port to make SSH connection to. + "org.onap.appc.adapter.saltstack.userName"; -> Saltstack server's SSH UserName. + "org.onap.appc.adapter.saltstack.userPasswd"; -> Saltstack server's SSH Password. + "org.onap.appc.adapter.saltstack.sshKey"; -> Saltstack server's SSH KEY file location. +2) All the server related details can also be passed as param to the adaptor from the Directed Graphs. Param has to be given with following types. + "HostName"; -> Saltstack server's host name IP address. + "Port"; -> Saltstack server's port to make SSH connection to. + "Password"; -> Saltstack server's SSH UserName. + "User"; -> Saltstack server's SSH Password. + "withRetry"; -> Specify 'true' if you wanna connect to server with retry. + Note: SSH_CERT based Auth is not supported in this method. + +***Using Saltstack Adaptor Commands and params to pass in: reqExecCommand API:*** + +Method to execute a single command on SaltState server and execute a SLS file located on the server. The command entered should request the output in JSON format, this can be done by appending json-out outputter as specified in https://docs.saltstack.com/en/latest/ref/output/all/salt.output.json_out.html#module-salt.output.json_out and https://docs.saltstack.com/en/2017.7/ref/cli/salt-call.html +The response from Saltstack comes in json format and it is automatically put to context for DGs access, with a certain request-ID as prefix. +If Id is not passed as part of input param, then a random Id will be generated and put to properties in "org.onap.appc.adapter.saltstack.Id" field. All the output message from the execution will be appended with reqId. +1) Execute a single command on SaltState server : Example command will look like: +1.1) Command to test if all VNFC are running: "salt '*' test.ping --out=json --static" +1.2) To check Network interfaces on your minions: "salt '*' network.interfaces --out=json --static" +1.3) Restart Minion service after upgrade process: "salt minion1 service.restart salt-minion --out=json --static" +Note: If using --out=json, you will probably want --static as well. Without the static option, you will get a separate JSON string per minion which makes JSON output invalid as a whole. This is due to using an iterative outputter. So if you want to feed it to a JSON parser, use --static as well. + +This "reqExecCommand" method gives the Operator/Directed Graphs to execute commands in a fine-tuned manner, which also means the operator/DG-creator should know what to expect as output as a result of command execution (for both success/failure case). +By this way using DGs, the operator can check for success/failure of the executed comment. +If the output is not in JSON format, then the adaptor still tries to convert it into properties, in addition, params that will hold the command execution result for DG access are (note: this is just to check if the command was executed successfully on the server, this doesn't check the status of the command on saltstack server): +Result code at: org.onap.appc.adapter.saltstack.result.code (On success: This will be always be 250, means command execution was success but the result of the execution is unknown and is to be checked from ctx using DGs) +Message at: org.onap.appc.adapter.saltstack.message +Both user inputted/auto generated req Id at: org.onap.appc.adapter.saltstack.Id +To check the status of the command configuration on saltstack server: the user should exactly know what to look for in the context +so the user can identify if the configuration execution on the saltstack server succeded or not. +here for instance, in 1.1) the user should check if $reqId.<minion-name> is set to true in the context memory using DGs. + +2) Execute a SLS file located on the server : Example command will look like: +Knowing the saltstack server has vim.sls file located at "/srv/salt" directory then user can execute the following commands: +1.1) Command to run the vim.sls file on saltstack server: Cmd = "salt '*' state.apply vim --out=json --static" +1.2) Command to run the nettools.sls file on saltstack server: Cmd = "cd /srv/salt/; salt '*' state.apply <sls-file-name> --out=json --static" +Important thing to note: If the reqExecCommand is used to execute sls file then along with following, + "HostName"; -> Saltstack server's host name IP address. + "Port"; -> Saltstack server's port to make SSH connection to. + "Password"; -> Saltstack server's SSH UserName. + "User"; -> Saltstack server's SSH Password. +the param should contain, + "SlsExec"; -> this variable should be set to true. + "Timeout"; -> set large timeout if your SLS file will take large time to finish executing (in Seconds). + +In this case, params that will hold the command execution result for DG access in Key: +Result code at: org.onap.appc.adapter.saltstack.result.code (On success: This will be 200, this means the command was executed successfully and also configuration change made using the SLS file was also successful) +Message at: org.onap.appc.adapter.saltstack.message +Both user inputted/auto generated req Id at: org.onap.appc.adapter.saltstack.Id +The result code here will be the execution of configuration SLS file on the server. +NOTE: It would be better to use reqExecSLS, where you will only have to specify SLS file name on server to execute it. + + +***Using Saltstack Adaptor Commands and params to pass in: reqExecSLS API:*** + +Method to execute a single sls on SaltState server (Where the SLS file already located on the server). The command entered will only be the SLS file name and the output will be in JSON format automatically. +The response from Saltstack comes in json format and it is automatically put to context for DGs access, with a certain request-ID as prefix. +If request Id (Id) is not passed as part of input param, then a random Id will be generated and put to properties in "org.onap.appc.adapter.saltstack.Id" field. All the output message from the execution will be appended with reqId. +1) Execute a single command on SaltState server : Example command will look like: + In the context set the "SlsName" to "test.sls" + In the context set the "Timeout"; -> set large timeout if your SLS file will take large time to finish executing (in Seconds). + In the context set the "NodeList" to "minion1" //to the minions or VNFCs you want to apply the SLS file to. + "NodeList" can be empty or set to "*" is the SLS has to be applied to all the minions or VNFCs. + In the context set the "FileParameters: A JSON dictionary where keys are filenames and values are contents of files. The Saltstack Server will utilize this feature to generate files with keys as filenames and values as content. This attribute can be used to generate files that a SSL file may require as part of execution (Optional). + In the context set the "EnvParameters: A JSON dictionary which should list key value pairs to be passed to the Salstack command to run SLS. These values would correspond to instance specific parameters that a playbook may need to execute an action. + +In this case, params that will hold the command execution result for DG access in Key: +Result code at: org.onap.appc.adapter.saltstack.result.code (On success: This will be 200, this means the command was executed successfully and also configuration change made using the SLS file was also successful) +Message at: org.onap.appc.adapter.saltstack.message +Both user inputted/auto generated req Id at: org.onap.appc.adapter.saltstack.Id +The result code here will be the execution of configuration SLS file on the server. + +***Using Saltstack Adaptor Commands and params to pass in: reqExecSLSFile API:*** + +Method to execute a single sls on SaltState server (Where the SLS file in the adaptor). The command entered will only be the SLS file location on the APPC/ODL container and the output from server will be in JSON format automatically. +The response from Saltstack comes in json format and it is automatically put to context for DGs access, with a certain request-ID as prefix. +If request Id (Id) is not passed as part of input param, then a random Id will be generated and put to properties in "org.onap.appc.adapter.saltstack.Id" field. All the output message from the execution will be appended with reqId. +1) Execute a single command on SaltState server : Example command will look like: + In the context set the "SlsFile" to "/path/to/test.sls" //mention the path of the SLS file in ODL container. + In the context set the "Timeout"; -> set large timeout if your SLS file will take large time to finish executing (in Seconds). + In the context set the "NodeList" to "minion1" //to the minions or VNFCs you want to apply the SLS file to. + "NodeList" can be empty or set to 'minion*' (pattern matching) or set to "*" is the SLS has to be applied to all the minions or VNFCs. + In the context set the "FileParameters: A JSON dictionary where keys are filenames and values are contents of files. The Saltstack Server will utilize this feature to generate files with keys as filenames and values as content. This attribute can be used to generate files that a SSL file may require as part of execution (Optional). + In the context set the "EnvParameters: A JSON dictionary which should list key value pairs to be passed to the Salstack command to run SLS. These values would correspond to instance specific parameters that a playbook may need to execute an action. + +In this case, params that will hold the command execution result for DG access in Key: +Result code at: org.onap.appc.adapter.saltstack.result.code (On success: This will be 200, this means the command was executed successfully and also configuration change made using the SLS file was also successful) +Message at: org.onap.appc.adapter.saltstack.message +Both user inputted/auto generated req Id at: org.onap.appc.adapter.saltstack.Id +The result code here will be the execution of configuration SLS file on the server. + +Control the state system on the minion: by specifying Env Params (pillars) and Files. + +https://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.state.html
\ No newline at end of file diff --git a/saltstack-adapter/pom.xml b/saltstack-adapter/pom.xml new file mode 100644 index 000000000..de8a87b05 --- /dev/null +++ b/saltstack-adapter/pom.xml @@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2018 Samsung Electronics. 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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>saltstack-adaptor</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: saltstack-adapter</name> + <description>Abstractions to interact with Saltstack server via REST + </description> + + <modules> + <module>saltstack-adapter-provider</module> + <module>saltstack-adapter-installer</module> + </modules> + + <dependencyManagement> + <dependencies> + + <dependency> + <groupId>org.onap.appc</groupId> + <artifactId>saltstack-adapter-features</artifactId> + <version>${project.version}</version> + <type>xml</type> + <classifier>features</classifier> + </dependency> + + <dependency> + <groupId>org.onap.appc</groupId> + <artifactId>saltstack-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + + + </dependencies> + + + </dependencyManagement> + + <pluginRepositories> + <!-- Black Duck plugin dependencies --> + <pluginRepository> + <id>JCenter</id> + <name>JCenter Repository</name> + <url>http://jcenter.bintray.com</url> + </pluginRepository> + + </pluginRepositories> + + <build> + <plugins> + + <!-- Black duck plugin Not required for regular builds + <plugin> <groupId>com.blackducksoftware.integration</groupId> <artifactId>hub-maven-plugin</artifactId> + <version>1.4.0</version> <inherited>false</inherited> <configuration> <hubProjectName>${project.name}</hubProjectName> + <outputDirectory>${project.basedir}</outputDirectory> <deployHubBdio>false</deployHubBdio> + </configuration> <extensions>true</extensions> + <executions> + <execution> + <id>create-bdio-file</id> + <phase>package</phase> + <goals> + <goal>createHubOutput</goal> + </goals> + </execution> + </executions> + + </plugin> + --> + + </plugins> + </build> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + + </reporting> +</project> diff --git a/saltstack-adapter/saltstack-adapter-installer/pom.xml b/saltstack-adapter/saltstack-adapter-installer/pom.xml new file mode 100644 index 000000000..67e30fa02 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-installer/pom.xml @@ -0,0 +1,165 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2018 Samsung Electronics. 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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>saltstack-adapter-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: saltstack-adapter :: ${project.artifactId} + </name> + + <properties> + <application.name>ccsdk-saltstack-adapter</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories> + mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features + </features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>saltstack-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>true</appendAssemblyId> + <attach>true</attach> + <finalName> + stage/${application.name}-${project.version} + </finalName> + <descriptors> + <descriptor> + src/assembly/assemble_mvnrepo_zip.xml + </descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version} + </finalName> + <descriptors> + <descriptor> + src/assembly/assemble_installer_zip.xml + </descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory> + ${project.build.directory}/assembly/system + </outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>org.onap.ccsdk.sli.adaptors</includeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage + </outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts + </directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_installer_zip.xml b/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..d307e4f30 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,61 @@ +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2018 Samsung Electronics. 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + +</assembly> diff --git a/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml b/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..1b1bf0b6b --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,50 @@ +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2018 Samsung Electronics. 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/saltstack-adapter/saltstack-adapter-installer/src/main/resources/scripts/install-feature.sh b/saltstack-adapter/saltstack-adapter-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..38782cabb --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,42 @@ +### +# ============LICENSE_START======================================================= +# ONAP : APPC +# ================================================================================ +# Copyright (C) 2018 Samsung Electronics. 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/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/saltstack-adapter/saltstack-adapter-provider/.gitignore b/saltstack-adapter/saltstack-adapter-provider/.gitignore new file mode 100644 index 000000000..4e1ad823a --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/.gitignore @@ -0,0 +1,25 @@ +# ============LICENSE_START========================================== +# ONAP : CCSDK +# =================================================================== +# Copyright (C) 2017-2018 Samsung Electronics. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the License); +# you may not use this software 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/ +/target/ +/target-ide/ +/.settings/ diff --git a/saltstack-adapter/saltstack-adapter-provider/pom.xml b/saltstack-adapter/saltstack-adapter-provider/pom.xml new file mode 100644 index 000000000..4b6868179 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/pom.xml @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============LICENSE_START======================================================= + ONAP : CCSDK ================================================================================ + Copyright (C) 2017-2018 Samsung Electronics. 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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>saltstack-adapter-provider</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-adaptors :: saltstack-adapter :: ${project.artifactId} + </name> + + <properties> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-core-artifacts</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.2</version> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + + <!-- Needed to run SSH --> + <!-- VERSION CONFLICT !!!!! --> + <!-- OpenDaylight Fluorine comes with version 1.7.0 installed, which is not compatible --> + <!-- Code must be updated to use version 1.7.0 before this can be safely installed --> + <dependency> + <groupId>org.apache.sshd</groupId> + <artifactId>sshd-core</artifactId> + <version>1.7.0</version> + </dependency> + + <!-- Needed to run test cases --> + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-io</artifactId> + </dependency> + + <dependency> + <groupId>org.codehaus.jettison</groupId> + <artifactId>jettison</artifactId> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + </dependency> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-provider</artifactId> + </dependency> + + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + + </dependencies> +</project> diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java new file mode 100644 index 000000000..346910a39 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; + +import java.util.Map; + +/** + * This interface defines the operations that the Saltstack adapter exposes. + */ +public interface SaltstackAdapter extends SvcLogicJavaPlugin { + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + */ + String getAdapterName(); + + /* Method to post a single command request for execution on SaltState server + * The response from Saltstack comes in json format and it is automatically put + * to context for DGs access, with a certain prefix*/ + void reqExecCommand(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException; + + /* Method for execution of saltstack SLS command on SaltState server + * The response from Saltstack comes in json format and it is automatically put + * to context for DGs access, with a certain prefix*/ + void reqExecSLS(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException; + + /* When SLS file is created/available then this Method can be used to post + * the file to saltstack server and execute the SLS file on SaltState server + * The response from Saltstack comes in json format and it is automatically put + * to context for DGs access, with a certain prefix*/ + void reqExecSLSFile(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException; +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapterPropertiesProvider.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapterPropertiesProvider.java new file mode 100755 index 000000000..a6b707afc --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapterPropertiesProvider.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack; + +import java.util.Properties; + +public interface SaltstackAdapterPropertiesProvider { + + public Properties getProperties(); +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java new file mode 100644 index 000000000..48469fdd5 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java @@ -0,0 +1,172 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack.impl; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.onap.ccsdk.sli.adaptors.saltstack.model.SshException; +import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult; +import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResultCodes; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * Returns a custom SSH client + * - based on options + * - can create one with ssl using an X509 certificate that does NOT have a known CA + * - create one which trusts ALL SSL certificates + * - return default sshclient (which only trusts known CAs from default cacerts file for process) this is the default + * option + **/ +public class ConnectionBuilder { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ConnectionBuilder.class); + SshConnection sshConnection; + + /** + * Constructor that initializes an ssh client based on username and password + **/ + public ConnectionBuilder(String host, String port, String userName, String userPasswd) { + sshConnection = new SshConnection(host, Integer.parseInt(port), userName, userPasswd); + } + + /** + * Constructor that initializes an ssh client based on ssh certificate + * This is still not supported in 1.3.0 version + **/ + public ConnectionBuilder(String host, String port, String certFile) { + sshConnection = new SshConnection(host, Integer.parseInt(port), certFile); + } + + + /** + * 1. Connect to SSH server. + * 2. Exec remote command over SSH. Return command execution status. + * Command output is written to out or err stream. + * + * @param cmd Commands to execute + * @return command execution status + */ + public SaltstackResult connectNExecute(String cmd, long execTimeout) throws IOException { + return connectNExecute(cmd, false, execTimeout); + } + + /** + * 1. Connect to SSH server with retry enabled. + * 2. Exec remote command over SSH. Return command execution status. + * Command output is written to out or err stream. + * + * @param cmd Commands to execute + * @param withRetry make a SSH connection with default retry. + * @return command execution status + */ + public SaltstackResult connectNExecute(String cmd, boolean withRetry, long execTimeout) + throws IOException { + + SaltstackResult result = new SaltstackResult(); + ByteArrayOutputStream out = null; + ByteArrayOutputStream errs = null; + if (execTimeout >= 0) { + sshConnection.setExecTimeout(execTimeout); + } + + try { + if (withRetry) { + sshConnection.connectWithRetry(); + } else { + sshConnection.connect(); + } + out = new ByteArrayOutputStream(); + errs = new ByteArrayOutputStream(); + int resultCode = sshConnection.execCommand(cmd, out, errs); + sshConnection.disconnect(); + if (resultCode != 0) { + return sortExitStatus(resultCode, errs.toString(), cmd); + } + result.setStatusCode(SaltstackResultCodes.SUCCESS.getValue()); + result.setStatusMessage("Success"); + result.setOutputMessage(out); + } catch (SshException io) { + if (io.toString().equalsIgnoreCase("Authentication failed")) { + logger.error(io.toString()); + result.setStatusCode(SaltstackResultCodes.USER_UNAUTHORIZED.getValue()); + result.setStatusMessage(io.toString()); + return result; + } + logger.error("Caught Exception", io); + result.setStatusCode(SaltstackResultCodes.SSH_EXCEPTION.getValue()); + result.setStatusMessage(io.getMessage()); + } catch (Exception io) { + logger.error("Caught Exception", io); + result.setStatusCode(SaltstackResultCodes.SSH_EXCEPTION.getValue()); + result.setStatusMessage(io.getMessage()); + } finally { + if (out != null) { + out.close(); + } + if (errs != null) { + errs.close(); + } + } + return result; + } + + /** + * Print Reasonable error messages based on SSH Exit status code + * */ + public SaltstackResult sortExitStatus(int exitStatus, String errMess, String cmd) { + SaltstackResult result = new SaltstackResult(); + if (exitStatus == 255 || exitStatus == 1) { + String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString() + + "]. Exit Code " + exitStatus + " and Error message : " + + "Malformed configuration. " + errMess; + logger.error(errMessage); + result.setStatusCode(SaltstackResultCodes.INVALID_COMMAND.getValue()); + result.setStatusMessage(errMessage); + } else if (exitStatus == 5 || exitStatus == 65) { + String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString() + + "]. Exit Code " + exitStatus + " and Error message : " + + "Host not allowed to connect. " + errMess; + logger.error(errMessage); + result.setStatusCode(SaltstackResultCodes.USER_UNAUTHORIZED.getValue()); + result.setStatusMessage(errMessage); + } else if (exitStatus == 67 || exitStatus == 73) { + String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString() + + "]. Exit Code " + exitStatus + " and Error message : " + + "Key exchange failed. " + errMess; + logger.error(errMessage); + result.setStatusCode(SaltstackResultCodes.CERTIFICATE_ERROR.getValue()); + result.setStatusMessage(errMessage); + } else { + String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString() + + "]. Exit Code " + exitStatus + " and Error message : " + errMess; + logger.error(errMessage); + result.setStatusCode(SaltstackResultCodes.UNKNOWN_EXCEPTION.getValue()); + result.setStatusMessage(errMessage); + } + return result; + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java new file mode 100644 index 000000000..34321ea59 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java @@ -0,0 +1,446 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack.impl; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapter; +import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapterPropertiesProvider; +import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackMessageParser; +import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult; +import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResultCodes; +import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackServerEmulator; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Properties; + +/** + * This class implements the {@link SaltstackAdapter} interface. This interface defines the behaviors + * that our service provides. + */ +public class SaltstackAdapterImpl implements SaltstackAdapter { + + /** + * The constant for the status code for a failed outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_FAILURE = "failure"; + /** + * The constant for the status code for a successful outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_SUCCESS = "success"; + public static final String CONNECTION_RETRY = "withRetry"; + private static final String APPC_EXCEPTION_CAUGHT = "APPCException caught"; + /** + * Adapter Name + */ + private static final String ADAPTER_NAME = "Saltstack Adapter"; + private static final String RESULT_CODE_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.result.code"; + private static final String MESSAGE_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.message"; + private static final String ID_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.Id"; + private static final String CLIENT_TYPE_PROPERTY_NAME = "org.onap.appc.adapter.saltstack.clientType"; + private static final String SS_SERVER_HOSTNAME = "org.onap.appc.adapter.saltstack.host"; + private static final String SS_SERVER_PORT = "org.onap.appc.adapter.saltstack.port"; + private static final String SS_SERVER_USERNAME = "org.onap.appc.adapter.saltstack.userName"; + private static final String SS_SERVER_PASSWD = "org.onap.appc.adapter.saltstack.userPasswd"; + private static final String SS_SERVER_SSH_KEY = "org.onap.appc.adapter.saltstack.sshKey"; + + private static final String COMMAND_IN_JSON_OUT = " --out=json --static "; + private static final String COMMAND_CHANGE_DEFAULT_DIR = " cd /srv/salt/ ;"; + + /** + * The logger to be used + */ + private static final EELFLogger logger = EELFManager.getInstance().getLogger(SaltstackAdapterImpl.class); + /** + * Connection object + **/ + private ConnectionBuilder sshClient; + + /** + * Saltstack API Message Handlers + **/ + private SaltstackMessageParser messageProcessor; + + /** + * indicator whether in test mode + **/ + private boolean testMode = false; + + /** + * server emulator object to be used if in test mode + **/ + private SaltstackServerEmulator testServer; + + /** + * This default constructor is used as a work around because the activator wasn't getting called + */ + public SaltstackAdapterImpl() throws SvcLogicException { + initialize(new SaltstackAdapterPropertiesProviderImpl()); + } + + public SaltstackAdapterImpl(SaltstackAdapterPropertiesProvider propProvider) throws SvcLogicException { + initialize(propProvider); + } + + /** + * Used for jUnit test and testing interface + */ + public SaltstackAdapterImpl(boolean mode) { + testMode = mode; + testServer = new SaltstackServerEmulator(); + messageProcessor = new SaltstackMessageParser(); + } + + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + * @see SaltstackAdapter#getAdapterName() + */ + @Override + public String getAdapterName() { + return ADAPTER_NAME; + } + + /** + * Method posts info to Context memory in case of an error and throws a + * SvcLogicException causing SLI to register this as a failure + */ + @SuppressWarnings("static-method") + private void doFailure(SvcLogicContext svcLogic, int code, String message) throws SvcLogicException { + logger.error(APPC_EXCEPTION_CAUGHT, message); + svcLogic.setStatus(OUTCOME_FAILURE); + svcLogic.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(code)); + svcLogic.setAttribute(MESSAGE_ATTRIBUTE_NAME, message); + throw new SvcLogicException("Saltstack Adapter Error = " + message); + } + + /** + * initialize the Saltstack adapter based on default and over-ride configuration data + */ + private void initialize(SaltstackAdapterPropertiesProvider propProvider) throws SvcLogicException { + + + Properties props = propProvider.getProperties(); + + // Create the message processor instance + messageProcessor = new SaltstackMessageParser(); + + // Create the ssh client instance + // type of client is extracted from the property file parameter + // org.onap.appc.adapter.saltstack.clientType + // It can be : + // 1. BASIC. SSH Connection using username and password + // 2. SSH_CERT (trust only those whose certificates have been stored in the SSH KEY file) + // 3. DEFAULT SSH Connection without any authentication + + try { + String clientType = props.getProperty(CLIENT_TYPE_PROPERTY_NAME); + logger.info("Saltstack ssh client type set to " + clientType); + + if ("BASIC".equalsIgnoreCase(clientType)) { + logger.info("Creating ssh client connection"); + // set path to keystore file + String sshHost = props.getProperty(SS_SERVER_HOSTNAME); + String sshPort = reqServerPort(props); + String sshUserName = props.getProperty(SS_SERVER_USERNAME); + String sshPassword = props.getProperty(SS_SERVER_PASSWD); + sshClient = new ConnectionBuilder(sshHost, sshPort, sshUserName, sshPassword); + } else if ("SSH_CERT".equalsIgnoreCase(clientType)) { + // set path to keystore file + String sshKey = props.getProperty(SS_SERVER_SSH_KEY); + String sshHost = props.getProperty(SS_SERVER_HOSTNAME); + String sshPort = reqServerPort(props); + logger.info("Creating ssh client with ssh KEY from " + sshKey); + sshClient = new ConnectionBuilder(sshHost, sshPort, sshKey); + } else { + logger.info("No saltstack-adapter.properties defined so reading from DG props"); + sshClient = null; + } + } catch (NumberFormatException e) { + logger.error("Error Initializing Saltstack Adapter due to Unknown Exception", e); + throw new SvcLogicException("Saltstack Adapter Property file parsing Error = port in property file has to be an integer."); + } catch (Exception e) { + logger.error("Error Initializing Saltstack Adapter due to Exception", e); + throw new SvcLogicException("Saltstack Adapter Property file parsing Error = " + e.getMessage()); + } + logger.info("Initialized Saltstack Adapter"); + } + + private String reqServerPort(Properties props) { + // use default port if null + if (props.getProperty(SS_SERVER_PORT) == null) { + return "22"; + } + return props.getProperty(SS_SERVER_PORT); + } + + private void setSSHClient(Map<String, String> params) throws SvcLogicException { + if (sshClient == null) { + logger.info("saltstack-adapter.properties not defined so reading saltstack host and " + + "auth details from DG's parameters"); + String sshHost = messageProcessor.reqHostNameResult(params); + String sshPort = messageProcessor.reqPortResult(params); + String sshUserName = messageProcessor.reqUserNameResult(params); + String sshPassword = messageProcessor.reqPasswordResult(params); + logger.info("Creating ssh client with BASIC Auth"); + if (!testMode) { + sshClient = new ConnectionBuilder(sshHost, sshPort, sshUserName, sshPassword); + } + } + } + + private String parseEnvParam(JSONObject envParams) { + StringBuilder envParamBuilder = new StringBuilder(); + if (envParams != null) { + for (Object key : envParams.keySet()) { + if (envParamBuilder.length() > 0) { + envParamBuilder.append(", "); + } + envParamBuilder.append(key + "=" + envParams.get((String) key)); + logger.info("EnvParameters : " + envParamBuilder); + } + } + return envParamBuilder.toString(); + } + + private String parseFileParam(JSONObject fileParams) { + StringBuilder fileParamBuilder = new StringBuilder(); + if (fileParams != null) { + for (Object key : fileParams.keySet()) { + fileParamBuilder.append("echo -e \"" + fileParams.get((String) key) + "\" > /srv/salt/" + key).append("; "); + logger.info("FileParameters : " + fileParamBuilder); + } + } + return fileParamBuilder.toString(); + } + + private String putToCommands(SvcLogicContext ctx, String slsFileName, + String applyTo, JSONObject envParams, JSONObject fileParams) throws SvcLogicException { + + StringBuilder constructedCommand = new StringBuilder(); + try { + File file = new File(slsFileName); + String slsFile = file.getName(); + if (!slsFile.substring(slsFile.lastIndexOf("."), + slsFile.length()).equalsIgnoreCase(".sls")) { + doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input file " + + "is not of type .sls"); + } + try(InputStream in = new FileInputStream(file)){ + byte[] data = new byte[(int) file.length()]; + in.read(data); + String str = new String(data, "UTF-8"); + String slsWithoutExtn = stripExtension(slsFile); + constructedCommand.append(parseFileParam(fileParams)).append("echo -e \"").append(str).append("\" > /srv/salt/"). + append(slsFile).append("; ").append(COMMAND_CHANGE_DEFAULT_DIR).append(" salt '"). + append(applyTo).append("' state.apply ").append(slsWithoutExtn).append(" ").append(parseEnvParam(envParams)).append(COMMAND_IN_JSON_OUT); + } + logger.info("Command to be executed on server : " + constructedCommand.toString()); + + } catch (FileNotFoundException e) { + doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input SLS file " + + "not found in path : " + slsFileName + ". " + e.getMessage()); + } catch (IOException e) { + doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input SLS file " + + "error in path : " + slsFileName + ". " + e.getMessage()); + } catch (StringIndexOutOfBoundsException e) { + doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input file " + + "is not of type .sls"); + } + return constructedCommand.toString(); + } + + private String stripExtension(String str) { + if (str == null) { + return null; + } + int pos = str.lastIndexOf("."); + if (pos == -1) { + return str; + } + return str.substring(0, pos); + } + + private String putToCommands(String slsName, String applyTo, JSONObject envParams, JSONObject fileParams) { + + StringBuilder constructedCommand = new StringBuilder(); + + constructedCommand.append(parseFileParam(fileParams)).append(COMMAND_CHANGE_DEFAULT_DIR).append(" salt '").append(applyTo) + .append("' state.apply ").append(slsName).append(" ").append(parseEnvParam(envParams)).append(COMMAND_IN_JSON_OUT); + + logger.info("Command to be executed on server : " + constructedCommand.toString()); + return constructedCommand.toString(); + } + + private void checkResponseStatus(SaltstackResult testResult, SvcLogicContext ctx, String reqID, boolean slsExec) + throws SvcLogicException { + + // Check status of test request returned by Agent + if (testResult.getStatusCode() != SaltstackResultCodes.FINAL_SUCCESS.getValue()) { + ctx.setAttribute(ID_ATTRIBUTE_NAME, reqID); + doFailure(ctx, testResult.getStatusCode(), "Request for execution of command failed. Reason = " + testResult.getStatusMessage()); + } else { + logger.info(String.format("Execution of request : successful.")); + ctx.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(testResult.getStatusCode())); + ctx.setAttribute(MESSAGE_ATTRIBUTE_NAME, OUTCOME_SUCCESS); + ctx.setAttribute(ID_ATTRIBUTE_NAME, reqID); + } + } + + // Public Method to post single command request to execute saltState. Posts the following back + // to Svc context memory + // org.onap.appc.adapter.saltstack.req.code : 100 if successful + // org.onap.appc.adapter.saltstack.req.messge : any message + // org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request + @Override + public void reqExecCommand(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + String reqID; + boolean slsExec; + SaltstackResult testResult; + setSSHClient(params); + try { + reqID = messageProcessor.reqId(params); + String commandToExecute = messageProcessor.reqCmd(params); + slsExec = messageProcessor.reqIsSLSExec(params); + long execTimeout = messageProcessor.reqExecTimeout(params); + testResult = execCommand(ctx, params, commandToExecute, execTimeout); + testResult = messageProcessor.parseResponse(ctx, reqID, testResult, slsExec); + checkResponseStatus(testResult, ctx, reqID, slsExec); + } catch (IOException e) { + doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), + "IOException in file stream : " + e.getMessage()); + } + } + + /** + * Public Method to post SLS command request to execute saltState on server. Posts the following back + * to Svc context memory + * <p> + * org.onap.appc.adapter.saltstack.req.code : 200 if successful + * org.onap.appc.adapter.saltstack.req.messge : any message + * org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request + */ + @Override + public void reqExecSLS(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + String reqID; + SaltstackResult testResult; + setSSHClient(params); + try { + reqID = messageProcessor.reqId(params); + String slsName = messageProcessor.reqSlsName(params); + String applyTo = messageProcessor.reqApplyToDevices(params); + long execTimeout = messageProcessor.reqExecTimeout(params); + JSONObject envParams = messageProcessor.reqEnvParameters(params); + JSONObject fileParams = messageProcessor.reqFileParameters(params); + + String commandToExecute = putToCommands(slsName, applyTo, envParams, fileParams); + testResult = execCommand(ctx, params, commandToExecute, execTimeout); + testResult = messageProcessor.parseResponse(ctx, reqID, testResult, true); + checkResponseStatus(testResult, ctx, reqID, true); + } catch (IOException e) { + doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), + "IOException in file stream : " + e.getMessage()); + } catch (JSONException e) { + doFailure(ctx, SaltstackResultCodes.INVALID_COMMAND.getValue(), e.getMessage()); + } + } + + /** + * Public Method to post SLS file request to execute saltState. Posts the following back + * to Svc context memory + * <p> + * org.onap.appc.adapter.saltstack.req.code : 100 if successful + * org.onap.appc.adapter.saltstack.req.messge : any message + * org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request + */ + @Override + public void reqExecSLSFile(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException { + String reqID; + SaltstackResult testResult; + setSSHClient(params); + try { + reqID = messageProcessor.reqId(params); + String slsFile = messageProcessor.reqSlsFile(params); + String applyTo = messageProcessor.reqApplyToDevices(params); + long execTimeout = messageProcessor.reqExecTimeout(params); + JSONObject envParams = messageProcessor.reqEnvParameters(params); + JSONObject fileParams = messageProcessor.reqFileParameters(params); + + String commandToExecute = putToCommands(ctx, slsFile, applyTo, envParams, fileParams); + testResult = execCommand(ctx, params, commandToExecute, execTimeout); + testResult = messageProcessor.parseResponse(ctx, reqID, testResult, true); + checkResponseStatus(testResult, ctx, reqID, true); + } catch (IOException e) { + doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), + "IOException in file stream : " + e.getMessage()); + } + } + + public SaltstackResult execCommand(SvcLogicContext ctx, Map<String, String> params, String commandToExecute, + long execTimeout) + throws SvcLogicException { + + //convert execTimeout to Milliseconds + execTimeout = execTimeout * 1000; + SaltstackResult testResult = new SaltstackResult(); + try { + if (params.get(CONNECTION_RETRY) == null) { + if (!testMode) { + testResult = sshClient.connectNExecute(commandToExecute, execTimeout); + } else { + testResult = testServer.mockReqExec(params); + } + } else if (params.get(CONNECTION_RETRY).equalsIgnoreCase("true")) { + if (!testMode) { + testResult = sshClient.connectNExecute(commandToExecute, true, execTimeout); + } else { + testResult = testServer.mockReqExec(params); + } + } else { + if (!testMode) { + testResult = sshClient.connectNExecute(commandToExecute, execTimeout); + } else { + testResult = testServer.mockReqExec(params); + } + } + } catch (IOException e) { + doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), + "IOException in file stream : " + e.getMessage()); + } + return testResult; + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java new file mode 100755 index 000000000..8f0d9857a --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java @@ -0,0 +1,192 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack.impl; + +import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapterPropertiesProvider; +import org.onap.ccsdk.sli.core.sli.ConfigurationException; +import org.onap.ccsdk.sli.core.utils.JREFileResolver; +import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver; +import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver; +import org.onap.ccsdk.sli.core.utils.common.CoreDefaultFileResolver; +import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; +import java.util.Properties; +import java.util.Vector; + +/** + * Responsible for determining the properties file to use and instantiating the + * <code>SqlResource</code> Service. The priority for properties file + * resolution is as follows: + * <p> + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>sql-resource.properties</code></li> + * <li>A <code>sql-resource.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ +public class SaltstackAdapterPropertiesProviderImpl implements SaltstackAdapterPropertiesProvider { + + private static final Logger LOG = LoggerFactory.getLogger(SaltstackAdapterPropertiesProviderImpl.class); + + /** + * The name of the properties file for database configuration + */ + private static final String SALTSTACKADAPTER_PROP_FILE_NAME = "saltstack-adapter.properties"; + + /** + * A prioritized list of strategies for resolving sql-resource properties files. + */ + private Vector<PropertiesFileResolver> saltstackAdapterPropertiesFileResolvers = new Vector<>(); + + /** + * The configuration properties for the db connection. + */ + private Properties properties; + + /** + * Set up the prioritized list of strategies for resolving dblib properties + * files. + */ + public SaltstackAdapterPropertiesProviderImpl() { + saltstackAdapterPropertiesFileResolvers + .add(new SdncConfigEnvVarFileResolver("Using property file (1) from environment variable")); + saltstackAdapterPropertiesFileResolvers.add(new CoreDefaultFileResolver("Using property file (2) from default directory")); + + saltstackAdapterPropertiesFileResolvers.add( + new JREFileResolver("Using property file (3) from JRE argument", SaltstackAdapterPropertiesProviderImpl.class)); + saltstackAdapterPropertiesFileResolvers.add(new KarafRootFileResolver("Using property file (4) from karaf root", this)); + + // determines properties file as according to the priority described in the + // class header comment + final File propertiesFile = determinePropertiesFile(this); + if (propertiesFile != null) { + try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) { + properties = new Properties(); + properties.load(fileInputStream); + } catch (final IOException e) { + LOG.error("Failed to load properties for file: {}", propertiesFile.toString(), + new ConfigurationException("Failed to load properties for file: " + propertiesFile.toString(), + e)); + } + } else { + // Try to read properties as resource + + InputStream propStr = getClass().getResourceAsStream("/" + SALTSTACKADAPTER_PROP_FILE_NAME); + if (propStr != null) { + properties = new Properties(); + try { + properties.load(propStr); + propStr.close(); + } catch (IOException e) { + properties = null; + } + } + + } + + if (properties == null) { + reportFailure("Missing configuration properties resource(3)", new ConfigurationException( + "Missing configuration properties resource(3): " + SALTSTACKADAPTER_PROP_FILE_NAME)); + + LOG.info("Defaulting org.onap.appc.adapter.saltstack.clientType to NONE"); + + properties = new Properties(); + properties.setProperty("org.onap.appc.adapter.saltstack.clientType", "NONE"); + } + } + + /** + * Reports the method chosen for properties resolution to the + * <code>Logger</code>. + * + * @param message Some user friendly message + * @param fileOptional The file location of the chosen properties file + * @return the file location of the chosen properties file + */ + private static File reportSuccess(final String message, final Optional<File> fileOptional) { + if (fileOptional.isPresent()) { + final File file = fileOptional.get(); + LOG.info("{} {}", message, file.getPath()); + return file; + } + return null; + } + + /** + * Reports fatal errors. This is the case in which no properties file could be + * found. + * + * @param message An appropriate fatal error message + * @param configurationException An exception describing what went wrong during resolution + */ + private static void reportFailure(final String message, final ConfigurationException configurationException) { + + LOG.error("{}", message, configurationException); + } + + /** + * Extract svclogic config properties. + * + * @return the svclogic config properties + */ + public Properties getProperties() { + return properties; + } + + /** + * Determines the sql-resource properties file to use based on the following priority: + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>sql-resource.properties</code></li> + * <li>A <code>sql-resource.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ + File determinePropertiesFile(final SaltstackAdapterPropertiesProviderImpl resourceProvider) { + + for (final PropertiesFileResolver sliPropertiesFileResolver : saltstackAdapterPropertiesFileResolvers) { + final Optional<File> fileOptional = sliPropertiesFileResolver.resolveFile(SALTSTACKADAPTER_PROP_FILE_NAME); + if (fileOptional.isPresent()) { + return reportSuccess(sliPropertiesFileResolver.getSuccessfulResolutionMessage(), fileOptional); + } + } + + return null; + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java new file mode 100644 index 000000000..25d2d8402 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java @@ -0,0 +1,217 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack.impl; + +import java.io.OutputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.KeyPair; +import org.apache.sshd.client.SshClient; +import org.apache.sshd.client.channel.ChannelExec; +import org.apache.sshd.client.future.AuthFuture; +import org.apache.sshd.client.future.OpenFuture; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.common.keyprovider.FileKeyPairProvider; +import org.apache.sshd.common.keyprovider.KeyPairProvider; +import org.onap.ccsdk.sli.adaptors.saltstack.model.Constants; +import org.onap.ccsdk.sli.adaptors.saltstack.model.SshException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +/** + * Implementation of SshConnection interface based on Apache MINA SSHD library. + */ +class SshConnection { + + private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + + private static final long AUTH_TIMEOUT = 60000; + private static final long EXEC_TIMEOUT = 120000; + private String host; + private int port; + private String username; + private String password; + private long timeout = EXEC_TIMEOUT; + private String keyFile; + private SshClient sshClient; + private ClientSession clientSession; + + public SshConnection(String host, int port, String username, String password, String keyFile) { + this.host = host; + this.port = port; + this.username = username; + this.password = password; + this.keyFile = keyFile; + } + + public SshConnection(String host, int port, String username, String password) { + this(host, port, username, password, null); + } + + public SshConnection(String host, int port, String keyFile) { + this(host, port, null, null, keyFile); + } + + public void connect() { + sshClient = SshClient.setUpDefaultClient(); + sshClient.start(); + try { + clientSession = + sshClient.connect(username, host, port).getSession(); + if (password != null) { + clientSession.addPasswordIdentity(password); + } else if (keyFile != null) { + Path keyFilePath = Paths.get(keyFile); + KeyPairProvider keyPairProvider = new FileKeyPairProvider(keyFilePath); + KeyPair keyPair = keyPairProvider.loadKeys().iterator().next(); + clientSession.addPublicKeyIdentity(keyPair); + } + AuthFuture authFuture = clientSession.auth(); + authFuture.await(AUTH_TIMEOUT); + if (!authFuture.isSuccess()) { + throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + + "]. Authentication failed."); + } + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "].", + e); + } + if (logger.isDebugEnabled()) { + logger.debug("SSH: connected to [" + toString() + "]"); + } + } + + public void connectWithRetry() { + int retryCount; + int retryDelay; + int retriesLeft; + retryCount = Constants.DEFAULT_CONNECTION_RETRY_COUNT; + retryDelay = Constants.DEFAULT_CONNECTION_RETRY_DELAY; + retriesLeft = retryCount + 1; + do { + try { + this.connect(); + break; + } catch (RuntimeException e) { + if (retriesLeft > 1) { + logger.debug("SSH Connection failed. Waiting for change in server's state."); + waitForConnection(retryDelay); + retriesLeft--; + logger.debug("Retrying SSH connection. Attempt [" + Integer.toString(retryCount - retriesLeft + 1) + + "] out of [" + retryCount + "]"); + } else { + throw e; + } + } + } while (retriesLeft > 0); + } + + public void disconnect() { + try { + if (logger.isDebugEnabled()) { + logger.debug("SSH: disconnecting from [" + toString() + "]"); + } + clientSession.close(false); + } finally { + if (sshClient != null) { + sshClient.stop(); + } + } + } + + public void setExecTimeout(long timeout) { + this.timeout = timeout; + } + + public int execCommand(String cmd, OutputStream out, OutputStream err) { + return execCommand(cmd, out, err, false); + } + + public int execCommandWithPty(String cmd, OutputStream out) { + return execCommand(cmd, out, out, true); + } + + private int execCommand(String cmd, OutputStream out, OutputStream err, boolean usePty) { + try { + if (logger.isDebugEnabled()) { + logger.debug("SSH: executing command"); + } + ChannelExec client = clientSession.createExecChannel(cmd); + client.setUsePty(usePty); // use pseudo-tty? + client.setOut(out); + client.setErr(err); + OpenFuture openFuture = client.open(); + int exitStatus; + try { + client.wait(timeout); + openFuture.verify(); + Integer exitStatusI = client.getExitStatus(); + if (exitStatusI == null) { + throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host + + ":" + port + "]. Operation timed out."); + } + exitStatus = exitStatusI; + } finally { + client.close(false); + } + return exitStatus; + } catch (RuntimeException e) { + throw e; + } catch (Exception e1) { + throw new SshException( + "Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]", e1); + } + } + + private void waitForConnection(int retryDelay) { + long time = retryDelay * 1000L; + long future = System.currentTimeMillis() + time; + if (time != 0) { + while (System.currentTimeMillis() < future && time > 0) { + try { + Thread.sleep(time); + } catch (InterruptedException e) { + /* + * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that + * case, the thread is resumed before the delay time has actually expired, so re-calculate the + * amount of delay time needed and reenter the sleep until we get to the future time. + */ + time = future - System.currentTimeMillis(); + } + } + } + } + + @Override + public String toString() { + String address = host; + if (username != null) { + address = username + '@' + address + ':' + port; + } + return address; + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/Constants.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/Constants.java new file mode 100644 index 000000000..a1826c4e1 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/Constants.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.saltstack.model; + +public class Constants { + public static final String NETCONF_SCHEMA = "sdnctl"; + public static final String SDNCTL_SCHEMA = "sdnctl"; + public static final String DEVICE_AUTHENTICATION_TABLE_NAME = "DEVICE_AUTHENTICATION"; + public static final String CONFIGFILES_TABLE_NAME = "CONFIGFILES"; + public static final String DEVICE_INTERFACE_LOG_TABLE_NAME = "DEVICE_INTERFACE_LOG"; + public static final String FILE_CONTENT_TABLE_FIELD_NAME = "FILE_CONTENT"; + public static final String FILE_NAME_TABLE_FIELD_NAME = "FILE_NAME"; + public static final String USER_NAME_TABLE_FIELD_NAME = "USER_NAME"; + public static final String PASSWORD_TABLE_FIELD_NAME = "PASSWORD"; + public static final String PORT_NUMBER_TABLE_FIELD_NAME = "PORT_NUMBER"; + public static final String VNF_TYPE_TABLE_FIELD_NAME = "VNF_TYPE"; + public static final String SERVICE_INSTANCE_ID_FIELD_NAME = "SERVICE_INSTANCE_ID"; + public static final String REQUEST_ID_FIELD_NAME = "REQUEST_ID"; + public static final String CREATION_DATE_FIELD_NAME = "CREATION_DATE"; + public static final String LOG_FIELD_NAME = "LOG"; + public static final String SDC_ARTIFACTS_TABLE_NAME = "ASDC_ARTIFACTS"; + public static final String PAYLOAD = "payload"; + public static final String CONNECTION_RETRY_DELAY = "org.onap.appc.ssh.connection.retry.delay"; + public static final String CONNECTION_RETRY_COUNT = "org.onap.appc.ssh.connection.retry.count"; + public static final int DEFAULT_CONNECTION_RETRY_DELAY = 60; + public static final int DEFAULT_CONNECTION_RETRY_COUNT = 5; + public static final int DEFAULT_SSH_COMMAND_RETRY_COUNT = 3; + public static final int DEFAULT_CHECKACTIVE_RETRY_COUNT = 3; + public static final int DEFAULT_CHECKACTIVE_RETRY_DELAY = 30; + public static final int DEFAULT_STOP_RETRY_COUNT = 3; + public static final int DEFAULT_STOP_RETRY_DELAY = 30; + public static final String PARAM_IN_CONNECTION_DETAILS = "connection-details"; + public static final String PARAM_IN_NODE_NAME = "node-name"; + public static final String PARAM_IN_NODE_STATUS = "node-status"; + public static final String PARAM_IN_VM_URL = "vm-url"; + public static final String SKIP_EXECUTION_INSTALLER_BIN_FILE = "Skip-execution-installer-bin-file"; + public static final String SKIP_DEPLOY = "Skip-deploy"; + public static final String UPGRADE_VERSION = "upgrade-version"; + public static final String STATE_COMMAND = "/opt/jnetx/skyfall-scp/asp-state.sh | grep -o UP | wc -l"; + public static final String VNFC_STATE_COMMAND = "/opt/jnetx/skyfall-scp/asp-state.sh"; + public static final String RESTART_NODE_COMMAND = "/opt/jnetx/skyfall-scp/asp-stop.sh --restart -f --nodes"; + public static final String START_NODE_COMMAND = "/opt/jnetx/skyfall-scp/asp-start.sh -f --nodes"; + public static final String STOP_NODE_COMMAND = "/opt/jnetx/skyfall-scp/asp-stop.sh -f --nodes"; + public static final int STATE_COMMAND_RESULT = 18; + public static final String FE_STATE_TRUE_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o TRUE | wc -l"; + public static final int FE_STATE_TRUE_TEST_RESULT = 22; + public static final String FE_STATE_FALSE_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o FALSE | wc -l"; + public static final int FE_STATE_FALSE_TEST_RESULT = 2; + public static final String FE_OPERATIONAL_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o 'NOT FULLY OPERATIONAL' | wc -l"; + public static final int FE_OPERATIONAL_TEST_RESULT = 2; + public static final String SMP_CHECK_ACTIVE_STATE_COMMAND = "cat skyfall-scp/runtime/SCP_SMP_*/smp/log/system.log| grep SSS | tail -1"; + public static final String SMP_STATE_ACTIVE = "SMP is active"; + public static final String SMP_STATE_INACTIVE = "SMP is not active"; + public static final String RSYNC_COMMAND = "yes n | /opt/jnetx/skyfall-scp/asp-rsync.sh --check | grep -o 'is active' | wc -l"; + public static final int RSYNC_COMMAND_RESULT = 9; + public static final String PARAM_IN_TIMEOUT = "timeout"; + public static final String PARAM_IN_FILE_URL = "source-file-url"; + public static final String DOWNLOAD_COMMAND = "wget -N %s"; + public static final String[] VM_NAMES = new String[]{"fe1", "fe2", "be1", "be2", "be3", "be4", "be5", "smp1", "smp2"}; + public static final String DEFAULT_DISK_SPACE = "10240000"; + public static final String DF_COMMAND_TEMPLATE = "ssh %s df | grep vda1 | grep -v grep | tr -s ' '|cut -d ' ' -f4"; + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + public static final String ATTRIBUTE_ERROR_MESSAGE = "error-message"; + public static final String CONNECTION_DETAILS_FIELD_NAME = "connection-details"; + public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address"; + public static final String VNF_HOST_IP2_ADDRESS_FIELD_NAME = "vnf-host-ip2-address"; + public static final String DG_ERROR_FIELD_NAME = "org.openecom.appc.dg.error"; + + private Constants() { + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java new file mode 100644 index 000000000..3eb353a17 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack.model; + +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import static com.google.common.base.Preconditions.checkNotNull; + +public final class JsonParser { + + private static final Logger log = LoggerFactory.getLogger(JsonParser.class); + + private JsonParser() { + // Preventing instantiation of the same. + } + + @SuppressWarnings("unchecked") + public static Map<String, String> convertToProperties(String s) + throws JSONException { + + checkNotNull(s, "Input should not be null."); + + JSONObject json = new JSONObject(s); + Map<String, Object> wm = new HashMap<>(); + Iterator<String> ii = json.keys(); + while (ii.hasNext()) { + String key1 = ii.next(); + wm.put(key1, json.get(key1)); + } + + Map<String, String> mm = new HashMap<>(); + + while (!wm.isEmpty()) + for (String key : new ArrayList<>(wm.keySet())) { + Object o = wm.get(key); + wm.remove(key); + + if (o instanceof Boolean || o instanceof Number || o instanceof String) { + mm.put(key, o.toString()); + + log.info("Added property: {} : {}", key, o.toString()); + } else if (o instanceof JSONObject) { + JSONObject jo = (JSONObject) o; + Iterator<String> i = jo.keys(); + while (i.hasNext()) { + String key1 = i.next(); + wm.put(key + "." + key1, jo.get(key1)); + } + } else if (o instanceof JSONArray) { + JSONArray ja = (JSONArray) o; + mm.put(key + "_length", String.valueOf(ja.length())); + + log.info("Added property: {}_length: {}", key, String.valueOf(ja.length())); + + for (int i = 0; i < ja.length(); i++) + wm.put(key + '[' + i + ']', ja.get(i)); + } + } + return mm; + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java new file mode 100644 index 000000000..3bb401ad4 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java @@ -0,0 +1,412 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017-2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack.model; + +/** + * This module implements the APP-C/Saltstack Server interface + * based on the REST API specifications + */ + +import com.google.common.base.Strings; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.UUID; + +/** + * Class that validates and constructs requests sent/received from + * Saltstack Server + */ +public class SaltstackMessageParser { + + private static final String SS_AGENT_HOSTNAME_KEY = "HostName"; + private static final String SS_AGENT_PORT_KEY = "Port"; + private static final String PASS_KEY = "Password"; + private static final String USER_KEY = "User"; + private static final String CMD_EXEC = "Cmd"; //cmd + private static final String IS_SLS_EXEC = "SlsExec"; //slsExec + private static final String SS_REQ_ID = "Id"; + private static final String SLS_FILE_LOCATION = "SlsFile"; //slsFile + private static final String SLS_NAME = "SlsName"; //slsName + private static final String MINION_TO_APPLY = "NodeList"; //applyTo + private static final String EXEC_TIMEOUT_TO_APPLY = "Timeout"; //execTimeout + private static final String FILE_PARAMETERS_OPT_KEY = "FileParameters"; + private static final String ENV_PARAMETERS_OPT_KEY = "EnvParameters"; + + private static final Logger LOGGER = LoggerFactory.getLogger(SaltstackMessageParser.class); + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate PORT number. + */ + public String reqPortResult(Map<String, String> params) throws SvcLogicException { + // use default port if null + if (params.get(SS_AGENT_PORT_KEY) == null) { + return "22"; + } + return params.get(SS_AGENT_PORT_KEY); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate HOST name. + */ + public String reqHostNameResult(Map<String, String> params) throws SvcLogicException { + + throwIfMissingMandatoryParam(params, SS_AGENT_HOSTNAME_KEY); + return params.get(SS_AGENT_HOSTNAME_KEY); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate request ID. + */ + public String reqId(Map<String, String> params) { + + if (params.get(SaltstackMessageParser.SS_REQ_ID) == null) { + return UUID.randomUUID().toString(); + } else if (params.get(SaltstackMessageParser.SS_REQ_ID).equalsIgnoreCase("")) { + return UUID.randomUUID().toString(); + } + return params.get(SaltstackMessageParser.SS_REQ_ID); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate command to execute. + */ + public String reqCmd(Map<String, String> params) throws SvcLogicException { + + throwIfMissingMandatoryParam(params, CMD_EXEC); + return params.get(SaltstackMessageParser.CMD_EXEC); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate SLS file location to execute. + */ + public String reqSlsFile(Map<String, String> params) throws SvcLogicException { + + throwIfMissingMandatoryParam(params, SLS_FILE_LOCATION); + return params.get(SaltstackMessageParser.SLS_FILE_LOCATION); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate SLS file location to execute. + */ + public String reqSlsName(Map<String, String> params) throws SvcLogicException { + + throwIfMissingMandatoryParam(params, SLS_NAME); + String slsName = params.get(SaltstackMessageParser.SLS_NAME); + try { + if (slsName.substring(slsName.lastIndexOf("."), slsName.length()).equalsIgnoreCase(".sls")) { + return stripExtension(slsName); + } + } catch (StringIndexOutOfBoundsException e) { + return slsName; + } + return slsName; + } + + private String stripExtension(String str) { + if (str == null) { + return null; + } + int pos = str.lastIndexOf("."); + if (pos == -1) { + return str; + } + return str.substring(0, pos); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate minions/vnfc to execute the SLS file. + */ + public String reqApplyToDevices(Map<String, String> params) { + + if (params.get(SaltstackMessageParser.MINION_TO_APPLY) == null) { + return "*"; + } else if (params.get(SaltstackMessageParser.MINION_TO_APPLY).equalsIgnoreCase("")) { + return "*"; + } + return params.get(SaltstackMessageParser.MINION_TO_APPLY); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate minions/vnfc to execute the SLS file. + */ + public long reqExecTimeout(Map<String, String> params) { + + if (params.get(SaltstackMessageParser.EXEC_TIMEOUT_TO_APPLY) == null) { + return -1; + } else if (params.get(SaltstackMessageParser.EXEC_TIMEOUT_TO_APPLY).equalsIgnoreCase("")) { + return -1; + } + return Long.parseLong(params.get(SaltstackMessageParser.EXEC_TIMEOUT_TO_APPLY)); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate EnvParameters to execute the SLS file. + */ + public JSONObject reqEnvParameters(Map<String, String> params) throws JSONException { + + JSONObject jsonPayload = new JSONObject(); + final String[] optionalTestParam = {SaltstackMessageParser.ENV_PARAMETERS_OPT_KEY}; + parseParam(params, optionalTestParam, jsonPayload); + + return (JSONObject) jsonPayload.remove(SaltstackMessageParser.ENV_PARAMETERS_OPT_KEY); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate EnvParameters to execute the SLS file. + */ + public JSONObject reqFileParameters(Map<String, String> params) throws JSONException { + + JSONObject jsonPayload = new JSONObject(); + final String[] optionalTestParam = {SaltstackMessageParser.FILE_PARAMETERS_OPT_KEY}; + parseParam(params, optionalTestParam, jsonPayload); + + return (JSONObject) jsonPayload.remove(SaltstackMessageParser.FILE_PARAMETERS_OPT_KEY); + } + + private void parseParam(Map<String, String> params, String[] optionalTestParams, JSONObject jsonPayload) + throws JSONException { + + Set<String> optionalParamsSet = new HashSet<>(); + Collections.addAll(optionalParamsSet, optionalTestParams); + + //@formatter:off + params.entrySet() + .stream() + .filter(entry -> optionalParamsSet.contains(entry.getKey())) + .filter(entry -> !Strings.isNullOrEmpty(entry.getValue())) + .forEach(entry -> parseParam(entry, jsonPayload)); + //@formatter:on + } + + private void parseParam(Map.Entry<String, String> params, JSONObject jsonPayload) + throws JSONException { + String key = params.getKey(); + String payload = params.getValue(); + + switch (key) { + case ENV_PARAMETERS_OPT_KEY: + JSONObject paramsJson = new JSONObject(payload); + jsonPayload.put(key, paramsJson); + break; + + case FILE_PARAMETERS_OPT_KEY: + jsonPayload.put(key, getFilePayload(payload)); + break; + + default: + break; + } + } + + /** + * Return payload with escaped newlines + */ + private JSONObject getFilePayload(String payload) { + String formattedPayload = payload.replace("\n", "\\n").replace("\r", "\\r"); + return new JSONObject(formattedPayload); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate IsSLSExec true or false. + */ + public boolean reqIsSLSExec(Map<String, String> params) throws SvcLogicException { + + final String[] mandatoryTestParams = {CMD_EXEC, IS_SLS_EXEC}; + + for (String key : mandatoryTestParams) { + throwIfMissingMandatoryParam(params, key); + } + + return params.get(SaltstackMessageParser.IS_SLS_EXEC).equalsIgnoreCase("true"); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate Saltstack server login user name. + */ + public String reqUserNameResult(Map<String, String> params) throws SvcLogicException { + + throwIfMissingMandatoryParam(params, USER_KEY); + return params.get(USER_KEY); + } + + /** + * Method that validates that the Map has enough information + * to query Saltstack server for a result. If so, it returns + * the appropriate Saltstack server login password. + */ + public String reqPasswordResult(Map<String, String> params) throws SvcLogicException { + + throwIfMissingMandatoryParam(params, PASS_KEY); + return params.get(PASS_KEY); + } + + /** + * This method parses response from the Saltstack Server when we do a post + * and returns an SaltstackResult object. + */ + public SaltstackResult parseResponse(SvcLogicContext ctx, String pfx, + SaltstackResult saltstackResult, boolean slsExec) throws IOException { + int code = saltstackResult.getStatusCode(); + boolean executionStatus = true; + boolean retCodeFound = false; + if (code != SaltstackResultCodes.SUCCESS.getValue()) { + return saltstackResult; + } + ByteArrayOutputStream outStream = saltstackResult.getOutputMessage(); + String outMessage = outStream.toString(); + try { + Map<String, String> mm = JsonParser.convertToProperties(outMessage); + if (mm != null) { + for (Map.Entry<String, String> entry : mm.entrySet()) { + if (entry.getKey().contains("retcode")) { + retCodeFound = true; + if (!entry.getValue().equalsIgnoreCase("0")) { + executionStatus = false; + } + } + ctx.setAttribute(pfx + "." + entry.getKey(), entry.getValue()); + LOGGER.info("+++ " + pfx + "." + entry.getKey() + ": [" + entry.getValue() + "]"); + } + } + } catch (org.codehaus.jettison.json.JSONException e) { + if (slsExec) { + return new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE.getValue(), "error parsing response file" + + " : Output has to be in JSON format"); + } + LOGGER.info("Output not in JSON format"); + return putToProperties(ctx, pfx, saltstackResult); + } catch (Exception e) { + return new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE_FILE.getValue(), "error parsing response file" + + " : " + e.getMessage()); + } finally { + if (outStream != null) { + outStream.close(); + } + } + if (slsExec) { + if (!retCodeFound) { + if (outMessage != null && !outMessage.equalsIgnoreCase("")) { + return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(), + outMessage); + } + return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(), + "error in executing configuration at the server, check your command input"); + } + if (!executionStatus) { + if (outMessage != null && !outMessage.equalsIgnoreCase("")) { + return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(), + outMessage); + } + return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(), + "error in executing configuration at the server, check your command input"); + } + } + saltstackResult.setStatusCode(SaltstackResultCodes.FINAL_SUCCESS.getValue()); + return saltstackResult; + } + + public SaltstackResult putToProperties(SvcLogicContext ctx, String pfx, + SaltstackResult saltstackResult) throws IOException { + + ByteArrayOutputStream buffer = saltstackResult.getOutputMessage(); + InputStream inputStream = null; + try { + byte[] bytes = buffer.toByteArray(); + Properties prop = new Properties(); + inputStream = new ByteArrayInputStream(bytes); + prop.load(inputStream); + ctx.setAttribute(pfx + "completeResult", prop.toString()); + for (Object key : prop.keySet()) { + String name = (String) key; + String value = prop.getProperty(name); + if (value != null && value.trim().length() > 0) { + ctx.setAttribute(pfx + "." + name, value.trim()); + LOGGER.info("+++ " + pfx + "." + name + ": [" + value + "]"); + } + } + } catch (Exception e) { + saltstackResult = new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE_FILE.getValue(), "Error parsing response file." + + " Error = " + e.getMessage()); + } finally { + if (buffer != null && inputStream != null) { + buffer.close(); + inputStream.close(); + } + } + saltstackResult.setStatusCode(SaltstackResultCodes.FINAL_SUCCESS.getValue()); + return saltstackResult; + } + + private void throwIfMissingMandatoryParam(Map<String, String> params, String key) throws SvcLogicException { + if (!params.containsKey(key)) { + throw new SvcLogicException(String.format( + "Saltstack: Mandatory SaltstackAdapter key %s not found in parameters provided by calling agent !", + key)); + } + if (Strings.isNullOrEmpty(params.get(key))) { + throw new SvcLogicException(String.format( + "Saltstack: Mandatory SaltstackAdapter key %s not found in parameters provided by calling agent !", + key)); + } + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java new file mode 100644 index 000000000..727cfe314 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack.model; + +import java.io.ByteArrayOutputStream; + +/** + * Simple class to store code and message returned by POST/GET to an Saltstack Server + */ +public class SaltstackResult { + + private static final String EMPTY_VALUE = "UNKNOWN"; + + private int statusCode; + private String statusMessage; + private String results; + private ByteArrayOutputStream out; + private int sshExitStatus; + + public SaltstackResult() { + this(-1, EMPTY_VALUE, EMPTY_VALUE, -1); + } + + public SaltstackResult(int code, String message) { + this(code, message, EMPTY_VALUE, -1); + } + + public SaltstackResult(int code, String message, String result, int sshCode) { + statusCode = code; + statusMessage = message; + results = result; + sshExitStatus = sshCode; + } + + void set(int code, String message, String results) { + this.statusCode = code; + this.statusMessage = message; + this.results = results; + } + + public ByteArrayOutputStream getOutputMessage() { + return out; + } + + public void setOutputMessage(ByteArrayOutputStream out) { + this.out = out; + } + + public int getStatusCode() { + return this.statusCode; + } + + public void setStatusCode(int code) { + this.statusCode = code; + } + + public String getStatusMessage() { + return this.statusMessage; + } + + public void setStatusMessage(String message) { + this.statusMessage = message; + } + + public String getResults() { + return this.results; + } + + public void setResults(String results) { + this.results = results; + } + + public int getSshExitStatus() { + return sshExitStatus; + } + + public void setSshExitStatus(int sshExitStatus) { + this.sshExitStatus = sshExitStatus; + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java new file mode 100644 index 000000000..932554983 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.sli.adaptors.saltstack.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * enum of the various codes that APP-C uses to resolve different + * status of response from Saltstack Server + **/ + +public enum SaltstackResultCodes { + + // @formatter:off + SUCCESS(400), + KEYSTORE_EXCEPTION(622), + CERTIFICATE_ERROR(610), + IO_EXCEPTION(611), + HOST_UNKNOWN(625), + USER_UNAUTHORIZED(613), + UNKNOWN_EXCEPTION(699), + OPERATION_TIMEOUT(659), + SSL_EXCEPTION(697), + SSH_EXCEPTION(695), + INVALID_COMMAND(698), + INVALID_RESPONSE(601), + INVALID_RESPONSE_FILE(600), + PENDING(100), + REJECTED(101), + FINAL_SUCCESS(200), + CHECK_CTX_FOR_CMD_SUCCESS(250), + COMMAND_EXEC_FAILED_STATUS(670), + REQ_FAILURE(401), + MESSAGE(1), + CODE(0), + INITRESPONSE(0), + FINALRESPONSE(1); + // @formatter:on + + private final Set<Integer> initCodes = new HashSet<>(Arrays.asList(100, 101)); + private final Set<Integer> finalCodes = new HashSet<>(Arrays.asList(200, 500)); + private final ArrayList<Set<Integer>> codeSets = new ArrayList<>(Arrays.asList(initCodes, finalCodes)); + private final Set<String> messageSet = new HashSet<>(Arrays.asList("PENDING", "FINISHED", "TERMINATED")); + private final int value; + + SaltstackResultCodes(int value) { + this.value = value; + } + + ; + + public int getValue() { + return value; + } + + public boolean checkValidCode(int type, int code) { + return codeSets.get(type).contains(code); + } + + public String getValidCodes(int type) { + StringBuilder sb = new StringBuilder("[ "); + codeSets.get(type).stream().forEach(s -> sb.append(s).append(",")); + return sb.append("]").toString(); + } + + public boolean checkValidMessage(String message) { + return messageSet.contains(message); + } + + public String getValidMessages() { + StringBuilder sb = new StringBuilder("[ "); + messageSet.stream().forEach(s -> sb.append(s).append(",")); + return sb.append("]").toString(); + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java new file mode 100644 index 000000000..78976562b --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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========================================================= + */ + + + +/* + * Class to emulate responses from the Saltstack Server that is compliant with the APP-C Saltstack Server + * Interface. Used for jUnit tests to verify code is working. In tests it can be used + * as a replacement for methods from ConnectionBuilder class + */ + +package org.onap.ccsdk.sli.adaptors.saltstack.model; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; + +public class SaltstackServerEmulator { + + private static final String SALTSTATE_FILE_NAME = "fileName"; + private final EELFLogger logger = EELFManager.getInstance().getLogger(SaltstackServerEmulator.class); + + /** + * Method that emulates the response from an Saltstack Server + * when presented with a request to execute a saltState + * Returns an saltstack object result. The response code is always the ssh code 200 (i.e connection successful) + * payload is json string as would be sent back by Saltstack Server + **/ + public SaltstackResult mockReqExec(Map<String, String> params) { + SaltstackResult result = new SaltstackResult(); + + try { + if (params.get("Test") == "fail") { + result = rejectRequest(result, "Mocked: Fail"); + } else { + String fileName = params.get(SALTSTATE_FILE_NAME); + if (fileName == null) { + throw new FileNotFoundException("No response file found"); + } + result = acceptRequest(result, fileName); + } + } catch (Exception e) { + logger.error("Exception caught", e); + rejectRequest(result, e.getMessage()); + } + return result; + } + + private SaltstackResult rejectRequest(SaltstackResult result, String Message) { + result.setStatusCode(SaltstackResultCodes.REJECTED.getValue()); + result.setStatusMessage("Rejected"); + return result; + } + + private SaltstackResult acceptRequest(SaltstackResult result, String fileName) throws IOException { + result.setStatusCode(SaltstackResultCodes.SUCCESS.getValue()); + result.setStatusMessage("Success"); + Path path = Paths.get(fileName); + byte[] data = Files.readAllBytes(path); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(data.length); + byteOut.write(data, 0, data.length); + result.setOutputMessage(byteOut); + return result; + } +}
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SshException.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SshException.java new file mode 100644 index 000000000..037a1e891 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SshException.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : APPC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Copyright (C) 2017 Amdocs + * ============================================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.saltstack.model; + +public class SshException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public SshException(String message) { + super(message); + } + + public SshException(String message, Throwable cause) { + super(message, cause); + } +}
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/resources/OSGI-INF/blueprint/saltstack-adapter-blueprint.xml b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/OSGI-INF/blueprint/saltstack-adapter-blueprint.xml new file mode 100755 index 000000000..e360f8184 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/OSGI-INF/blueprint/saltstack-adapter-blueprint.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 - 2018 Samsung Electronics. 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========================================================= + --> + +<blueprint xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" + class="org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterPropertiesProviderImpl"/> + + <bean id="saltstackAdapterInstance" + class="org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterImpl"> + <argument ref="propProvider"/> + </bean> + + <service ref="saltstackAdapterInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapter + </value> + </interfaces> + </service> + +</blueprint> diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/resources/org/opendaylight/blueprint/saltstack-adapter-blueprint.xml b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/org/opendaylight/blueprint/saltstack-adapter-blueprint.xml new file mode 100755 index 000000000..e360f8184 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/org/opendaylight/blueprint/saltstack-adapter-blueprint.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 - 2018 Samsung Electronics. 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========================================================= + --> + +<blueprint xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" + class="org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterPropertiesProviderImpl"/> + + <bean id="saltstackAdapterInstance" + class="org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterImpl"> + <argument ref="propProvider"/> + </bean> + + <service ref="saltstackAdapterInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapter + </value> + </interfaces> + </service> + +</blueprint> diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/resources/saltstack-adapter.properties b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/saltstack-adapter.properties new file mode 100644 index 000000000..1755f7adf --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/saltstack-adapter.properties @@ -0,0 +1,43 @@ +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2018 Samsung Electronics. 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========================================================= +### +# +# Default properties for the APP-C TestService Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.onap.appc.bootstrap.file=appc.properties +org.onap.appc.bootstrap.path=${user.home},/opt/opendaylight/current/properties +appc.application.name=APPC +# +# Define the message resource bundle name to be loaded +org.onap.appc.resources=org.onap/appc/i18n/MessageResources +# +# The name of the adapter. +org.onap.appc.provider.adaptor.name=org.onap.appc.appc_saltstack_adapter +# Default truststore path and password +org.onap.appc.adapter.saltstack.trustStore=/opt/opendaylight/tls-client/mykeystore.js +org.onap.appc.adapter.saltstack.trustStore.trustPasswd=changeit +org.onap.appc.adapter.saltstack.clientType=TRUST_ALL diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestConnectionBuilder.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestConnectionBuilder.java new file mode 100644 index 000000000..71fcf3454 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestConnectionBuilder.java @@ -0,0 +1,184 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.adapter.impl; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.saltstack.impl.ConnectionBuilder; +import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + + +public class TestConnectionBuilder { + + private ConnectionBuilder connBuilder; + private Map<String, String> params; + + + @Before + public void setup() throws IllegalArgumentException { + String HostName = "test"; + String Port = "10"; + String User = "test"; + String Password = "test"; + connBuilder = new ConnectionBuilder(HostName, Port, User, Password); + + params = new HashMap<>(); + params.put("AgentUrl", "https://192.168.1.1"); + params.put("User", "test"); + params.put("Password", "test"); + } + + @After + public void tearDown() { + connBuilder = null; + params = null; + } + + @Test + public void reqExecCommand_exitStatus255() { + + int exitStatus = 255; + String errFilePath = "src/test/resources/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(698, status); + } + + @Test + public void reqExecCommand_exitStatus1() { + + int exitStatus = 1; + String errFilePath = "src/test/resources/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(698, status); + } + + @Test + public void reqExecCommand_exitStatus67() { + + int exitStatus = 67; + String errFilePath = "src/test/resources/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(610, status); + } + + @Test + public void reqExecCommand_exitStatus73() { + + int exitStatus = 73; + String errFilePath = "src/test/resources/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(610, status); + } + + @Test + public void reqExecCommand_exitStatus5() { + + int exitStatus = 5; + String errFilePath = "src/test/resources/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(613, status); + } + + @Test + public void reqExecCommand_exitStatus65() { + + int exitStatus = 65; + String errFilePath = "src/test/resources/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(613, status); + } + + @Test + public void reqExecCommand_exitStatus67613() { + + int exitStatus = 5; + String errFilePath = "src/test/resources/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(613, status); + } + + @Test + public void reqExecCommand_exitStatus65613() { + + int exitStatus = 65; + String errFilePath = "src/test/resources/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(613, status); + } + + @Test + public void reqExecCommand_exitStatusUnknown() { + + int exitStatus = 5121; + String errFilePath = "src/test/resources/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(699, status); + } + + @Test + public void reqExecCommand_exitStatusNoFile() { + + int exitStatus = 65; + String errFilePath = "src/test/resource/test.json"; + String command = "test"; + + SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command); + int status = result.getStatusCode(); + assertEquals(613, status); + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterImpl.java new file mode 100644 index 000000000..22e8c2082 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterImpl.java @@ -0,0 +1,1051 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.adapter.impl; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterImpl; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + + +public class TestSaltstackAdapterImpl { + + private SaltstackAdapterImpl adapter; + private String TestId; + private boolean testMode = true; + private Map<String, String> params; + private SvcLogicContext svcContext; + + + @Before + public void setup() throws IllegalArgumentException { + testMode = true; + svcContext = new SvcLogicContext(); + adapter = new SaltstackAdapterImpl(testMode); + + params = new HashMap<>(); + params.put("AgentUrl", "https://192.168.1.1"); + params.put("User", "test"); + params.put("Password", "test"); + } + + @After + public void tearDown() { + testMode = false; + adapter = null; + params = null; + svcContext = null; + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_shouldSetFailed() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "fail"); + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("101", status); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_shouldSetUserFailed() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("Password", "test"); + params.put("Test", "fail"); + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("101", status); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_shouldSetHostFailed() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "fail"); + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("101", status); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_shouldSetPortFailed() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "fail"); + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("101", status); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_shouldSetPasswordFailed() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Test", "fail"); + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("101", status); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_shouldSetMandatoryFailed() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("Test", "fail"); + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("101", status); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_NoResponseFile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("Cmd", "test"); + params.put("SlsExec", "false"); + try { + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("400", status); + } catch (NullPointerException e) { + fail(e.getMessage() + " Unknown exception encountered "); + } + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_NoResponseFileWithRetry() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("withRetry", "true"); + params.put("Cmd", "test"); + params.put("SlsExec", "false"); + try { + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("400", status); + } catch (NullPointerException e) { + fail(e.getMessage() + " Unknown exception encountered "); + } + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_NoResponseFileWithRetryZero() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("withRetry", "0"); + params.put("Cmd", "test"); + params.put("SlsExec", "false"); + try { + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("400", status); + } catch (NullPointerException e) { + fail(e.getMessage() + " Unknown exception encountered "); + } + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_NoResponseFileWithNoRetry() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("withRetry", "false"); + params.put("Cmd", "test"); + params.put("SlsExec", "false"); + + try { + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("400", status); + } catch (NullPointerException e) { + fail(e.getMessage() + " Unknown exception encountered "); + } + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_shouldSetFailure() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Cmd", "test"); + params.put("SlsExec", "test"); + params.put("Test", "fail"); + try { + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("400", status); + } catch (NullPointerException e) { + fail(e.getMessage() + " Unknown exception encountered "); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessNoSLS() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("fileName", "src/test/resources/test.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + params.put("SlsExec", "false"); + + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + @Test + public void reqExecCommand_shouldSetSuccessExecSLS() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + params.put("SlsExec", "true"); + + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_shouldSetFailExecSLS() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("fileName", "src/test/resources/test.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + params.put("SlsExec", "true"); + + adapter.reqExecCommand(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + @Test + public void reqExecCommand_shouldSetSuccessFileTxt() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("fileName", "src/test/resources/test.txt"); + params.put("Id", "txt"); + params.put("Cmd", "test"); + params.put("SlsExec", "false"); + + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "txt"); + } + + @Test + public void reqExecCommand_shouldSetSuccessFileNoExtension() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("fileName", "src/test/resources/test"); + params.put("Id", "txt"); + params.put("Cmd", "test"); + params.put("SlsExec", "false"); + + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "txt"); + } + + @Test + public void reqExecCommand_shouldSetSuccessFileInvalidJson() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("fileName", "src/test/resources/test-invalid.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + params.put("SlsExec", "false"); + + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_shouldSetFailFileInvalidFile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("fileName", "src/test/resources/test-none.json"); + params.put("Id", "test1"); + + adapter.reqExecCommand(params, svcContext); + } + + @Test + public void reqExecCommand_shouldSetSuccessFileJsonNoReqID() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("fileName", "src/test/resources/test.json"); + params.put("Cmd", "test"); + params.put("SlsExec", "false"); + + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + } + + @Test + public void reqExecSLSFile_shouldSetSuccessJson() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test.sls"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + + adapter.reqExecSLSFile(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecSLSFile_NoSLSfile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test-none.sls"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + + adapter.reqExecSLSFile(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecSLSFile_NoExtn() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test-none"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + + adapter.reqExecSLSFile(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecSLSFile_NoResponsefile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test.json"); + params.put("fileName", "src/test/resources/test-none.json"); + params.put("Id", "test1"); + + adapter.reqExecSLSFile(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecSLSFile_WithMinionSetNotSLSType() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test.json"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + params.put("NodeList", "minion1"); + + adapter.reqExecSLSFile(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + @Test + public void reqExecSLSFile_WithMinionSetSuccessSls() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test.sls"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + params.put("NodeList", "minion1"); + + adapter.reqExecSLSFile(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecSLSFile_WithMinionNoSLSfile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test-none.json"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("NodeList", "minion1"); + + adapter.reqExecSLSFile(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecSLSFile_WithMinionNoResponsefile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test.json"); + params.put("fileName", "src/test/resources/test-none.json"); + params.put("Id", "test1"); + params.put("NodeList", "minion1"); + + adapter.reqExecSLSFile(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + @Test + public void reqExecSLSFile_WithAllMinionSetSuccessJson() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test.sls"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + params.put("NodeList", "*"); + + adapter.reqExecSLSFile(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecSLSFile_WithAllMinionNoSLSfile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test-none.json"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("NodeList", "*"); + + adapter.reqExecSLSFile(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecSLSFile_WithAllMinionNoResponsefile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsFile", "src/test/resources/test.json"); + params.put("fileName", "src/test/resources/test-none.json"); + params.put("Id", "test1"); + params.put("NodeList", "*"); + + adapter.reqExecSLSFile(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + + @Test + public void reqExecSLS_shouldSetSuccessJson() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsName", "src/test.sls"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + + adapter.reqExecSLS(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + @Test + public void reqExecSLS_shouldSetNoExtn() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsName", "src/test"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + + adapter.reqExecSLS(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + @Test(expected = SvcLogicException.class) + public void reqExecSLS_NoResponsefile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsName", "src/test/resources/test.json"); + params.put("fileName", "src/test/resources/test-none.json"); + params.put("Id", "test1"); + + adapter.reqExecSLS(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + + @Test + public void reqExecSLS_WithMinionSetSuccessSls() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsName", "src/test/resources/test.sls"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + params.put("NodeList", "minion1"); + + adapter.reqExecSLS(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + + @Test(expected = SvcLogicException.class) + public void reqExecSLS_WithMinionNoResponsefile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsName", "src/test/resources/test.json"); + params.put("fileName", "src/test/resources/test-none.json"); + params.put("Id", "test1"); + params.put("NodeList", "minion1"); + + adapter.reqExecSLS(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + @Test + public void reqExecSLS_WithAllMinionSetSuccessJson() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsName", "src/test/resources/test.sls"); + params.put("fileName", "src/test/resources/test-sls.json"); + params.put("Id", "test1"); + params.put("Cmd", "test"); + params.put("NodeList", "*"); + + adapter.reqExecSLS(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } + + + @Test(expected = SvcLogicException.class) + public void reqExecSLS_WithAllMinionNoResponsefile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "test"); + params.put("Port", "10"); + params.put("User", "test"); + params.put("Password", "test"); + params.put("Test", "success"); + params.put("SlsName", "src/test/resources/test.json"); + params.put("fileName", "src/test/resources/test-none.json"); + params.put("Id", "test1"); + params.put("NodeList", "*"); + + adapter.reqExecSLS(params, svcContext); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals(TestId, "test1"); + } + + + @Test + public void reqExecCommand_shouldSetSuccessReal() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "127.0.0.1"); + params.put("Port", "22"); + params.put("User", "sdn"); + params.put("Password", "foo"); + params.put("Id", "test1"); + params.put("Cmd", "ls -l"); + params.put("SlsExec", "false"); + params.put("Timeout", "120"); + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } catch (Exception e) { + //if local ssh is not enabled + System.out.print(e.getMessage()); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessRealSLSCommand() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "<IP>"); + params.put("Port", "2222"); + params.put("User", "root"); + params.put("Password", "vagrant"); + params.put("Id", "test1"); + params.put("Cmd", "salt '*' test.ping --out=json --static"); + params.put("SlsExec", "false"); + params.put("Timeout", "120"); + + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + TestId = svcContext.getAttribute("test1.minion1"); + assertEquals(TestId, "true"); + } catch (Exception e) { + //if saltstack ssh IP is not enabled + System.out.print(e.getMessage()); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessRealCommand() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "<IP>"); + params.put("Port", "2222"); + params.put("User", "root"); + params.put("Password", "vagrant"); + params.put("Id", "test1"); + params.put("Cmd", "cd /srv/salt/; salt '*' state.apply vim --out=json --static"); + params.put("SlsExec", "true"); + params.put("Timeout", "120"); + + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecCommand(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } catch (Exception e) { + //if saltstack ssh IP is not enabled + System.out.print(e.getMessage()); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessRealSSL() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "<IP>"); + params.put("Port", "2222"); + params.put("User", "root"); + params.put("Password", "vagrant"); + params.put("Id", "test1"); + params.put("SlsName", "vim"); + params.put("Timeout", "120"); + params.put("NodeList", "minion1"); + + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecSLS(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } catch (Exception e) { + //if saltstack ssh IP is not enabled + System.out.print(e.getMessage()); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessEnvParam() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "<IP>"); + params.put("Port", "2222"); + params.put("User", "root"); + params.put("Password", "vagrant"); + params.put("Id", "test1"); + params.put("SlsName", "vim"); + params.put("Timeout", "120"); + params.put("NodeList", "minion1"); + params.put("EnvParameters", "{\"exclude\": bar*}"); + + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecSLS(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } catch (Exception e) { + //if saltstack ssh IP is not enabled + System.out.print(e.getMessage()); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessFileParam() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "<IP>"); + params.put("Port", "2222"); + params.put("User", "root"); + params.put("Password", "vagrant"); + params.put("Id", "test1"); + params.put("SlsName", "vim"); + params.put("Timeout", "120"); + params.put("NodeList", "minion1"); + params.put("EnvParameters", "{\"exclude\": \"bar,baz\"}"); + params.put("FileParameters", "{\"config.txt\":\"db_ip=10.1.1.1, sip_timer=10000\"}"); + + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecSLS(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } catch (Exception e) { + //if saltstack ssh IP is not enabled + System.out.print(e.getMessage()); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessPillarParam() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "<IP>"); + params.put("Port", "2222"); + params.put("User", "root"); + params.put("Password", "vagrant"); + params.put("Id", "test1"); + params.put("SlsName", "vim"); + params.put("Timeout", "120"); + params.put("NodeList", "minion1"); + params.put("EnvParameters", "{\"exclude\": \"bar,baz\", \"pillar\":\"'{\\\"foo\\\": \\\"bar\\\"}'\"}"); + params.put("FileParameters", "{\"config.txt\":\"db_ip=10.1.1.1, sip_timer=10000\"}"); + + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecSLS(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } catch (Exception e) { + //if saltstack ssh IP is not enabled + System.out.print(e.getMessage()); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessMultiFileParam() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "<IP>"); + params.put("Port", "2222"); + params.put("User", "root"); + params.put("Password", "vagrant"); + params.put("Id", "test1"); + params.put("SlsName", "vim"); + params.put("Timeout", "120"); + params.put("NodeList", "minion1"); + params.put("EnvParameters", "{\"exclude\": bar*}"); + params.put("FileParameters", "{\"config.txt\":\"db_ip=10.1.1.1, sip_timer=10000\" , \"config-tep.txt\":\"db_ip=10.1.1.1, sip_timer=10000\"}"); + + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecSLS(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } catch (Exception e) { + //if saltstack ssh IP is not enabled + System.out.print(e.getMessage()); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessSSLFile() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "<IP>"); + params.put("Port", "2222"); + params.put("User", "root"); + params.put("Password", "vagrant"); + params.put("Id", "test1"); + params.put("Timeout", "120"); + params.put("NodeList", "minion1"); + params.put("SlsFile", "src/test/resources/config.sls"); + + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecSLSFile(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } catch (Exception e) { + //if saltstack ssh IP is not enabled + System.out.print(e.getMessage()); + } + } + + @Test + public void reqExecCommand_shouldSetSuccessSSLFileMultiFileParam() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + + params.put("HostName", "<IP>"); + params.put("Port", "2222"); + params.put("User", "root"); + params.put("Password", "vagrant"); + params.put("Id", "test1"); + params.put("Timeout", "120"); + params.put("NodeList", "minion1"); + params.put("SlsFile", "src/test/resources/config.sls"); + params.put("EnvParameters", "{\"exclude\": bar, \"pillar\":\"'{\\\"foo\\\": \\\"bar\\\"}'\"}"); + params.put("FileParameters", "{\"config.txt\":\"db_ip=10.1.1.1, sip_timer=10000\" , \"config-tep.txt\":\"db_ip=10.1.1.1, sip_timer=10000\"}"); + + adapter = new SaltstackAdapterImpl(); + try { + adapter.reqExecSLSFile(params, svcContext); + String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code"); + TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id"); + assertEquals("200", status); + assertEquals(TestId, "test1"); + } catch (Exception e) { + //if saltstack ssh IP is not enabled + System.out.print(e.getMessage()); + } + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterPropertiesProviderImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterPropertiesProviderImpl.java new file mode 100644 index 000000000..88acc1919 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterPropertiesProviderImpl.java @@ -0,0 +1,310 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.adapter.impl; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapterPropertiesProvider; +import org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterImpl; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class TestSaltstackAdapterPropertiesProviderImpl { + + private SaltstackAdapterImpl adapter; + private Properties params; + + + @Before + public void setup() throws IllegalArgumentException { + params = new Properties(); + } + + @After + public void tearDown() { + adapter = null; + params = null; + } + + @Test + public void reqExecCommand_setPropertiesBasicPortNull() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "BASIC"); + params.put("User", "test"); + params.put("Password", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_setPropertiesBasicPortString() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "BASIC"); + params.put("org.onap.appc.adapter.saltstack.host", "test"); + params.put("org.onap.appc.adapter.saltstack.port", "test"); + params.put("org.onap.appc.adapter.saltstack.userName", "test"); + params.put("org.onap.appc.adapter.saltstack.userPasswd", "test"); + params.put("org.onap.appc.adapter.saltstack.sshKey", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + } + + @Test + public void reqExecCommand_setPropertiesBasicSuccess() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "BASIC"); + params.put("org.onap.appc.adapter.saltstack.host", "test"); + params.put("org.onap.appc.adapter.saltstack.port", "10"); + params.put("org.onap.appc.adapter.saltstack.userName", "test"); + params.put("org.onap.appc.adapter.saltstack.userPasswd", "test"); + params.put("org.onap.appc.adapter.saltstack.sshKey", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(adapter); + } + + @Test + public void reqExecCommand_setPropertiesSSH_CERTPortNull() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "SSH_CERT"); + params.put("User", "test"); + params.put("Password", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + @Test(expected = SvcLogicException.class) + public void reqExecCommand_setPropertiesSSH_CERTPortString() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "SSH_CERT"); + params.put("org.onap.appc.adapter.saltstack.host", "test"); + params.put("org.onap.appc.adapter.saltstack.port", "test"); + params.put("org.onap.appc.adapter.saltstack.userName", "test"); + params.put("org.onap.appc.adapter.saltstack.userPasswd", "test"); + params.put("org.onap.appc.adapter.saltstack.sshKey", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + } + + @Test + public void reqExecCommand_setPropertiesSSH_CERTSuccess() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "SSH_CERT"); + params.put("org.onap.appc.adapter.saltstack.host", "test"); + params.put("org.onap.appc.adapter.saltstack.port", "10"); + params.put("org.onap.appc.adapter.saltstack.userName", "test"); + params.put("org.onap.appc.adapter.saltstack.userPasswd", "test"); + params.put("org.onap.appc.adapter.saltstack.sshKey", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + @Test + public void reqExecCommand_setPropertiesBOTHPortNull() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "BOTH"); + params.put("User", "test"); + params.put("Password", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + @Test + public void reqExecCommand_setPropertiesBOTHSuccess() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "BOTH"); + params.put("org.onap.appc.adapter.saltstack.host", "test"); + params.put("org.onap.appc.adapter.saltstack.port", "10"); + params.put("org.onap.appc.adapter.saltstack.userName", "test"); + params.put("org.onap.appc.adapter.saltstack.userPasswd", "test"); + params.put("org.onap.appc.adapter.saltstack.sshKey", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + @Test + public void reqExecCommand_setPropertiesNonePortNull() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "NONE"); + params.put("User", "test"); + params.put("Password", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + @Test + public void reqExecCommand_setPropertiesNonePortString() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "NONE"); + params.put("org.onap.appc.adapter.saltstack.host", "test"); + params.put("org.onap.appc.adapter.saltstack.port", "test"); + params.put("org.onap.appc.adapter.saltstack.userName", "test"); + params.put("org.onap.appc.adapter.saltstack.userPasswd", "test"); + params.put("org.onap.appc.adapter.saltstack.sshKey", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + @Test + public void reqExecCommand_setPropertiesNoneSuccess() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.clientType", "NONE"); + params.put("org.onap.appc.adapter.saltstack.host", "test"); + params.put("org.onap.appc.adapter.saltstack.port", "10"); + params.put("org.onap.appc.adapter.saltstack.userName", "test"); + params.put("org.onap.appc.adapter.saltstack.userPasswd", "test"); + params.put("org.onap.appc.adapter.saltstack.sshKey", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + + @Test + public void reqExecCommand_setPropertiesElsePortNull() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("User", "test"); + params.put("Password", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + @Test + public void reqExecCommand_setPropertiesElsePortString() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.host", "test"); + params.put("org.onap.appc.adapter.saltstack.port", "test"); + params.put("org.onap.appc.adapter.saltstack.userName", "test"); + params.put("org.onap.appc.adapter.saltstack.userPasswd", "test"); + params.put("org.onap.appc.adapter.saltstack.sshKey", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + assertNotNull(propProvider); + } + + @Test + public void reqExecCommand_setPropertiesElseSuccess() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + params.put("org.onap.appc.adapter.saltstack.host", "test"); + params.put("org.onap.appc.adapter.saltstack.port", "10"); + params.put("org.onap.appc.adapter.saltstack.userName", "test"); + params.put("org.onap.appc.adapter.saltstack.userPasswd", "test"); + params.put("org.onap.appc.adapter.saltstack.sshKey", "test"); + SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() { + @Override + public Properties getProperties() { + return params; + } + }; + adapter = new SaltstackAdapterImpl(propProvider); + String adaptorName = adapter.getAdapterName(); + assertEquals("Saltstack Adapter", adaptorName); + } + + @Test + public void reqExecCommand_setPropertiesDefault() throws SvcLogicException, + IllegalStateException, IllegalArgumentException { + adapter = new SaltstackAdapterImpl(); + assertNotNull(adapter); + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/model/TestJsonParser.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/model/TestJsonParser.java new file mode 100644 index 000000000..d4eafc1a0 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/model/TestJsonParser.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2018 Samsung Electronics. 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.onap.ccsdk.adapter.model; + +import org.codehaus.jettison.json.JSONException; +import org.junit.Test; +import org.onap.ccsdk.sli.adaptors.saltstack.model.JsonParser; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import static org.junit.Assert.assertNotNull; + +public class TestJsonParser { + + private static final Logger log = LoggerFactory.getLogger(TestJsonParser.class); + + @Test + public void test() throws SvcLogicException, IOException, JSONException { + BufferedReader in = new BufferedReader( + new InputStreamReader(ClassLoader.getSystemResourceAsStream("test.json")) + ); + StringBuilder b = new StringBuilder(); + String line; + while ((line = in.readLine()) != null) + b.append(line).append('\n'); + + Map<String, String> mm = JsonParser.convertToProperties(b.toString()); + + logProperties(mm); + + in.close(); + assertNotNull(mm); + } + + @Test(expected = NullPointerException.class) + public void testNullString() throws SvcLogicException, JSONException { + JsonParser.convertToProperties(null); + } + + private void logProperties(Map<String, String> mm) { + List<String> ll = new ArrayList<>(); + for (Object o : mm.keySet()) + ll.add((String) o); + Collections.sort(ll); + log.info("Properties:"); + for (String name : ll) + log.info("--- {}: {}", name, mm.get(name)); + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/config.sls b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/config.sls new file mode 100644 index 000000000..aff05939b --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/config.sls @@ -0,0 +1,2 @@ +vim: + pkg.installed diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/org/onap/ccsdk/default.properties b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/org/onap/ccsdk/default.properties new file mode 100644 index 000000000..e5650e853 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/org/onap/ccsdk/default.properties @@ -0,0 +1,102 @@ +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2018 Samsung Electronics. 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========================================================= +### +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.onap.appc.bootstrap.file=appc.properties +org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},. +appc.application.name=APPC +# +# Define the message resource bundle name to be loaded +org.onap.appc.resources=org/onap/appc/i18n/MessageResources +# +# The name of the adapter. +org.onap.appc.provider.adaptor.name=org.onap.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.onap.appc.logging.file=org/onap/appc/logback.xml +org.onap.appc.logging.path=${user.home};etc;../etc +org.onap.appc.logger=org.onap.appc +org.onap.appc.security.logger=org.onap.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.onap.appc.provider.min.pool=1 +org.onap.appc.provider.max.pool=0 +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.onap.appc.provider.retry.delay=30 +org.onap.appc.provider.retry.limit=10 +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.onap.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.onap.appc.openstack.poll.interval=20 +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# +# Don't change these 2 right now since they are hard coded in the DG +#provider1.type=appc +#provider1.name=appc +#These you can change +#provider1.identity=appc +#provider1.tenant1.name=appc +#provider1.tenant1.userid=appc +#provider1.tenant1.password=appc +# After a change to the provider make sure to recheck these values with an api call to provider1.identity/tokens +test.expected-regions=1 +test.expected-endpoints=1 +#Your OpenStack IP +#test.ip=192.168.1.2 +# Your OpenStack Platform's Keystone Port (default is 5000) +#test.port=5000 +#test.tenantid=abcde12345fghijk6789lmnopq123rst +#test.vmid=abc12345-1234-5678-890a-abcdefg12345 +# Port 8774 below is default port for OpenStack's Nova API Service +#test.url=http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345 + diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test new file mode 100644 index 000000000..dec578bd9 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test @@ -0,0 +1,30 @@ +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos2v-queueing-code = P +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos3-queueing-code = W +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2-queueing = WRED +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2v-queueing = QueueLimit +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos3-queueing = WRED +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2-shaping = Disable +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2v-shaping = Enable +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos3-shaping = Disable +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2-shaping-code = W +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2v-shaping-code = P +service-configuration-notification-input.ack-final-indicator = Y +service-configuration-notification-input.response-code = 0 +service-configuration-notification-input.response-message = Plc Activation Failed: Device gblond2005me6 Sync-from Failed. Please check device IP address and NCS setup. +service-configuration-notification-input.service-information.service-instance-id = TEST7 +service-configuration-notification-input.service-information.service-type = AVPN +service-configuration-notification-input.svc-request-id = TEST7 +service-data.avpn-ip-port-information.avpn-access-information.access-circuit-id = DHEC.54831.170.ATI +service-data.avpn-ip-port-information.avpn-access-information.access-interface = _1G +service-data.avpn-ip-port-information.avpn-access-information.access-speed = 10000 +service-data.avpn-ip-port-information.avpn-access-information.access-speed-units = Kbps +service-data.avpn-ip-port-information.avpn-access-information.l1-customer-handoff = _1000BASELX +service-data.avpn-ip-port-information.avpn-access-information.managed-ce = N +service-data.avpn-ip-port-information.avpn-access-information.vlan-tag-control = _1Q +service-data.avpn-ip-port-information.clli = LONDENEH +service-data.avpn-ip-port-information.contracted-port-speed = 10000 +service-data.avpn-ip-port-information.contracted-port-speed-units = Kbps +service-data.avpn-ip-port-information.endpoint-information.bundle-id = 33 +service-data.avpn-ip-port-information.endpoint-information.interface-string = ae0 +service-data.service-information.service-instance-id = ICORESITE-2751508 +service-data.service-information.service-type = AVPN diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json new file mode 100644 index 000000000..d16bfccdf --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json @@ -0,0 +1,29 @@ +"equipment-data": [ +{ +"server-count": "4", +"max-server-speed": "1600000", +"number-primary-servers": "2", +"equipment-id": "Server1", +"server-model": "Unknown", +"server-id": "Server1", +"test-node": { +"test-inner-node": "Test-Value" +} +} +], +"resource-state": { +"threshold-value": "1600000", +"last-added": "1605000", +"used": "1605000", +"limit-value": "1920000" +}, +"resource-rule": { +"endpoint-position": "VCE-Cust", +"soft-limit-expression": "0.6 * max-server-speed * number-primary-servers", +"resource-name": "Bandwidth", +"service-model": "DUMMY", +"hard-limit-expression": "max-server-speed * number-primary-servers", +"equipment-level": "Server" +}, +"message": "The provisioned access bandwidth is at or exceeds 50% of the total server capacity." +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json new file mode 100644 index 000000000..bc1c10c8d --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json @@ -0,0 +1,35 @@ +{ + "minion1": { + "retcode": 0, + "pkg_|-install_network_packages_|-install_network_packages_|-installed": { + "comment": "The following packages were installed/updated: lftp\nThe following packages were already installed: rsync, curl", + "name": "install_network_packages", + "start_time": "08:47:16.061765", + "result": true, + "duration": 11086.334, + "__run_num__": 0, + "__sls__": "nettools", + "changes": { + "lftp": { + "new": "4.6.3a-1build2", + "old": "" + } + }, + "__id__": "install_network_packages" + } + }, + "minion2": { + "retcode": 0, + "pkg_|-install_network_packages_|-install_network_packages_|-installed": { + "comment": "All specified packages are already installed", + "name": "curl", + "start_time": "08:47:16.152099", + "result": true, + "duration": 426.493, + "__run_num__": 0, + "__sls__": "nettools", + "changes": {}, + "__id__": "install_network_packages" + } + } +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json new file mode 100644 index 000000000..81131d6f4 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json @@ -0,0 +1,30 @@ +{ + "equipment-data": [ + { + "server-count": "4", + "max-server-speed": "1600000", + "number-primary-servers": "2", + "equipment-id": "Server1", + "server-model": "Unknown", + "server-id": "Server1", + "test-node": { + "test-inner-node": "Test-Value" + } + } + ], + "resource-state": { + "threshold-value": "1600000", + "last-added": "1605000", + "used": "1605000", + "limit-value": "1920000" + }, + "resource-rule": { + "endpoint-position": "VCE-Cust", + "soft-limit-expression": "0.6 * max-server-speed * number-primary-servers", + "resource-name": "Bandwidth", + "service-model": "DUMMY", + "hard-limit-expression": "max-server-speed * number-primary-servers", + "equipment-level": "Server" + }, + "message": "The provisioned access bandwidth is at or exceeds 50% of the total server capacity." +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.sls b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.sls new file mode 100644 index 000000000..cd76486aa --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.sls @@ -0,0 +1,30 @@ +{ + "equipment-data": [ + { + "server-count": "4", + "max-server-speed": "1600000", + "number-primary-servers": "2", + "equipment-id": "Server1", + "server-model": "Unknown", + "server-id": "Server1", + "test-node" : { + "test-inner-node" : "Test-Value" + } + } + ], + "resource-state": { + "threshold-value": "1600000", + "last-added": "1605000", + "used": "1605000", + "limit-value": "1920000" + }, + "resource-rule": { + "endpoint-position": "VCE-Cust", + "soft-limit-expression": "0.6 * max-server-speed * number-primary-servers", + "resource-name": "Bandwidth", + "service-model": "DUMMY", + "hard-limit-expression": "max-server-speed * number-primary-servers", + "equipment-level": "Server" + }, + "message": "The provisioned access bandwidth is at or exceeds 50% of the total server capacity." +} diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt new file mode 100644 index 000000000..dec578bd9 --- /dev/null +++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt @@ -0,0 +1,30 @@ +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos2v-queueing-code = P +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos3-queueing-code = W +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2-queueing = WRED +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2v-queueing = QueueLimit +operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos3-queueing = WRED +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2-shaping = Disable +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2v-shaping = Enable +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos3-shaping = Disable +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2-shaping-code = W +operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2v-shaping-code = P +service-configuration-notification-input.ack-final-indicator = Y +service-configuration-notification-input.response-code = 0 +service-configuration-notification-input.response-message = Plc Activation Failed: Device gblond2005me6 Sync-from Failed. Please check device IP address and NCS setup. +service-configuration-notification-input.service-information.service-instance-id = TEST7 +service-configuration-notification-input.service-information.service-type = AVPN +service-configuration-notification-input.svc-request-id = TEST7 +service-data.avpn-ip-port-information.avpn-access-information.access-circuit-id = DHEC.54831.170.ATI +service-data.avpn-ip-port-information.avpn-access-information.access-interface = _1G +service-data.avpn-ip-port-information.avpn-access-information.access-speed = 10000 +service-data.avpn-ip-port-information.avpn-access-information.access-speed-units = Kbps +service-data.avpn-ip-port-information.avpn-access-information.l1-customer-handoff = _1000BASELX +service-data.avpn-ip-port-information.avpn-access-information.managed-ce = N +service-data.avpn-ip-port-information.avpn-access-information.vlan-tag-control = _1Q +service-data.avpn-ip-port-information.clli = LONDENEH +service-data.avpn-ip-port-information.contracted-port-speed = 10000 +service-data.avpn-ip-port-information.contracted-port-speed-units = Kbps +service-data.avpn-ip-port-information.endpoint-information.bundle-id = 33 +service-data.avpn-ip-port-information.endpoint-information.interface-string = ae0 +service-data.service-information.service-instance-id = ICORESITE-2751508 +service-data.service-information.service-type = AVPN diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.json new file mode 100644 index 000000000..562c24ad3 --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.json @@ -0,0 +1,203 @@ +[ + { + "id": "d86e7ee4.ee3f1", + "type": "method", + "name": "saltstack-adapter-1.0", + "xml": "<method rpc='saltstack-adapter-1.0-exe-nonSLS' mode='sync'>\n", + "comments": "", + "outputs": 1, + "x": 492, + "y": 216, + "z": "5945fc3c.78efc4", + "wires": [ + [ + "38662e01.1d3c22" + ] + ] + }, + { + "id": "9997883e.ec9028", + "type": "service-logic", + "name": "APPC 2.0.1", + "module": "APPC", + "version": "2.0.1", + "comments": "", + "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>", + "outputs": 1, + "x": 283, + "y": 289, + "z": "5945fc3c.78efc4", + "wires": [ + [ + "d86e7ee4.ee3f1" + ] + ] + }, + { + "id": "d40bf650.8338e8", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1007, + "y": 373, + "z": "5945fc3c.78efc4", + "wires": [] + }, + { + "id": "38662e01.1d3c22", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='cd /srv/salt; ls -l'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 700, + "y": 212, + "z": "5945fc3c.78efc4", + "wires": [ + [ + "7b75e382.6344dc", + "6f108926.d7baf8" + ] + ] + }, + { + "id": "24fb9f79.a6c6c", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 486, + "y": 372, + "z": "5945fc3c.78efc4", + "wires": [ + [ + "c526c44.c850738", + "9c394980.2a56a8" + ] + ] + }, + { + "id": "c526c44.c850738", + "type": "other", + "name": "outcome", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 675, + "y": 371, + "z": "5945fc3c.78efc4", + "wires": [ + [ + "d40bf650.8338e8" + ] + ] + }, + { + "id": "7b75e382.6344dc", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 951, + "y": 210, + "z": "5945fc3c.78efc4", + "wires": [ + [ + "d40bf650.8338e8" + ] + ] + }, + { + "id": "6f108926.d7baf8", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 298, + "y": 378, + "z": "5945fc3c.78efc4", + "wires": [ + [ + "24fb9f79.a6c6c" + ] + ] + }, + { + "id": "9c394980.2a56a8", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 667, + "y": 460, + "z": "5945fc3c.78efc4", + "wires": [ + [ + "1f81a3db.54cd1c" + ] + ] + }, + { + "id": "1f81a3db.54cd1c", + "type": "returnSuccess", + "name": "return success", + "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n", + "comments": "", + "x": 887, + "y": 460, + "z": "5945fc3c.78efc4", + "wires": [] + }, + { + "id": "fcad80f8.ba2d9", + "type": "dgstart", + "name": "DGSTART", + "outputs": 1, + "x": 261, + "y": 189, + "z": "5945fc3c.78efc4", + "wires": [ + [ + "9997883e.ec9028" + ] + ] + }, + { + "id": "b86e624d.49f0f", + "type": "comment", + "name": "SaltStack Adaptor DG", + "info": "", + "comments": "", + "x": 630, + "y": 75, + "z": "5945fc3c.78efc4", + "wires": [] + }, + { + "id": "83c0578d.061f98", + "type": "comment", + "name": "request-method = reqExecCommand, req-action = \"execute a single non SLS command\"", + "info": "", + "comments": "", + "x": 650, + "y": 155, + "z": "5945fc3c.78efc4", + "wires": [] + }, + { + "id": "f104feb6.558f7", + "type": "comment", + "name": "Assumptions for this DG", + "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controlls minion1 and minion2. ", + "comments": "", + "x": 627, + "y": 115, + "z": "5945fc3c.78efc4", + "wires": [] + } +]
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.xml new file mode 100644 index 000000000..6fbbe5b1f --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.xml @@ -0,0 +1,50 @@ +<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exe-nonSLS' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd' value='cd /srv/salt; ls -l'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='200'>
+ <return status='success'>
+ <parameter name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.json new file mode 100644 index 000000000..7f427674b --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.json @@ -0,0 +1,350 @@ +[ + { + "id": "d0ad0305.352fc", + "type": "method", + "name": "saltstack-adapter-1.0", + "xml": "<method rpc='saltstack-adapter-1.0-exec-SLSFile' mode='sync'>\n", + "comments": "", + "outputs": 1, + "x": 552, + "y": 183, + "z": "b84dc629.83cd08", + "wires": [ + [ + "65cc87e2.a95188" + ] + ] + }, + { + "id": "22aefec.e8c7902", + "type": "service-logic", + "name": "APPC 2.0.1", + "module": "APPC", + "version": "2.0.1", + "comments": "", + "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>", + "outputs": 1, + "x": 343, + "y": 261, + "z": "b84dc629.83cd08", + "wires": [ + [ + "d0ad0305.352fc" + ] + ] + }, + { + "id": "31587001.4259e", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1262, + "y": 365, + "z": "b84dc629.83cd08", + "wires": [] + }, + { + "id": "65cc87e2.a95188", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt '*' test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 761, + "y": 185, + "z": "b84dc629.83cd08", + "wires": [ + [ + "f9bf6ee7.cf954", + "7b51c357.a852cc" + ] + ] + }, + { + "id": "42fa1258.aa570c", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 544, + "y": 345, + "z": "b84dc629.83cd08", + "wires": [ + [ + "a7cf236a.84c03", + "c45d597b.20b4c8" + ] + ] + }, + { + "id": "a7cf236a.84c03", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 735, + "y": 343, + "z": "b84dc629.83cd08", + "wires": [ + [ + "31587001.4259e" + ] + ] + }, + { + "id": "f9bf6ee7.cf954", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 1011, + "y": 182, + "z": "b84dc629.83cd08", + "wires": [ + [ + "31587001.4259e" + ] + ] + }, + { + "id": "7b51c357.a852cc", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 366, + "y": 343, + "z": "b84dc629.83cd08", + "wires": [ + [ + "42fa1258.aa570c" + ] + ] + }, + { + "id": "c45d597b.20b4c8", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 351, + "y": 459, + "z": "b84dc629.83cd08", + "wires": [ + [ + "30d5f0f7.0e3c8" + ] + ] + }, + { + "id": "2856792.c401a86", + "type": "returnSuccess", + "name": "return success", + "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n", + "comments": "", + "x": 1042, + "y": 656, + "z": "b84dc629.83cd08", + "wires": [] + }, + { + "id": "6c359fdc.3b566", + "type": "dgstart", + "name": "DGSTART", + "outputs": 1, + "x": 321, + "y": 161, + "z": "b84dc629.83cd08", + "wires": [ + [ + "22aefec.e8c7902" + ] + ] + }, + { + "id": "b5342c59.29f74", + "type": "comment", + "name": "SaltStack Adaptor DG", + "info": "", + "comments": "", + "x": 693, + "y": 44, + "z": "b84dc629.83cd08", + "wires": [] + }, + { + "id": "19202194.8ff55e", + "type": "comment", + "name": "request-method = reqExecCommand, req-action = \"execute multiple SLS commands\"", + "info": "Here we basically test if minion1 is active by pinging to it, then install vim package to it. \n", + "comments": "", + "x": 711, + "y": 127, + "z": "b84dc629.83cd08", + "wires": [] + }, + { + "id": "a2ebc17e.fa03a", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 396, + "y": 661, + "z": "b84dc629.83cd08", + "wires": [ + [ + "c9345fbb.d6d19" + ] + ] + }, + { + "id": "770411a5.18825", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='Cmd' value='cd /srv/salt/; salt 'minion1' state.apply vim --out=json --static'/>\n <parameter name='SlsExec' value='true'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 773, + "y": 548, + "z": "b84dc629.83cd08", + "wires": [ + [ + "e09a3e12.87428", + "a2ebc17e.fa03a" + ] + ] + }, + { + "id": "e09a3e12.87428", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 991, + "y": 554, + "z": "b84dc629.83cd08", + "wires": [ + [ + "31587001.4259e" + ] + ] + }, + { + "id": "c9345fbb.d6d19", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 578, + "y": 658, + "z": "b84dc629.83cd08", + "wires": [ + [ + "485e453d.36c75c", + "f1adcf2a.2c456" + ] + ] + }, + { + "id": "485e453d.36c75c", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 783, + "y": 732, + "z": "b84dc629.83cd08", + "wires": [ + [ + "31587001.4259e" + ] + ] + }, + { + "id": "f1adcf2a.2c456", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 776, + "y": 658, + "z": "b84dc629.83cd08", + "wires": [ + [ + "2856792.c401a86" + ] + ] + }, + { + "id": "30d5f0f7.0e3c8", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$test1.minion1`\">\n", + "comments": "", + "outputs": 1, + "x": 523, + "y": 459, + "z": "b84dc629.83cd08", + "wires": [ + [ + "15e9ff68.9812a1", + "17d9d7e.4d9a928" + ] + ] + }, + { + "id": "17d9d7e.4d9a928", + "type": "other", + "name": "outcome", + "xml": "<outcome value='true'>\n", + "comments": "", + "outputs": 1, + "x": 593, + "y": 550, + "z": "b84dc629.83cd08", + "wires": [ + [ + "770411a5.18825" + ] + ] + }, + { + "id": "15e9ff68.9812a1", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 717, + "y": 459, + "z": "b84dc629.83cd08", + "wires": [ + [ + "31587001.4259e" + ] + ] + }, + { + "id": "b764890c.ed0018", + "type": "comment", + "name": "Assumptions for this DG (example-server)", + "info": "1) Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controlls minion1 and minion2. \n2) We assume that sls file called vim.sls is already present in the path /srv/salt on the server.", + "comments": "", + "x": 693, + "y": 86, + "z": "b84dc629.83cd08", + "wires": [] + } +]
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.xml new file mode 100644 index 000000000..fc63bbd7b --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.xml @@ -0,0 +1,112 @@ +<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-SLSFile' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt '*' test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='200'>
+ <switch test="`$test1.minion1`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='true'>
+ <execute
+ plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName'
+ value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password'
+ value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='Cmd'
+ value='cd /srv/salt/; salt 'minion1' state.apply vim --out=json --static'/>
+ <parameter name='SlsExec' value='true'/>
+ <parameter name='Timeout'
+ value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter
+ name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter
+ name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </outcome>
+ </switch>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.json new file mode 100644 index 000000000..d7cfef01e --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.json @@ -0,0 +1,399 @@ +[ + { + "id": "65f5c0d6.9c4ce", + "type": "method", + "name": "saltstack-adapter-1.0", + "xml": "<method rpc='saltstack-adapter-1.0-exec-multi-sls' mode='sync'>\n", + "comments": "", + "outputs": 1, + "x": 615, + "y": 273, + "z": "6df02477.0463cc", + "wires": [ + [ + "c332cb01.51a3e8" + ] + ] + }, + { + "id": "bf71bd6e.1be5b", + "type": "service-logic", + "name": "APPC 2.0.1", + "module": "APPC", + "version": "2.0.1", + "comments": "", + "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>", + "outputs": 1, + "x": 406, + "y": 351, + "z": "6df02477.0463cc", + "wires": [ + [ + "65f5c0d6.9c4ce" + ] + ] + }, + { + "id": "40ce8a6.5f7d174", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1325, + "y": 455, + "z": "6df02477.0463cc", + "wires": [] + }, + { + "id": "c332cb01.51a3e8", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt '*' test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 824, + "y": 275, + "z": "6df02477.0463cc", + "wires": [ + [ + "5b387684.e51be8", + "4bb6b32e.adfc2c" + ] + ] + }, + { + "id": "16dfbd4f.b6da73", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 607, + "y": 435, + "z": "6df02477.0463cc", + "wires": [ + [ + "24d22f52.ef59a", + "ac765880.a6c548" + ] + ] + }, + { + "id": "24d22f52.ef59a", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 798, + "y": 433, + "z": "6df02477.0463cc", + "wires": [ + [ + "40ce8a6.5f7d174" + ] + ] + }, + { + "id": "5b387684.e51be8", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 1074, + "y": 272, + "z": "6df02477.0463cc", + "wires": [ + [ + "40ce8a6.5f7d174" + ] + ] + }, + { + "id": "4bb6b32e.adfc2c", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 429, + "y": 433, + "z": "6df02477.0463cc", + "wires": [ + [ + "16dfbd4f.b6da73" + ] + ] + }, + { + "id": "ac765880.a6c548", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 414, + "y": 549, + "z": "6df02477.0463cc", + "wires": [ + [ + "2dda30fc.8747" + ] + ] + }, + { + "id": "e45accfe.91615", + "type": "returnSuccess", + "name": "return success", + "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n", + "comments": "", + "x": 1345, + "y": 757, + "z": "6df02477.0463cc", + "wires": [] + }, + { + "id": "11a891ad.55bc1e", + "type": "dgstart", + "name": "DGSTART", + "outputs": 1, + "x": 384, + "y": 251, + "z": "6df02477.0463cc", + "wires": [ + [ + "bf71bd6e.1be5b" + ] + ] + }, + { + "id": "a56383b.496c48", + "type": "comment", + "name": "SaltStack Adaptor DG", + "info": "", + "comments": "", + "x": 756, + "y": 134, + "z": "6df02477.0463cc", + "wires": [] + }, + { + "id": "cfda30b5.5e166", + "type": "comment", + "name": "request-method = reqExecCommand, req-action = \"execute multiple SLS commands\"", + "info": "Here we basically test if minion1 is active by pinging to it, then install vim package to it. \n", + "comments": "", + "x": 773, + "y": 217, + "z": "6df02477.0463cc", + "wires": [] + }, + { + "id": "a8efb922.f23ce8", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 459, + "y": 751, + "z": "6df02477.0463cc", + "wires": [ + [ + "3ff32215.20cd0e" + ] + ] + }, + { + "id": "df0c0907.d17838", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='Cmd' value='salt 'minion1' pkg.install vim --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 836, + "y": 638, + "z": "6df02477.0463cc", + "wires": [ + [ + "1e5bbe2e.9cbb82", + "a8efb922.f23ce8" + ] + ] + }, + { + "id": "1e5bbe2e.9cbb82", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 1054, + "y": 644, + "z": "6df02477.0463cc", + "wires": [ + [ + "40ce8a6.5f7d174" + ] + ] + }, + { + "id": "3ff32215.20cd0e", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 647, + "y": 745, + "z": "6df02477.0463cc", + "wires": [ + [ + "8e2c712b.784b4", + "3d74cfe5.d41f5" + ] + ] + }, + { + "id": "8e2c712b.784b4", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 830, + "y": 823, + "z": "6df02477.0463cc", + "wires": [ + [ + "40ce8a6.5f7d174" + ] + ] + }, + { + "id": "3d74cfe5.d41f5", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 829, + "y": 758, + "z": "6df02477.0463cc", + "wires": [ + [ + "8313564b.004798" + ] + ] + }, + { + "id": "2dda30fc.8747", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$test1.minion1`\">\n", + "comments": "", + "outputs": 1, + "x": 586, + "y": 549, + "z": "6df02477.0463cc", + "wires": [ + [ + "e0133af5.2ca028", + "7f28f521.cf47cc" + ] + ] + }, + { + "id": "7f28f521.cf47cc", + "type": "other", + "name": "outcome", + "xml": "<outcome value='true'>\n", + "comments": "", + "outputs": 1, + "x": 656, + "y": 640, + "z": "6df02477.0463cc", + "wires": [ + [ + "df0c0907.d17838" + ] + ] + }, + { + "id": "e0133af5.2ca028", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 780, + "y": 549, + "z": "6df02477.0463cc", + "wires": [ + [ + "40ce8a6.5f7d174" + ] + ] + }, + { + "id": "8313564b.004798", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$test2.minion1.retcode`\">\n", + "comments": "", + "outputs": 1, + "x": 986, + "y": 752, + "z": "6df02477.0463cc", + "wires": [ + [ + "13d18d2d.71fbf3", + "2e940add.522a36" + ] + ] + }, + { + "id": "13d18d2d.71fbf3", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 1165, + "y": 825, + "z": "6df02477.0463cc", + "wires": [ + [ + "40ce8a6.5f7d174" + ] + ] + }, + { + "id": "2e940add.522a36", + "type": "success", + "name": "success", + "xml": "<outcome value='0'>\n", + "comments": "", + "outputs": 1, + "x": 1156, + "y": 754, + "z": "6df02477.0463cc", + "wires": [ + [ + "e45accfe.91615" + ] + ] + }, + { + "id": "6d6678d2.6a9bd8", + "type": "comment", + "name": "Assumptions for this DG (example-server)", + "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controlls minion1 and minion2. ", + "comments": "", + "x": 756, + "y": 173, + "z": "6df02477.0463cc", + "wires": [] + } +]
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.xml new file mode 100644 index 000000000..cc36b1ca7 --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.xml @@ -0,0 +1,129 @@ +<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-multi-sls' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt '*' test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='200'>
+ <switch test="`$test1.minion1`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='true'>
+ <execute
+ plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName'
+ value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password'
+ value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='Cmd'
+ value='salt 'minion1' pkg.install vim --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout'
+ value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <switch test="`$test2.minion1.retcode`">
+ <outcome value='0'>
+ <return status='success'>
+ <parameter
+ name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter
+ name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter
+ name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </outcome>
+ </switch>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.json new file mode 100644 index 000000000..4be0db3dd --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.json @@ -0,0 +1,203 @@ +[ + { + "id": "bd0f1105.ff214", + "type": "method", + "name": "saltstack-adapter-1.0", + "xml": "<method rpc='saltstack-adapter-1.0-exec-single-SLSComm' mode='sync'>\n", + "comments": "", + "outputs": 1, + "x": 526, + "y": 238, + "z": "c053ae12.4067b", + "wires": [ + [ + "f4e59dd0.ee45f" + ] + ] + }, + { + "id": "26f2a2b8.90f58e", + "type": "service-logic", + "name": "APPC 2.0.1", + "module": "APPC", + "version": "2.0.1", + "comments": "", + "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>", + "outputs": 1, + "x": 317, + "y": 316, + "z": "c053ae12.4067b", + "wires": [ + [ + "bd0f1105.ff214" + ] + ] + }, + { + "id": "55a7736.2789e8c", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1064, + "y": 453, + "z": "c053ae12.4067b", + "wires": [] + }, + { + "id": "f4e59dd0.ee45f", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt '*' test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 735, + "y": 240, + "z": "c053ae12.4067b", + "wires": [ + [ + "93fca622.05ad58", + "7ce4a659.44c828" + ] + ] + }, + { + "id": "2ceb37d9.a8ba18", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 522, + "y": 398, + "z": "c053ae12.4067b", + "wires": [ + [ + "cd89356c.279678", + "781026e2.01d498" + ] + ] + }, + { + "id": "cd89356c.279678", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 708, + "y": 456, + "z": "c053ae12.4067b", + "wires": [ + [ + "55a7736.2789e8c" + ] + ] + }, + { + "id": "93fca622.05ad58", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 985, + "y": 237, + "z": "c053ae12.4067b", + "wires": [ + [ + "55a7736.2789e8c" + ] + ] + }, + { + "id": "7ce4a659.44c828", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 332, + "y": 405, + "z": "c053ae12.4067b", + "wires": [ + [ + "2ceb37d9.a8ba18" + ] + ] + }, + { + "id": "781026e2.01d498", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 711, + "y": 398, + "z": "c053ae12.4067b", + "wires": [ + [ + "ce510062.8dcc7" + ] + ] + }, + { + "id": "ce510062.8dcc7", + "type": "returnSuccess", + "name": "return success", + "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n", + "comments": "", + "x": 893, + "y": 399, + "z": "c053ae12.4067b", + "wires": [] + }, + { + "id": "593bd7fb.675368", + "type": "dgstart", + "name": "DGSTART", + "outputs": 1, + "x": 295, + "y": 216, + "z": "c053ae12.4067b", + "wires": [ + [ + "26f2a2b8.90f58e" + ] + ] + }, + { + "id": "901c8408.5fecb8", + "type": "comment", + "name": "SaltStack Adaptor DG", + "info": "", + "comments": "", + "x": 673, + "y": 103, + "z": "c053ae12.4067b", + "wires": [] + }, + { + "id": "cc449713.a1be88", + "type": "comment", + "name": "request-method = reqExecCommand, req-action = \"execute a single SLS command\"", + "info": "Here we just ping to all the minions, and we dont even check if the minions are active. ", + "comments": "", + "x": 684, + "y": 188, + "z": "c053ae12.4067b", + "wires": [] + }, + { + "id": "c07fa80e.7f3ac8", + "type": "comment", + "name": "Assumptions for this DG (example-server)", + "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controlls minion1 and minion2. ", + "comments": "", + "x": 676, + "y": 144, + "z": "c053ae12.4067b", + "wires": [] + } +]
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.xml new file mode 100644 index 000000000..bd9aea771 --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.xml @@ -0,0 +1,51 @@ +<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-single-SLSComm' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt '*' test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.json new file mode 100644 index 000000000..7fe88f063 --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.json @@ -0,0 +1,214 @@ +[ + { + "id": "80b83851.e527b8", + "type": "method", + "name": "saltstack-adapter-1.0", + "xml": "<method rpc='saltstack-adapter-1.0' mode='sync'>\n", + "comments": "", + "outputs": 1, + "x": 676, + "y": 277, + "z": "1f6661d7.1ebd2e", + "wires": [ + [ + "83c8d47e.cb9c98" + ] + ] + }, + { + "id": "41231c44.5d1324", + "type": "service-logic", + "name": "APPC 2.0.1", + "module": "APPC", + "version": "2.0.1", + "comments": "", + "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>", + "outputs": 1, + "x": 453, + "y": 276, + "z": "1f6661d7.1ebd2e", + "wires": [ + [ + "80b83851.e527b8" + ] + ] + }, + { + "id": "1f4a794d.fb3be7", + "type": "returnSuccess", + "name": "return success", + "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n", + "comments": "", + "x": 1055, + "y": 369, + "z": "1f6661d7.1ebd2e", + "wires": [] + }, + { + "id": "5a85036.5a9e2fc", + "type": "dgstart", + "name": "DGSTART", + "outputs": 1, + "x": 284, + "y": 275, + "z": "1f6661d7.1ebd2e", + "wires": [ + [ + "41231c44.5d1324" + ] + ] + }, + { + "id": "b38fc61c.a23438", + "type": "comment", + "name": "SaltStack Adaptor DG", + "info": "", + "comments": "", + "x": 661, + "y": 154, + "z": "1f6661d7.1ebd2e", + "wires": [] + }, + { + "id": "6a821d83.4070e4", + "type": "comment", + "name": "request-method = reqExecSLS, req-action = \"execute SLS\"", + "info": "This would be the ideal adaptor the orchestrator DG will call, this just takes in SlsName.", + "comments": "", + "x": 672, + "y": 239, + "z": "1f6661d7.1ebd2e", + "wires": [] + }, + { + "id": "ba16960c.36bad8", + "type": "comment", + "name": "Assumptions for this DG (example-server)", + "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controllers minion1 and minion2. ", + "comments": "", + "x": 664, + "y": 195, + "z": "1f6661d7.1ebd2e", + "wires": [] + }, + { + "id": "83c8d47e.cb9c98", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='SlsName' value='test-file.sls'/>\n <parameter name='NodeList' value='`$NodeList`'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n <parameter name='FileParameters' value='`$FileParameters`'/>\n <parameter name='EnvParameters' value='`$EnvParameters`'/>\n", + "comments": "", + "outputs": 1, + "x": 366, + "y": 406, + "z": "1f6661d7.1ebd2e", + "wires": [ + [ + "b83f5a23.33f938", + "3354190.eb450e8" + ] + ] + }, + { + "id": "b83f5a23.33f938", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 559, + "y": 367, + "z": "1f6661d7.1ebd2e", + "wires": [ + [ + "efc02e73.0cf1d" + ] + ] + }, + { + "id": "3354190.eb450e8", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 557, + "y": 439, + "z": "1f6661d7.1ebd2e", + "wires": [ + [ + "88b53985.e42758" + ] + ] + }, + { + "id": "88b53985.e42758", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 709, + "y": 427, + "z": "1f6661d7.1ebd2e", + "wires": [ + [ + "195a294e.61efb7", + "bc1bfd78.146bc" + ] + ] + }, + { + "id": "bc1bfd78.146bc", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 872, + "y": 373, + "z": "1f6661d7.1ebd2e", + "wires": [ + [ + "1f4a794d.fb3be7" + ] + ] + }, + { + "id": "195a294e.61efb7", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 869, + "y": 442, + "z": "1f6661d7.1ebd2e", + "wires": [ + [ + "81ddc2e0.dce24" + ] + ] + }, + { + "id": "efc02e73.0cf1d", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 719, + "y": 351, + "z": "1f6661d7.1ebd2e", + "wires": [] + }, + { + "id": "81ddc2e0.dce24", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1039, + "y": 439, + "z": "1f6661d7.1ebd2e", + "wires": [] + } +]
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.xml new file mode 100644 index 000000000..23ec7856b --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.xml @@ -0,0 +1,52 @@ +<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='SlsName' value='test-file.sls'/>
+ <parameter name='NodeList' value='`$NodeList`'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <parameter name='FileParameters' value='`$FileParameters`'/>
+ <parameter name='EnvParameters' value='`$EnvParameters`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.json new file mode 100644 index 000000000..b276f3815 --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.json @@ -0,0 +1,372 @@ +[ + { + "id": "edb39979.b1ccd8", + "type": "method", + "name": "saltstack-adapter-1.0", + "xml": "<method rpc='saltstack-adapter-1.0-exec-SLS-NodeList' mode='sync'>\n", + "comments": "", + "outputs": 1, + "x": 476, + "y": 245, + "z": "671ca899.284f68", + "wires": [ + [ + "95c9ba42.6e4aa8" + ] + ] + }, + { + "id": "a16ea11e.f8d1c", + "type": "service-logic", + "name": "APPC 2.0.1", + "module": "APPC", + "version": "2.0.1", + "comments": "", + "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>", + "outputs": 1, + "x": 267, + "y": 323, + "z": "671ca899.284f68", + "wires": [ + [ + "edb39979.b1ccd8" + ] + ] + }, + { + "id": "1591f92e.029ca7", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1191, + "y": 315, + "z": "671ca899.284f68", + "wires": [] + }, + { + "id": "95c9ba42.6e4aa8", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt '*' test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 684, + "y": 251, + "z": "671ca899.284f68", + "wires": [ + [ + "cd0c458a.2430b8", + "69e531e3.4efc3" + ] + ] + }, + { + "id": "38b44d70.9c85d2", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 472, + "y": 405, + "z": "671ca899.284f68", + "wires": [ + [ + "505df598.069b9c", + "5d7292e.22ec06c" + ] + ] + }, + { + "id": "505df598.069b9c", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 658, + "y": 463, + "z": "671ca899.284f68", + "wires": [ + [ + "1591f92e.029ca7" + ] + ] + }, + { + "id": "cd0c458a.2430b8", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 935, + "y": 244, + "z": "671ca899.284f68", + "wires": [ + [ + "1591f92e.029ca7" + ] + ] + }, + { + "id": "69e531e3.4efc3", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 282, + "y": 412, + "z": "671ca899.284f68", + "wires": [ + [ + "38b44d70.9c85d2" + ] + ] + }, + { + "id": "5d7292e.22ec06c", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 661, + "y": 405, + "z": "671ca899.284f68", + "wires": [ + [ + "c9df0cea.f2361" + ] + ] + }, + { + "id": "e4f7eb59.0abb58", + "type": "returnSuccess", + "name": "return success", + "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n", + "comments": "", + "x": 1079, + "y": 564, + "z": "671ca899.284f68", + "wires": [] + }, + { + "id": "8e586da4.570f1", + "type": "dgstart", + "name": "DGSTART", + "outputs": 1, + "x": 245, + "y": 223, + "z": "671ca899.284f68", + "wires": [ + [ + "a16ea11e.f8d1c" + ] + ] + }, + { + "id": "71387074.137c1", + "type": "comment", + "name": "SaltStack Adaptor DG", + "info": "", + "comments": "", + "x": 623, + "y": 110, + "z": "671ca899.284f68", + "wires": [] + }, + { + "id": "c5e8c62d.021758", + "type": "comment", + "name": "request-method = reqExecSLS, req-action = \"execute SLS\"", + "info": "Here we basically test if minion1 is active by pinging to it, then respective sls file is executed on to it. \n", + "comments": "", + "x": 634, + "y": 195, + "z": "671ca899.284f68", + "wires": [] + }, + { + "id": "1805797.a241487", + "type": "comment", + "name": "Assumptions for this DG (example-server)", + "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controllers minion1 and minion2. ", + "comments": "", + "x": 626, + "y": 151, + "z": "671ca899.284f68", + "wires": [] + }, + { + "id": "c9df0cea.f2361", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$test1.minion1`\">\n", + "comments": "", + "outputs": 1, + "x": 825, + "y": 405, + "z": "671ca899.284f68", + "wires": [ + [ + "d83d6024.2454d", + "f4d70bbc.f0bc38" + ] + ] + }, + { + "id": "d83d6024.2454d", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 991, + "y": 459, + "z": "671ca899.284f68", + "wires": [ + [ + "1591f92e.029ca7" + ] + ] + }, + { + "id": "f4d70bbc.f0bc38", + "type": "other", + "name": "outcome", + "xml": "<outcome value='true'>\n", + "comments": "", + "outputs": 1, + "x": 994, + "y": 401, + "z": "671ca899.284f68", + "wires": [ + [ + "e86d9995.b65c58" + ] + ] + }, + { + "id": "e86d9995.b65c58", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='SlsName' value='test-file.sls'/>\n <parameter name='NodeList' value='minion1'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 398, + "y": 593, + "z": "671ca899.284f68", + "wires": [ + [ + "89ff1c2a.08f52", + "e20c4c85.43d3c" + ] + ] + }, + { + "id": "89ff1c2a.08f52", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 583, + "y": 562, + "z": "671ca899.284f68", + "wires": [ + [ + "6032e33e.5b044c" + ] + ] + }, + { + "id": "e20c4c85.43d3c", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 581, + "y": 634, + "z": "671ca899.284f68", + "wires": [ + [ + "8bb4c177.499c8" + ] + ] + }, + { + "id": "8bb4c177.499c8", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 733, + "y": 622, + "z": "671ca899.284f68", + "wires": [ + [ + "905334fe.934d68", + "9c217c10.9d539" + ] + ] + }, + { + "id": "9c217c10.9d539", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 896, + "y": 568, + "z": "671ca899.284f68", + "wires": [ + [ + "e4f7eb59.0abb58" + ] + ] + }, + { + "id": "905334fe.934d68", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 893, + "y": 637, + "z": "671ca899.284f68", + "wires": [ + [ + "7026a88c.5bffd8" + ] + ] + }, + { + "id": "6032e33e.5b044c", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 735, + "y": 559, + "z": "671ca899.284f68", + "wires": [] + }, + { + "id": "7026a88c.5bffd8", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1054, + "y": 637, + "z": "671ca899.284f68", + "wires": [] + } +]
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.xml new file mode 100644 index 000000000..cc4538cac --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.xml @@ -0,0 +1,112 @@ +<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-SLS-NodeList' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt '*' test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <switch test="`$test1.minion1`">
+ <outcome value='true'>
+ <execute
+ plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName'
+ value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password'
+ value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='SlsName'
+ value='test-file.sls'/>
+ <parameter name='NodeList' value='minion1'/>
+ <parameter name='Timeout'
+ value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter
+ name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter
+ name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.json new file mode 100644 index 000000000..b20e7e8da --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.json @@ -0,0 +1,214 @@ +[ + { + "id": "3228200a.5dc1a", + "type": "method", + "name": "saltstack-adapter-1.0", + "xml": "<method rpc='saltstack-adapter-1.0-SLSFILE' mode='sync'>\n", + "comments": "", + "outputs": 1, + "x": 679, + "y": 282, + "z": "6d4f912d.f07bc", + "wires": [ + [ + "50b2729f.712eac" + ] + ] + }, + { + "id": "9fb54163.4fb28", + "type": "service-logic", + "name": "APPC 2.0.1", + "module": "APPC", + "version": "2.0.1", + "comments": "", + "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>", + "outputs": 1, + "x": 456, + "y": 281, + "z": "6d4f912d.f07bc", + "wires": [ + [ + "3228200a.5dc1a" + ] + ] + }, + { + "id": "49109fbc.a7a14", + "type": "returnSuccess", + "name": "return success", + "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n", + "comments": "", + "x": 1058, + "y": 374, + "z": "6d4f912d.f07bc", + "wires": [] + }, + { + "id": "d030a396.56232", + "type": "dgstart", + "name": "DGSTART", + "outputs": 1, + "x": 287, + "y": 280, + "z": "6d4f912d.f07bc", + "wires": [ + [ + "9fb54163.4fb28" + ] + ] + }, + { + "id": "281900c4.fd3e8", + "type": "comment", + "name": "SaltStack Adaptor DG", + "info": "", + "comments": "", + "x": 664, + "y": 159, + "z": "6d4f912d.f07bc", + "wires": [] + }, + { + "id": "431a69db.2d2c58", + "type": "comment", + "name": "request-method = reqExecSLS, req-action = \"execute SLS\"", + "info": "This would be the ideal adaptor the orchestrator DG will call, this just takes in SlsName.", + "comments": "", + "x": 675, + "y": 244, + "z": "6d4f912d.f07bc", + "wires": [] + }, + { + "id": "4202e1ce.09495", + "type": "comment", + "name": "Assumptions for this DG (example-server)", + "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controllers minion1 and minion2. ", + "comments": "", + "x": 667, + "y": 200, + "z": "6d4f912d.f07bc", + "wires": [] + }, + { + "id": "50b2729f.712eac", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='SlsFile' value='file/location/test-file.sls'/>\n", + "comments": "", + "outputs": 1, + "x": 369, + "y": 411, + "z": "6d4f912d.f07bc", + "wires": [ + [ + "71746570.35f0dc", + "3e4f7a4a.ae0dc6" + ] + ] + }, + { + "id": "71746570.35f0dc", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 562, + "y": 372, + "z": "6d4f912d.f07bc", + "wires": [ + [ + "e59a1a81.112a08" + ] + ] + }, + { + "id": "3e4f7a4a.ae0dc6", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 560, + "y": 444, + "z": "6d4f912d.f07bc", + "wires": [ + [ + "59e320fa.12908" + ] + ] + }, + { + "id": "59e320fa.12908", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 712, + "y": 432, + "z": "6d4f912d.f07bc", + "wires": [ + [ + "f81ed07.2135c3", + "eb55b5a9.f0d2f8" + ] + ] + }, + { + "id": "eb55b5a9.f0d2f8", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 875, + "y": 378, + "z": "6d4f912d.f07bc", + "wires": [ + [ + "49109fbc.a7a14" + ] + ] + }, + { + "id": "f81ed07.2135c3", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 872, + "y": 447, + "z": "6d4f912d.f07bc", + "wires": [ + [ + "6549631f.8e516c" + ] + ] + }, + { + "id": "e59a1a81.112a08", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 722, + "y": 356, + "z": "6d4f912d.f07bc", + "wires": [] + }, + { + "id": "6549631f.8e516c", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1042, + "y": 444, + "z": "6d4f912d.f07bc", + "wires": [] + } +]
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.xml new file mode 100644 index 000000000..2c5e600fc --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.xml @@ -0,0 +1,48 @@ +<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-SLSFILE' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='SlsFile' value='file/location/test-file.sls'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.json new file mode 100644 index 000000000..264950d5e --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.json @@ -0,0 +1,372 @@ +[ + { + "id": "9a6bf94f.d969f8", + "type": "method", + "name": "saltstack-adapter-1.0", + "xml": "<method rpc='saltstack-adapter-1.0-exec-SLSFile-SlsName' mode='sync'>\n", + "comments": "", + "outputs": 1, + "x": 498, + "y": 240, + "z": "723548c7.652d78", + "wires": [ + [ + "138ad7ed.403248" + ] + ] + }, + { + "id": "4bb87049.3f546", + "type": "service-logic", + "name": "APPC 2.0.1", + "module": "APPC", + "version": "2.0.1", + "comments": "", + "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>", + "outputs": 1, + "x": 289, + "y": 318, + "z": "723548c7.652d78", + "wires": [ + [ + "9a6bf94f.d969f8" + ] + ] + }, + { + "id": "6c593992.106038", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1202, + "y": 280, + "z": "723548c7.652d78", + "wires": [] + }, + { + "id": "138ad7ed.403248", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt '*' test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 706, + "y": 246, + "z": "723548c7.652d78", + "wires": [ + [ + "167273ed.f0577c", + "954a34ea.701368" + ] + ] + }, + { + "id": "d5841e65.537ba", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 494, + "y": 400, + "z": "723548c7.652d78", + "wires": [ + [ + "ede42371.2f52b", + "d306d7a0.c830e8" + ] + ] + }, + { + "id": "ede42371.2f52b", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 680, + "y": 458, + "z": "723548c7.652d78", + "wires": [ + [ + "6c593992.106038" + ] + ] + }, + { + "id": "167273ed.f0577c", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 957, + "y": 239, + "z": "723548c7.652d78", + "wires": [ + [ + "6c593992.106038" + ] + ] + }, + { + "id": "954a34ea.701368", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 304, + "y": 407, + "z": "723548c7.652d78", + "wires": [ + [ + "d5841e65.537ba" + ] + ] + }, + { + "id": "d306d7a0.c830e8", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 683, + "y": 400, + "z": "723548c7.652d78", + "wires": [ + [ + "5b12ba31.94b3b4" + ] + ] + }, + { + "id": "9ef7fcc3.69279", + "type": "returnSuccess", + "name": "return success", + "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n", + "comments": "", + "x": 1101, + "y": 559, + "z": "723548c7.652d78", + "wires": [] + }, + { + "id": "7803eeaf.1e31d", + "type": "dgstart", + "name": "DGSTART", + "outputs": 1, + "x": 267, + "y": 218, + "z": "723548c7.652d78", + "wires": [ + [ + "4bb87049.3f546" + ] + ] + }, + { + "id": "9c6f1e7c.2a3d9", + "type": "comment", + "name": "SaltStack Adaptor DG", + "info": "", + "comments": "", + "x": 645, + "y": 105, + "z": "723548c7.652d78", + "wires": [] + }, + { + "id": "93ea02a5.4e792", + "type": "comment", + "name": "request-method = reqExecSLS, req-action = \"execute SLS FILE\"", + "info": "Here we basically test if minion1 is active by pinging to it, then respective sls file is executed on to it. \n", + "comments": "", + "x": 656, + "y": 190, + "z": "723548c7.652d78", + "wires": [] + }, + { + "id": "243edbf.f35fc24", + "type": "comment", + "name": "Assumptions for this DG (example-server)", + "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controllers minion1 and minion2. ", + "comments": "", + "x": 648, + "y": 146, + "z": "723548c7.652d78", + "wires": [] + }, + { + "id": "5b12ba31.94b3b4", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$test1.minion1`\">\n", + "comments": "", + "outputs": 1, + "x": 847, + "y": 400, + "z": "723548c7.652d78", + "wires": [ + [ + "9bf0915.96f217", + "f6e533d.95d99d" + ] + ] + }, + { + "id": "9bf0915.96f217", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 1013, + "y": 454, + "z": "723548c7.652d78", + "wires": [ + [ + "6c593992.106038" + ] + ] + }, + { + "id": "f6e533d.95d99d", + "type": "other", + "name": "outcome", + "xml": "<outcome value='true'>\n", + "comments": "", + "outputs": 1, + "x": 1016, + "y": 396, + "z": "723548c7.652d78", + "wires": [ + [ + "eb57ba41.1d7328" + ] + ] + }, + { + "id": "eb57ba41.1d7328", + "type": "execute", + "name": "execute", + "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='SlsFile' value='file/location/test.sls'/>\n <parameter name='NodeList' value='minion1'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n", + "comments": "", + "outputs": 1, + "x": 420, + "y": 588, + "z": "723548c7.652d78", + "wires": [ + [ + "892a8f1d.7d77f", + "74be8a6e.975f24" + ] + ] + }, + { + "id": "892a8f1d.7d77f", + "type": "failure", + "name": "failure", + "xml": "<outcome value='failure'>\n", + "comments": "", + "outputs": 1, + "x": 605, + "y": 557, + "z": "723548c7.652d78", + "wires": [ + [ + "8c091fe.c6cbfe" + ] + ] + }, + { + "id": "74be8a6e.975f24", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 603, + "y": 629, + "z": "723548c7.652d78", + "wires": [ + [ + "3875d695.fd37ca" + ] + ] + }, + { + "id": "3875d695.fd37ca", + "type": "switchNode", + "name": "switch", + "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n", + "comments": "", + "outputs": 1, + "x": 755, + "y": 617, + "z": "723548c7.652d78", + "wires": [ + [ + "2e60af80.ea3a6", + "24ed6dd2.6624c2" + ] + ] + }, + { + "id": "24ed6dd2.6624c2", + "type": "success", + "name": "success", + "xml": "<outcome value='200'>\n", + "comments": "", + "outputs": 1, + "x": 918, + "y": 563, + "z": "723548c7.652d78", + "wires": [ + [ + "9ef7fcc3.69279" + ] + ] + }, + { + "id": "2e60af80.ea3a6", + "type": "other", + "name": "other", + "xml": "<outcome value='Other'>\n", + "comments": "", + "outputs": 1, + "x": 915, + "y": 632, + "z": "723548c7.652d78", + "wires": [ + [ + "2e4414a7.ba6d4c" + ] + ] + }, + { + "id": "8c091fe.c6cbfe", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 757, + "y": 554, + "z": "723548c7.652d78", + "wires": [] + }, + { + "id": "2e4414a7.ba6d4c", + "type": "returnFailure", + "name": "return failure", + "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n", + "comments": "", + "x": 1076, + "y": 632, + "z": "723548c7.652d78", + "wires": [] + } +]
\ No newline at end of file diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.xml new file mode 100644 index 000000000..16c573add --- /dev/null +++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.xml @@ -0,0 +1,112 @@ +<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-SLSFile-NodeList' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt '*' test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <switch test="`$test1.minion1`">
+ <outcome value='true'>
+ <execute
+ plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName'
+ value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password'
+ value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='SlsFile'
+ value='file/location/test.sls'/>
+ <parameter name='NodeList' value='minion1'/>
+ <parameter name='Timeout'
+ value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter
+ name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter
+ name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/sql-resource/.gitignore b/sql-resource/.gitignore new file mode 100755 index 000000000..b73caf31e --- /dev/null +++ b/sql-resource/.gitignore @@ -0,0 +1,34 @@ +#####standard .git ignore entries##### + +## IDE Specific Files ## +org.eclipse.core.resources.prefs +.classpath +.project +.settings +.idea +.externalToolBuilders +maven-eclipse.xml +workspace + +## Compilation Files ## +*.class +**/target +target +target-ide +MANIFEST.MF + +## Misc Ignores (OS specific etc) ## +bin/ +dist +*~ +*.ipr +*.iml +*.iws +classes +out/ +.DS_STORE +.metadata + +## Folders which contain auto generated source code ## +yang-gen-config +yang-gen-sal diff --git a/sql-resource/installer/pom.xml b/sql-resource/installer/pom.xml new file mode 100755 index 000000000..5ec885ce0 --- /dev/null +++ b/sql-resource/installer/pom.xml @@ -0,0 +1,128 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>sql-resource-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: sql-resource :: ${project.artifactId}</name> + + <properties> + <application.name>ccsdk-sql-resource</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>sql-resource-provider</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>org.onap.ccsdk.sli.adaptor</includeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/sql-resource/installer/src/assembly/assemble_installer_zip.xml b/sql-resource/installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..3bed4b5ef --- /dev/null +++ b/sql-resource/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>installer_zip</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/sql-resource/installer/src/assembly/assemble_mvnrepo_zip.xml b/sql-resource/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..35e79db18 --- /dev/null +++ b/sql-resource/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,49 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + 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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/sql-resource/installer/src/main/resources/scripts/install-feature.sh b/sql-resource/installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..cee4a4952 --- /dev/null +++ b/sql-resource/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/sql-resource/pom.xml b/sql-resource/pom.xml new file mode 100755 index 000000000..5cbee1089 --- /dev/null +++ b/sql-resource/pom.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>sql-resource</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-adaptors :: sql-resource</name> + <description>The Sql resource adaptor allows service logic to read/write data from a local database using direct SQL statements</description> + + <modules> + <module>provider</module> + <module>installer</module> + </modules> +</project> diff --git a/sql-resource/provider/pom.xml b/sql-resource/provider/pom.xml new file mode 100755 index 000000000..94b0225c9 --- /dev/null +++ b/sql-resource/provider/pom.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>sql-resource-provider</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-adaptors :: sql-resource :: ${project.artifactId}</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-core-artifacts</artifactId> + <version>${ccsdk.sli.core.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>ch.vorburger.mariaDB4j</groupId> + <artifactId>mariaDB4j</artifactId> + <version>2.2.3</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>dblib-provider</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + </dependencies> +</project> diff --git a/sql-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResource.java b/sql-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResource.java new file mode 100755 index 000000000..435bc5bb1 --- /dev/null +++ b/sql-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResource.java @@ -0,0 +1,551 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.resource.sql; + +import java.io.File; +import java.io.FileInputStream; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import javax.sql.rowset.CachedRowSet; + +import org.apache.commons.lang3.StringUtils; +import org.onap.ccsdk.sli.core.dblib.DBResourceManager; +import org.onap.ccsdk.sli.core.dblib.DbLibService; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SqlResource implements SvcLogicResource, SvcLogicJavaPlugin { + + private static final Logger LOG = LoggerFactory.getLogger(SqlResource.class); + + private static final String DBLIB_SERVICE = "org.onap.ccsdk.sli.core.dblib.DbLibService"; + + private static String CRYPT_KEY = "QtfJMKggVk"; + + DbLibService dblibSvc = null; + + public SqlResource() { + this(new SqlResourcePropertiesProviderImpl(), null); + } + + public SqlResource(SqlResourcePropertiesProvider propProvider) { + this(propProvider, null); + } + + public SqlResource(SqlResourcePropertiesProvider propProvider, DbLibService dblibSvc) { + + this.dblibSvc = dblibSvc; + + Properties properties = propProvider.getProperties(); + + String cryptKey = properties.getProperty("org.onap.sdnc.resource.sql.cryptkey"); + + if ((cryptKey == null) || (cryptKey.length() == 0)) { + cryptKey = properties.getProperty("org.openecomp.sdnc.resource.sql.cryptkey"); + } + + SqlResource.setCryptKey(cryptKey); + } + + // For sql-resource, is-available is the same as exists + @Override + public QueryStatus isAvailable(String resource, String key, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + + return (exists(resource, key, prefix, ctx)); + + } + + @Override + public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + + DbLibService dblibSvc = getDbLibService(); + if (dblibSvc == null) { + return (QueryStatus.FAILURE); + } + + String theStmt = resolveCtxVars(key, ctx, resource); + + try { + CachedRowSet results = dblibSvc.getData(theStmt, null, null); + + if (!results.next()) { + return (QueryStatus.NOT_FOUND); + } + + int numRows = results.getInt(1); + + if (numRows > 0) { + return (QueryStatus.SUCCESS); + } else { + return (QueryStatus.NOT_FOUND); + } + } catch (Exception e) { + LOG.error("Caught SQL exception", e); + return (QueryStatus.FAILURE); + } + } + + // @Override + public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, + String orderBy, SvcLogicContext ctx) throws SvcLogicException { + + DbLibService dblibSvc = getDbLibService(); + + if (dblibSvc == null) { + return (QueryStatus.FAILURE); + } + + String sqlQuery = resolveCtxVars(key, ctx, resource); + + + try { + + CachedRowSet results = dblibSvc.getData(sqlQuery, null, null); + + QueryStatus retval = QueryStatus.SUCCESS; + + if (!results.next()) { + retval = QueryStatus.NOT_FOUND; + LOG.debug("No data found"); + } else { + saveCachedRowSetToCtx(results, ctx, prefix, dblibSvc); + } + return (retval); + } catch (Exception e) { + LOG.error("Caught SQL exception", e); + return (QueryStatus.FAILURE); + } + } + + public void saveCachedRowSetToCtx(CachedRowSet results, SvcLogicContext ctx, String prefix, DbLibService dblibSvc) + throws SQLException { + if (ctx != null) { + if ((prefix != null) && prefix.endsWith("[]")) { + // Return an array. + String pfx = prefix.substring(0, prefix.length() - 2); + int idx = 0; + do { + ResultSetMetaData rsMeta = results.getMetaData(); + int numCols = rsMeta.getColumnCount(); + + for (int i = 0; i < numCols; i++) { + String colValue = null; + String tableName = rsMeta.getTableName(i + 1); + if (rsMeta.getColumnType(i + 1) == java.sql.Types.VARBINARY) { + colValue = decryptColumn(tableName, rsMeta.getColumnName(i + 1), results.getBytes(i + 1), + dblibSvc); + } else { + colValue = results.getString(i + 1); + } + LOG.debug("Setting " + pfx + "[" + idx + "]." + + rsMeta.getColumnLabel(i + 1).replaceAll("_", "-") + " = " + colValue); + ctx.setAttribute(pfx + "[" + idx + "]." + rsMeta.getColumnLabel(i + 1).replaceAll("_", "-"), + colValue); + } + idx++; + } while (results.next()); + LOG.debug("Setting " + pfx + "_length = " + idx); + ctx.setAttribute(pfx + "_length", "" + idx); + } else { + ResultSetMetaData rsMeta = results.getMetaData(); + int numCols = rsMeta.getColumnCount(); + + for (int i = 0; i < numCols; i++) { + String colValue = null; + String tableName = rsMeta.getTableName(i + 1); + if ("VARBINARY".equalsIgnoreCase(rsMeta.getColumnTypeName(i + 1))) { + colValue = decryptColumn(tableName, rsMeta.getColumnName(i + 1), results.getBytes(i + 1), + dblibSvc); + } else { + colValue = results.getString(i + 1); + } + if (prefix != null) { + LOG.debug("Setting " + prefix + "." + rsMeta.getColumnLabel(i + 1).replaceAll("_", "-") + " = " + + colValue); + ctx.setAttribute(prefix + "." + rsMeta.getColumnLabel(i + 1).replaceAll("_", "-"), colValue); + } else { + LOG.debug("Setting " + rsMeta.getColumnLabel(i + 1).replaceAll("_", "-") + " = " + colValue); + ctx.setAttribute(rsMeta.getColumnLabel(i + 1).replaceAll("_", "-"), colValue); + } + } + } + } + } + + // reserve is no-op + @Override + public QueryStatus reserve(String resource, String select, String key, String prefix, SvcLogicContext ctx) + throws SvcLogicException { + return (QueryStatus.SUCCESS); + } + + // release is no-op + @Override + public QueryStatus release(String resource, String key, SvcLogicContext ctx) throws SvcLogicException { + return (QueryStatus.SUCCESS); + } + + private QueryStatus executeSqlWrite(String key, SvcLogicContext ctx) throws SvcLogicException { + QueryStatus retval = QueryStatus.SUCCESS; + + DbLibService dblibSvc = getDbLibService(); + + if (dblibSvc == null) { + return (QueryStatus.FAILURE); + } + + String sqlStmt = resolveCtxVars(key, ctx, ""); + + LOG.debug("key = [" + key + "]; sqlStmt = [" + sqlStmt + "]"); + try { + + if (!dblibSvc.writeData(sqlStmt, null, null)) { + retval = QueryStatus.FAILURE; + } + } catch (Exception e) { + LOG.error("Caught SQL exception", e); + retval = QueryStatus.FAILURE; + } + + return (retval); + + } + + private String resolveCtxVars(String key, SvcLogicContext ctx, String resource) { + if (key == null) { + return (null); + } + + if (key.startsWith("'") && key.endsWith("'")) { + key = key.substring(1, key.length() - 1); + LOG.debug("Stripped outer single quotes - key is now [" + key + "]"); + } + + //"SQL-TRUE" allows for the key to be used as is. + if (!resource.equals("SQL-TRUE")) { + String[] keyTerms = key.split("\\s+"); + + StringBuffer sqlBuffer = new StringBuffer(); + + for (int i = 0; i < keyTerms.length; i++) { + sqlBuffer.append(resolveTerm(keyTerms[i], ctx)); + sqlBuffer.append(" "); + } + key = sqlBuffer.toString(); + } + + return (key); + } + + private String resolveTerm(String term, SvcLogicContext ctx) { + if (term == null) { + return (null); + } + + LOG.trace("resolveTerm: term is " + term); + + if (term.startsWith("$") && (ctx != null)) { + // Resolve any index variables. + term = resolveCtxVariable(term.substring(1), ctx); + // Escape single quote + if (term != null) { + term = term.replaceAll("'", "''"); + } + return ("'" + term + "'"); + } else { + return (term); + } + + } + + private String resolveCtxVariable(String ctxVarName, SvcLogicContext ctx) { + + if (ctxVarName.indexOf('[') == -1) { + // Ctx variable contains no arrays + if ("CRYPT_KEY".equals(ctxVarName)) { + // Handle crypt key as special case. If it's set as a context + // variable, use it. Otherwise, use + // configured crypt key. + String cryptKey = ctx.getAttribute(ctxVarName); + if ((cryptKey != null) && (cryptKey.length() > 0)) { + return (cryptKey); + } else { + return (CRYPT_KEY); + } + } + return (ctx.getAttribute(ctxVarName)); + } + + // Resolve any array references + StringBuffer sbuff = new StringBuffer(); + String[] ctxVarParts = ctxVarName.split("\\["); + sbuff.append(ctxVarParts[0]); + for (int i = 1; i < ctxVarParts.length; i++) { + if (ctxVarParts[i].startsWith("$")) { + int endBracketLoc = ctxVarParts[i].indexOf("]"); + if (endBracketLoc == -1) { + // Missing end bracket ... give up parsing + LOG.warn("Variable reference " + ctxVarName + " seems to be missing a ']'"); + return (ctx.getAttribute(ctxVarName)); + } + + String idxVarName = ctxVarParts[i].substring(1, endBracketLoc); + String remainder = ctxVarParts[i].substring(endBracketLoc); + + sbuff.append("["); + sbuff.append(ctx.getAttribute(idxVarName)); + sbuff.append(remainder); + + } else { + // Index is not a variable reference + sbuff.append("["); + sbuff.append(ctxVarParts[i]); + } + } + + return (ctx.getAttribute(sbuff.toString())); + } + + @Override + public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> parms, + String prefix, SvcLogicContext ctx) throws SvcLogicException { + return (executeSqlWrite(key, ctx)); + } + + private DbLibService getDbLibService() { + + if (dblibSvc != null) { + return(dblibSvc); + } + // Try to get dblib as an OSGI service + + try { + BundleContext bctx = null; + ServiceReference sref = null; + + + + Bundle bundle = FrameworkUtil.getBundle(SqlResource.class); + + if (bundle != null) { + bctx = bundle.getBundleContext(); + } + + if (bctx != null) { + sref = bctx.getServiceReference(DBLIB_SERVICE); + } + + if (sref == null) { + LOG.warn("Could not find service reference for DBLIB service (" + DBLIB_SERVICE + ")"); + } else { + dblibSvc = (DbLibService) bctx.getService(sref); + if (dblibSvc == null) { + LOG.warn("Could not find service reference for DBLIB service (" + DBLIB_SERVICE + ")"); + } + } + } catch (NoClassDefFoundError ex) { + LOG.info("OSGI classes not found - must be running outside an OSGi container"); + } + + + if (dblibSvc == null) { + // Must not be running in an OSGI container. See if you can load it + // as a + // a POJO then. + + // If $SDNC_CONFIG_DIR/dblib.properties exists, that should + // be the properties passed to DBResourceManager constructor. + // If not, as default just use system properties. + Properties dblibProps = System.getProperties(); + + String cfgDir = dblibProps.getProperty("sdnc.config.dir", System.getenv("SDNC_CONFIG_DIR")); + + if ((cfgDir == null) || (cfgDir.length() == 0)) { + cfgDir = "/opt/sdnc/data/properties"; + } + + File dblibPropFile = new File(cfgDir + "/dblib.properties"); + if (dblibPropFile.exists()) { + try { + LOG.debug("Loading dblib properties from {}", dblibPropFile.getAbsolutePath()); + dblibProps = new Properties(); + dblibProps.load(new FileInputStream(dblibPropFile)); + } catch (Exception e) { + LOG.warn("Could not load properties file {}", dblibPropFile.getAbsolutePath(), e); + + dblibProps = System.getProperties(); + } + } + + try { + dblibSvc = new DBResourceManager(dblibProps); + } catch (Exception e) { + LOG.error("Caught exception trying to create dblib service", e); + } + + if (dblibSvc == null) { + LOG.warn("Could not create new DBResourceManager"); + } + } + + return (dblibSvc); + } + + @Override + public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) + throws SvcLogicException { + if (LOG.isDebugEnabled()) { + LOG.debug("SqlResource.notify called with resource=" + resource + ", action=" + action); + } + return QueryStatus.SUCCESS; + } + + @Override + public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException { + return (executeSqlWrite(key, ctx)); + } + + public QueryStatus update(String resource, String key, Map<String, String> parms, String prefix, + SvcLogicContext ctx) throws SvcLogicException { + return (executeSqlWrite(key, ctx)); + } + + private String decryptColumn(String tableName, String colName, byte[] colValue, DbLibService dblibSvc) { + String strValue = new String(colValue); + + if (StringUtils.isAsciiPrintable(strValue)) { + + // If printable, not encrypted + return (strValue); + } else { + ResultSet results = null; + try (Connection conn = dblibSvc.getConnection(); + PreparedStatement stmt = conn.prepareStatement("SELECT CAST(AES_DECRYPT(?, ?) AS CHAR(50)) FROM DUAL")) { + + stmt.setBytes(1, colValue); + stmt.setString(2, getCryptKey()); + results = stmt.executeQuery(); + + if ((results != null) && results.next()) { + strValue = results.getString(1); + LOG.debug("Decrypted value is " + strValue); + } else { + LOG.warn("Cannot decrypt " + tableName + "." + colName); + } + } catch (Exception e) { + LOG.error("Caught exception trying to decrypt " + tableName + "." + colName, e); + }finally { + if (results != null) { + try { + results.close(); + } catch (SQLException se) { + LOG.error("Caught exception trying to close ResultSet",se); + } + } + } + } + return (strValue); + } + + public static String getCryptKey() { + return (CRYPT_KEY); + } + + public static String setCryptKey(String key) { + CRYPT_KEY = key; + return (CRYPT_KEY); + } + + public String parameterizedQuery(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException { + DbLibService dblibSvc = getDbLibService(); + String prefix = parameters.get("prefix"); + String query = parameters.get("query"); + + ArrayList<String> arguments = new ArrayList<String>(); + for (Entry<String, String> a : parameters.entrySet()) { + if (a.getKey().startsWith("param")) { + arguments.add(a.getValue()); + } + } + + try { + if (dblibSvc == null) { + return mapQueryStatus(QueryStatus.FAILURE); + } + if (query.contains("count") || query.contains("COUNT")) { + CachedRowSet results = dblibSvc.getData(query, arguments, null); + + if (!results.next()) { + return mapQueryStatus(QueryStatus.FAILURE); + } + + int numRows = results.getInt(1); + ctx.setAttribute(prefix + ".count", String.valueOf(numRows)); + if (numRows > 0) { + return "true"; + } else { + return "false"; + } + } else if (query.startsWith("select") || query.startsWith("SELECT")) { + CachedRowSet results = dblibSvc.getData(query, arguments, null); + if (!results.next()) { + return mapQueryStatus(QueryStatus.NOT_FOUND); + } else { + saveCachedRowSetToCtx(results, ctx, prefix, dblibSvc); + } + } else { + if (!dblibSvc.writeData(query, arguments, null)) { + return mapQueryStatus(QueryStatus.FAILURE); + } + } + return mapQueryStatus(QueryStatus.SUCCESS); + } catch (SQLException e) { + LOG.error("Caught SQL exception", e); + return mapQueryStatus(QueryStatus.FAILURE); + } + } + + protected String mapQueryStatus(QueryStatus status) { + String str = status.toString(); + str = str.toLowerCase(); + str = str.replaceAll("_", "-"); + return str; + } +} diff --git a/sql-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResourcePropertiesProvider.java b/sql-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResourcePropertiesProvider.java new file mode 100755 index 000000000..7970151da --- /dev/null +++ b/sql-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResourcePropertiesProvider.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2016 - 2017 ONAP + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.resource.sql; + +import java.util.Properties; + +public interface SqlResourcePropertiesProvider { + + public Properties getProperties(); +} diff --git a/sql-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResourcePropertiesProviderImpl.java b/sql-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResourcePropertiesProviderImpl.java new file mode 100755 index 000000000..7c9f6f161 --- /dev/null +++ b/sql-resource/provider/src/main/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResourcePropertiesProviderImpl.java @@ -0,0 +1,186 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2016 - 2017 ONAP + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.adaptors.resource.sql; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; +import java.util.Properties; +import java.util.Vector; + +import org.onap.ccsdk.sli.core.sli.ConfigurationException; +import org.onap.ccsdk.sli.core.utils.JREFileResolver; +import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver; +import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver; +import org.onap.ccsdk.sli.core.utils.common.CoreDefaultFileResolver; +import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Responsible for determining the properties file to use and instantiating the + * <code>SqlResource</code> Service. The priority for properties file + * resolution is as follows: + * + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>sql-resource.properties</code></li> + * <li>A <code>sql-resource.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ +public class SqlResourcePropertiesProviderImpl implements SqlResourcePropertiesProvider { + + private static final Logger LOG = LoggerFactory.getLogger(SqlResourcePropertiesProviderImpl.class); + + /** + * The name of the properties file for database configuration + */ + private static final String SQLRESOURCE_PROP_FILE_NAME = "sql-resource.properties"; + + /** + * A prioritized list of strategies for resolving sql-resource properties files. + */ + private Vector<PropertiesFileResolver> sqlResourcePropertiesFileResolvers = new Vector<>(); + + /** + * The configuration properties for the db connection. + */ + private Properties properties; + + /** + * Set up the prioritized list of strategies for resolving dblib properties + * files. + */ + public SqlResourcePropertiesProviderImpl() { + sqlResourcePropertiesFileResolvers + .add(new SdncConfigEnvVarFileResolver("Using property file (1) from environment variable")); + sqlResourcePropertiesFileResolvers.add(new CoreDefaultFileResolver("Using property file (2) from default directory")); + + sqlResourcePropertiesFileResolvers.add( + new JREFileResolver("Using property file (3) from JRE argument", SqlResourcePropertiesProviderImpl.class)); + sqlResourcePropertiesFileResolvers.add(new KarafRootFileResolver("Using property file (4) from karaf root", this)); + + // determines properties file as according to the priority described in the + // class header comment + final File propertiesFile = determinePropertiesFile(this); + if (propertiesFile != null) { + try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) { + properties = new Properties(); + properties.load(fileInputStream); + } catch (final IOException e) { + LOG.error("Failed to load properties for file: {}", propertiesFile.toString(), + new ConfigurationException("Failed to load properties for file: " + propertiesFile.toString(), + e)); + } + } else { + // Try to read properties as resource + + InputStream propStr = getClass().getResourceAsStream("/" + SQLRESOURCE_PROP_FILE_NAME); + if (propStr != null) { + properties = new Properties(); + try { + properties.load(propStr); + propStr.close(); + } catch (IOException e) { + properties = null; + } + } + + } + + if (properties == null) { + reportFailure("Missing configuration properties resource(3)", new ConfigurationException( + "Missing configuration properties resource(3): " + SQLRESOURCE_PROP_FILE_NAME)); + } + } + + /** + * Extract svclogic config properties. + * + * @return the svclogic config properties + */ + public Properties getProperties() { + return properties; + } + + /** + * Reports the method chosen for properties resolution to the + * <code>Logger</code>. + * + * @param message + * Some user friendly message + * @param fileOptional + * The file location of the chosen properties file + * @return the file location of the chosen properties file + */ + private static File reportSuccess(final String message, final Optional<File> fileOptional) { + if (fileOptional.isPresent()) { + final File file = fileOptional.get(); + LOG.info("{} {}", message, file.getPath()); + return file; + } + return null; + } + + /** + * Reports fatal errors. This is the case in which no properties file could be + * found. + * + * @param message + * An appropriate fatal error message + * @param configurationException + * An exception describing what went wrong during resolution + */ + private static void reportFailure(final String message, final ConfigurationException configurationException) { + + LOG.error("{}", message, configurationException); + } + + /** + * Determines the sql-resource properties file to use based on the following priority: + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>sql-resource.properties</code></li> + * <li>A <code>sql-resource.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ + File determinePropertiesFile(final SqlResourcePropertiesProviderImpl resourceProvider) { + + for (final PropertiesFileResolver sliPropertiesFileResolver : sqlResourcePropertiesFileResolvers) { + final Optional<File> fileOptional = sliPropertiesFileResolver.resolveFile(SQLRESOURCE_PROP_FILE_NAME); + if (fileOptional.isPresent()) { + return reportSuccess(sliPropertiesFileResolver.getSuccessfulResolutionMessage(), fileOptional); + } + } + + return null; + } +} diff --git a/sql-resource/provider/src/main/resources/OSGI-INF/blueprint/sql-resource-blueprint.xml b/sql-resource/provider/src/main/resources/OSGI-INF/blueprint/sql-resource-blueprint.xml new file mode 100755 index 000000000..5e8d33946 --- /dev/null +++ b/sql-resource/provider/src/main/resources/OSGI-INF/blueprint/sql-resource-blueprint.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 - 2018 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" class="org.onap.ccsdk.sli.adaptors.resource.sql.SqlResourcePropertiesProviderImpl" /> + <reference id="dblibService" interface="org.onap.ccsdk.sli.core.dblib.DbLibService" /> + + <bean id="sqlResourceInstance" class="org.onap.ccsdk.sli.adaptors.resource.sql.SqlResource"> + <argument ref="propProvider"/> + <argument ref="dblibService"/> + </bean> + + <service ref="sqlResourceInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.resource.sql.SqlResource</value> + </interfaces> + </service> + +</blueprint> diff --git a/sql-resource/provider/src/main/resources/org/opendaylight/blueprint/sql-resource-blueprint.xml b/sql-resource/provider/src/main/resources/org/opendaylight/blueprint/sql-resource-blueprint.xml new file mode 100755 index 000000000..5e8d33946 --- /dev/null +++ b/sql-resource/provider/src/main/resources/org/opendaylight/blueprint/sql-resource-blueprint.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 - 2018 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========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" class="org.onap.ccsdk.sli.adaptors.resource.sql.SqlResourcePropertiesProviderImpl" /> + <reference id="dblibService" interface="org.onap.ccsdk.sli.core.dblib.DbLibService" /> + + <bean id="sqlResourceInstance" class="org.onap.ccsdk.sli.adaptors.resource.sql.SqlResource"> + <argument ref="propProvider"/> + <argument ref="dblibService"/> + </bean> + + <service ref="sqlResourceInstance"> + <interfaces> + <value>org.onap.ccsdk.sli.adaptors.resource.sql.SqlResource</value> + </interfaces> + </service> + +</blueprint> diff --git a/sql-resource/provider/src/main/resources/sql-resource.properties b/sql-resource/provider/src/main/resources/sql-resource.properties new file mode 100755 index 000000000..ac32f7734 --- /dev/null +++ b/sql-resource/provider/src/main/resources/sql-resource.properties @@ -0,0 +1,23 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +org.openecomp.sdnc.resource.sql.cryptkey=QtfJMKggVk + diff --git a/sql-resource/provider/src/main/resources/svclogic.properties b/sql-resource/provider/src/main/resources/svclogic.properties new file mode 100644 index 000000000..18718b869 --- /dev/null +++ b/sql-resource/provider/src/main/resources/svclogic.properties @@ -0,0 +1,34 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +org.onap.ccsdk.sli.adaptors.dbtype=jdbc +org.onap.ccsdk.sli.adaptors.jdbc.hosts=sdnctldb01,sdnctldb02 +org.onap.ccsdk.sli.adaptors.jdbc.url=jdbc:mysql://DBHOST:3306/sdnctl +org.onap.ccsdk.sli.adaptors.jdbc.database=sdnctl +org.onap.ccsdk.sli.adaptors.jdbc.user=sdnctl +org.onap.ccsdk.sli.adaptors.jdbc.password=gamma +org.onap.ccsdk.sli.adaptors.jdbc.connection.name=sdnctldb01 + +org.onap.ccsdk.sli.adaptors.jdbc.connection.timeout=50 +org.onap.ccsdk.sli.adaptors.jdbc.request.timeout=100 +org.onap.ccsdk.sli.adaptors.jdbc.limit.init=10 +org.onap.ccsdk.sli.adaptors.jdbc.limit.min=10 +org.onap.ccsdk.sli.adaptors.jdbc.limit.max=20 diff --git a/sql-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/sql/ITCaseSqlResource.java b/sql-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/sql/ITCaseSqlResource.java new file mode 100755 index 000000000..2863c6c96 --- /dev/null +++ b/sql-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/sql/ITCaseSqlResource.java @@ -0,0 +1,231 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * 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.onap.ccsdk.sli.adaptors.resource.sql; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Enumeration; +import java.util.Properties; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.vorburger.mariadb4j.DB; +import ch.vorburger.mariadb4j.DBConfigurationBuilder; +import junit.framework.TestCase; + +public class ITCaseSqlResource extends TestCase { + + private static final Logger LOG = LoggerFactory + .getLogger(ITCaseSqlResource.class); + + + public void testExists() throws Exception { + + + Properties props = new Properties(); + InputStream propStr = getClass().getResourceAsStream("/svclogic.properties"); + if (propStr == null) { + fail("src/test/resources/svclogic.properties missing"); + } + + try { + props.load(propStr); + propStr.close(); + } catch (Exception e) { + e.printStackTrace(); + fail("Could not initialize properties"); + } + + + // Start MariaDB4j database + DBConfigurationBuilder config = DBConfigurationBuilder.newBuilder(); + config.setPort(0); // 0 => autom. detect free port + DB db = DB.newEmbeddedDB(config.build()); + db.start(); + + // Override jdbc URL and database name + props.setProperty("org.onap.ccsdk.sli.jdbc.database", "test"); + props.setProperty("org.onap.ccsdk.sli.jdbc.url", config.getURL("test")); + + // Add properties to global properties + + Enumeration propNames = props.keys(); + + while (propNames.hasMoreElements()) { + String propName = (String) propNames.nextElement(); + + System.setProperty(propName, props.getProperty(propName)); + } + + SqlResource sqlResource = new SqlResource(new SqlResourcePropertiesProviderImpl()); + + + + InputStream testStr = getClass().getResourceAsStream("/save.tests"); + BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr)); + SvcLogicContext ctx = new SvcLogicContext(); + + try { + String testExpr = null; + + int testNum = 0; + while ((testExpr = testsReader.readLine()) != null) { + testExpr = testExpr.trim(); + + if (testExpr.startsWith("#")) { + testExpr = testExpr.substring(1).trim(); + String[] nameValue = testExpr.split("="); + String name = nameValue[0].trim(); + String value = nameValue[1].trim(); + + LOG.info("Setting context attribute " + name + " = " + + value); + ctx.setAttribute(name, value); + + } else { + + testNum++; + String sqlStmt = testExpr; + QueryStatus status = sqlResource.save("SQL", true, false, sqlStmt, null, "savetest"+testNum, ctx); + + switch (status) { + case SUCCESS: + LOG.info("Found data for query [" + sqlStmt + "]"); + break; + case NOT_FOUND: + LOG.info("Did not data for query [" + sqlStmt + "]"); + break; + default: + fail("Failure executing query [" + sqlStmt + "]"); + + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + fail("Caught exception running tests"); + } + + + testStr = getClass().getResourceAsStream("/query.tests"); + testsReader = new BufferedReader(new InputStreamReader(testStr)); + + try { + String testExpr = null; + + int testNum = 0; + while ((testExpr = testsReader.readLine()) != null) { + testExpr = testExpr.trim(); + if (testExpr.startsWith("#")) { + testExpr = testExpr.substring(1).trim(); + String[] nameValue = testExpr.split("="); + String name = nameValue[0].trim(); + String value = nameValue[1].trim(); + + LOG.info("Setting context attribute " + name + " = " + + value); + ctx.setAttribute(name, value); + + } else { + + testNum++; + + String sqlStmt = testExpr; + QueryStatus status = sqlResource.query("SQL", false, null, + sqlStmt, "querytest" + testNum, null, ctx); + + switch (status) { + case SUCCESS: + LOG.info("Found data for query [" + sqlStmt + "]"); + break; + case NOT_FOUND: + LOG.info("Did not data for query [" + sqlStmt + "]"); + break; + default: + fail("Failure executing query [" + sqlStmt + "]"); + + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + fail("Caught exception running tests"); + } + + + testStr = getClass().getResourceAsStream("/delete.tests"); + testsReader = new BufferedReader(new InputStreamReader(testStr)); + + try { + String testExpr = null; + + int testNum = 0; + while ((testExpr = testsReader.readLine()) != null) { + testExpr = testExpr.trim(); + if (testExpr.startsWith("#")) { + testExpr = testExpr.substring(1).trim(); + String[] nameValue = testExpr.split("="); + String name = nameValue[0].trim(); + String value = nameValue[1].trim(); + + LOG.info("Setting context attribute " + name + " = " + + value); + ctx.setAttribute(name, value); + + } else { + + testNum++; + + String sqlStmt = testExpr; + QueryStatus status = sqlResource.delete("SQL", sqlStmt, ctx); + + switch (status) { + case SUCCESS: + LOG.info("Found data for query [" + sqlStmt + "]"); + break; + case NOT_FOUND: + LOG.info("Did not data for query [" + sqlStmt + "]"); + break; + default: + fail("Failure executing query [" + sqlStmt + "]"); + + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + fail("Caught exception running tests"); + } + + for (String attrName : ctx.getAttributeKeySet()) { + LOG.info("ctx.getAttribute("+attrName+") = "+ctx.getAttribute(attrName)); + } + } + +} diff --git a/sql-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResourceProviderTest.java b/sql-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResourceProviderTest.java new file mode 100755 index 000000000..b261b9f7d --- /dev/null +++ b/sql-resource/provider/src/test/java/org/onap/ccsdk/sli/adaptors/resource/sql/SqlResourceProviderTest.java @@ -0,0 +1,38 @@ +package org.onap.ccsdk.sli.adaptors.resource.sql; + +import static org.junit.Assert.assertNotNull; +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Properties; + +import org.junit.Test; + +public class SqlResourceProviderTest { + + private static SqlResourcePropertiesProvider provider; + private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR"; + + @Test + public void testSqlResourceProvider() { + try{ + Map<String, String> env = System.getenv(); + Class<?> cl = env.getClass(); + Field field = cl.getDeclaredField("m"); + field.setAccessible(true); + Map<String, String> writableEnv = (Map<String, String>) field.get(env); + writableEnv.put(SDNC_CONFIG_DIR, "./src/test/resources"); + } catch (Exception e) { + throw new IllegalStateException("Failed to set environment variable", e); + } + + provider = new SqlResourcePropertiesProviderImpl(); + assertNotNull(provider); + } + + @Test + public void testGetProperties() { + Properties properties = provider.getProperties(); + assertNotNull(properties); + } + +} diff --git a/sql-resource/provider/src/test/resources/delete.tests b/sql-resource/provider/src/test/resources/delete.tests new file mode 100755 index 000000000..a60a3bc73 --- /dev/null +++ b/sql-resource/provider/src/test/resources/delete.tests @@ -0,0 +1,2 @@ +DROP TABLE SQLRESOURCE_ORDER; +DROP TABLE SQLRESOURCE_ORDER_ITEM; diff --git a/sql-resource/provider/src/test/resources/query.tests b/sql-resource/provider/src/test/resources/query.tests new file mode 100755 index 000000000..ec05c22e3 --- /dev/null +++ b/sql-resource/provider/src/test/resources/query.tests @@ -0,0 +1,5 @@ +# max-price = 100 +SELECT * FROM SQLRESOURCE_ORDER where placed_on < now(); +SELECT SQLRESOURCE_ORDER.order_number, clli, service, price FROM SQLRESOURCE_ORDER, SQLRESOURCE_ORDER_ITEM where SQLRESOURCE_ORDER.order_number = SQLRESOURCE_ORDER_ITEM.order_number and price > $max-price ; +SELECT SQLRESOURCE_ORDER.order_number, clli, service, price FROM SQLRESOURCE_ORDER, SQLRESOURCE_ORDER_ITEM where SQLRESOURCE_ORDER.order_number = SQLRESOURCE_ORDER_ITEM.order_number and price < $max-price ; +SELECT SQLRESOURCE_ORDER.order_number AS ordernum, clli, service, price FROM SQLRESOURCE_ORDER, SQLRESOURCE_ORDER_ITEM where SQLRESOURCE_ORDER.order_number = SQLRESOURCE_ORDER_ITEM.order_number and price < $max-price ; diff --git a/sql-resource/provider/src/test/resources/save.tests b/sql-resource/provider/src/test/resources/save.tests new file mode 100755 index 000000000..e2c42217d --- /dev/null +++ b/sql-resource/provider/src/test/resources/save.tests @@ -0,0 +1,13 @@ +# order-number = 1234 +# zero = 0 +# item[0].clli = MTJNJA14 +# item[0].service = NoD +# item[0].price = 1000000 +# item[1].clli = MTJNJA14 +# item[1].service = Pizza +# item[1].price = 10 +CREATE TABLE IF NOT EXISTS SQLRESOURCE_ORDER (order_number VARCHAR(40), placed_on TIMESTAMP); +CREATE TABLE IF NOT EXISTS SQLRESOURCE_ORDER_ITEM (order_number VARCHAR(40), clli VARCHAR(40), service VARCHAR(40), price INTEGER(4)); +INSERT INTO SQLRESOURCE_ORDER VALUES ( $order-number , now()); +INSERT INTO SQLRESOURCE_ORDER_ITEM VALUES( $order-number , $item[$zero].clli , $item[0].service , $item[0].price ); +INSERT INTO SQLRESOURCE_ORDER_ITEM VALUES( $order-number , $item[1].clli , $item[1].service , $item[1].price ); diff --git a/sql-resource/provider/src/test/resources/simplelogger.properties b/sql-resource/provider/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..61d82660f --- /dev/null +++ b/sql-resource/provider/src/test/resources/simplelogger.properties @@ -0,0 +1,22 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +org.slf4j.simpleLogger.defaultLogLevel=debug diff --git a/sql-resource/provider/src/test/resources/sql-resource.properties b/sql-resource/provider/src/test/resources/sql-resource.properties new file mode 100755 index 000000000..ac32f7734 --- /dev/null +++ b/sql-resource/provider/src/test/resources/sql-resource.properties @@ -0,0 +1,23 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### + +org.openecomp.sdnc.resource.sql.cryptkey=QtfJMKggVk + diff --git a/sql-resource/provider/src/test/resources/svclogic.properties b/sql-resource/provider/src/test/resources/svclogic.properties new file mode 100644 index 000000000..6504e1aec --- /dev/null +++ b/sql-resource/provider/src/test/resources/svclogic.properties @@ -0,0 +1,35 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : SDN-C +# ================================================================================ +# 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========================================================= +### +org.onap.ccsdk.sli.dbtype=jdbc + +org.onap.ccsdk.sli.jdbc.hosts=sdnctldb01 +org.onap.ccsdk.sli.jdbc.url=jdbc:mysql://dbhost:3306/sdnctl +org.onap.ccsdk.sli.jdbc.driver=org.mariadb.jdbc.Driver +org.onap.ccsdk.sli.jdbc.database=sdnctl +org.onap.ccsdk.sli.jdbc.user=sdnctl +org.onap.ccsdk.sli.jdbc.password=gamma +org.onap.ccsdk.sli.jdbc.connection.name=sdnctldb01 +org.onap.ccsdk.sli.jdbc.connection.timeout=50 +org.onap.ccsdk.sli.jdbc.request.timeout=100 +org.onap.ccsdk.sli.jdbc.limit.init=10 +org.onap.ccsdk.sli.jdbc.limit.min=10 +org.onap.ccsdk.sli.jdbc.limit.max=20 +org.onap.dblib.connection.recovery=false diff --git a/version.properties b/version.properties index ca85875b1..977efc0e3 100644 --- a/version.properties +++ b/version.properties @@ -2,14 +2,3 @@ # Versioning variables # Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... ) # because they are used in Jenkins, whose plug-in doesn't support - - -release_name=1 -sprint_number=1 -feature_revision=1 - -base_version=${release_name}.${sprint_number}.${feature_revision} - -release_version=${base_version} -snapshot_version=${base_version}-SNAPSHOT - |