Initial code submit for Babel 67/14667/3
authorEdwin Lawrance <Edwin.Lawrance@amdocs.com>
Fri, 22 Sep 2017 15:55:07 +0000 (16:55 +0100)
committerEdwin Lawrance <Edwin.Lawrance@amdocs.com>
Thu, 5 Oct 2017 10:36:10 +0000 (11:36 +0100)
Change-Id: I3738ebe15eadbbd6d16e24e374c6e40c535b425d
Issue-ID: AAI-46
Signed-off-by: Edwin Lawrance <Edwin.Lawrance@amdocs.com>
91 files changed:
License.txt [new file with mode: 0644]
ajsc-shared-config/README.txt [new file with mode: 0644]
ajsc-shared-config/etc/aft.properties [new file with mode: 0644]
ajsc-shared-config/etc/basic-logback_root_logger_level_off.xml [new file with mode: 0644]
ajsc-shared-config/etc/logback.xml [new file with mode: 0644]
ajsc-shared-config/etc/spm2.jks [new file with mode: 0644]
antBuild/build.xml [new file with mode: 0644]
appconfig-local/readme.txt [new file with mode: 0644]
bundleconfig-local/README.txt [new file with mode: 0644]
bundleconfig-local/RELEASE_NOTES.txt [new file with mode: 0644]
bundleconfig-local/etc/appprops/AAFUserRoles.properties [new file with mode: 0644]
bundleconfig-local/etc/appprops/PostProcessorInterceptors.properties [new file with mode: 0644]
bundleconfig-local/etc/appprops/PreProcessorInterceptors.properties [new file with mode: 0644]
bundleconfig-local/etc/appprops/app-intercepts.properties [new file with mode: 0644]
bundleconfig-local/etc/appprops/methodMapper.properties [new file with mode: 0644]
bundleconfig-local/etc/sysprops/sys-props.properties [new file with mode: 0644]
pom.xml [new file with mode: 0644]
src/main/ajsc/babel_v1/babel/v1/conf/babel-beans.xml [new file with mode: 0644]
src/main/ajsc/babel_v1/babel/v1/docs/README.txt [new file with mode: 0644]
src/main/ajsc/babel_v1/babel/v1/lib/README.txt [new file with mode: 0644]
src/main/ajsc/babel_v1/babel/v1/props/module.props [new file with mode: 0644]
src/main/ajsc/babel_v1/babel/v1/routes/babel-service.route [new file with mode: 0644]
src/main/assemble/ajsc_module_assembly.xml [new file with mode: 0644]
src/main/assemble/ajsc_props_assembly.xml [new file with mode: 0644]
src/main/assemble/ajsc_runtime_assembly.xml [new file with mode: 0644]
src/main/bin/start.sh [new file with mode: 0644]
src/main/config/ajsc-chef.jks [new file with mode: 0644]
src/main/config/ajsc-jetty.xml [new file with mode: 0644]
src/main/config/ajsc-override-web.xml [new file with mode: 0644]
src/main/config/ajscJetty.jks [new file with mode: 0644]
src/main/config/cadi.properties [new file with mode: 0644]
src/main/config/jul-redirect.properties [new file with mode: 0644]
src/main/config/keyfile [new file with mode: 0644]
src/main/config/runner-web.xml [new file with mode: 0644]
src/main/docker/Dockerfile [new file with mode: 0644]
src/main/java/org/onap/aai/auth/AAIAuthException.java [new file with mode: 0644]
src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java [new file with mode: 0644]
src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java [new file with mode: 0644]
src/main/java/org/onap/aai/auth/FileWatcher.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/csar/CsarConverterException.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/csar/extractor/InvalidArchiveException.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/csar/extractor/YamlExtractor.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/service/data/BabelArtifact.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/service/data/BabelRequest.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/util/RequestValidationException.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/util/RequestValidator.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/xml/generator/ArtifactGenerator.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java [new file with mode: 0644]
src/main/java/org/onap/aai/babel/xml/generator/XmlArtifactGenerationException.java [new file with mode: 0644]
src/main/resources/babel-logging-resources.properties [new file with mode: 0644]
src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context [new file with mode: 0644]
src/main/runtime/context/default#0.context [new file with mode: 0644]
src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json [new file with mode: 0644]
src/main/runtime/shiroRole/ajscadmin.json [new file with mode: 0644]
src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json [new file with mode: 0644]
src/main/runtime/shiroRole/contextadmin#default.json [new file with mode: 0644]
src/main/runtime/shiroUser/ajsc.json [new file with mode: 0644]
src/main/runtime/shiroUserRole/ajsc#ajscadmin.json [new file with mode: 0644]
src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json [new file with mode: 0644]
src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json [new file with mode: 0644]
src/test/java/org/onap/aai/babel/MicroServiceAuthTest.java [new file with mode: 0644]
src/test/java/org/onap/aai/babel/csar/extractor/YamlExtractorTest.java [new file with mode: 0644]
src/test/java/org/onap/aai/babel/csar/fixture/ArtifactInfoBuilder.java [new file with mode: 0644]
src/test/java/org/onap/aai/babel/csar/fixture/TestArtifactInfoImpl.java [new file with mode: 0644]
src/test/java/org/onap/aai/babel/service/CsarToXmlConverterTest.java [new file with mode: 0644]
src/test/java/org/onap/aai/babel/service/TestGenerateArtifactsServiceImpl.java [new file with mode: 0644]
src/test/java/org/onap/aai/babel/util/ArtifactTestUtils.java [new file with mode: 0644]
src/test/java/org/onap/aai/babel/util/TestRequestValidator.java [new file with mode: 0644]
src/test/resources/artifact-generator.properties [new file with mode: 0644]
src/test/resources/auth/auth_policy.json [new file with mode: 0644]
src/test/resources/compressedArtifacts/noYmlFilesArchive.zip [new file with mode: 0644]
src/test/resources/compressedArtifacts/service-SdWanServiceTest-csar.csar [new file with mode: 0644]
src/test/resources/generatedXml/AAI-SD-WAN-Service-Test-service-1.0.xml [new file with mode: 0644]
src/test/resources/generatedXml/AAI-SD-WAN-Test-VSP-resource-1.0.xml [new file with mode: 0644]
src/test/resources/generatedXml/AAI-SdWanTestVsp..DUMMY..module-0-resource-2.xml [new file with mode: 0644]
src/test/resources/generatedXml/AAI-Tunnel_XConnTest-resource-2.0.xml [new file with mode: 0644]
src/test/resources/jsonFiles/invalid_csar_request.json [new file with mode: 0644]
src/test/resources/jsonFiles/invalid_json_request.json [new file with mode: 0644]
src/test/resources/jsonFiles/missing_artifact_name_request.json [new file with mode: 0644]
src/test/resources/jsonFiles/missing_artifact_version_request.json [new file with mode: 0644]
src/test/resources/jsonFiles/missing_csar_request.json [new file with mode: 0644]
src/test/resources/jsonFiles/success_request.json [new file with mode: 0644]
src/test/resources/response/response.json [new file with mode: 0644]
src/test/resources/ymlFiles/resource-SdWanTestVsp-template.yml [new file with mode: 0644]
src/test/resources/ymlFiles/resource-TunnelXconntest-template.yml [new file with mode: 0644]
src/test/resources/ymlFiles/service-SdWanServiceTest-template.yml [new file with mode: 0644]

diff --git a/License.txt b/License.txt
new file mode 100644 (file)
index 0000000..3452576
--- /dev/null
@@ -0,0 +1,20 @@
+============LICENSE_START=======================================================
+org.onap.aai
+================================================================================
+Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+Copyright Â© 2017 European Software Marketing Ltd.
+================================================================================
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
\ No newline at end of file
diff --git a/ajsc-shared-config/README.txt b/ajsc-shared-config/README.txt
new file mode 100644 (file)
index 0000000..e0f7ff1
--- /dev/null
@@ -0,0 +1,8 @@
+#Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+
+The ajsc-shared-config folder is included in the service project to provide the functionality of the AJSC_SHARED_CONFIG 
+location that will exist in CSI envs. This includes the logback.xml for logging configurations, and some csm related 
+artifacts necessary for proper functionality of the csm framework within the CSI env. Within the 2 profiles that can 
+be utilized to run the AJSC locally, "runLocal" and "runAjsc", the system propery, "AJSC_SHARED_CONFIG", has been set
+to point to this directory. The files in this folder will NOT be copied/moved anywhere within the AJSC SWM package. These 
+files will already be in existence within the CSI env.
\ No newline at end of file
diff --git a/ajsc-shared-config/etc/aft.properties b/ajsc-shared-config/etc/aft.properties
new file mode 100644 (file)
index 0000000..95c7762
--- /dev/null
@@ -0,0 +1,15 @@
+#Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+# Flow test 319
+# The DEFAULT setup for this file is for deployment to soa cloud node which will use the "bundleconfig/etc/spm2.jks" location
+# For Testing Locally, you can set the system property, csiEnable=true, found within bundleconfig-local/etc/sysprops/sys-props.properties
+# and switch com.att.aft.keyStore and com.att.aft.trustStore values commented out below to "ajsc-shared-config/etc/spm2.jks"
+
+#replace proper values for the dummy values.
+com.att.aft.discovery.client.environment=TEST
+com.att.aft.discovery.client.latitude=35.318900
+com.att.aft.discovery.client.longitude=-80.762200
+com.att.aft.alias=fusionbus
+com.att.aft.keyStore=bundleconfig/etc/key.jks
+com.att.aft.keyStorePassword=password
+com.att.aft.trustStore=bundleconfig/etc/key.jks
+com.att.aft.trustStorePassword=password
diff --git a/ajsc-shared-config/etc/basic-logback_root_logger_level_off.xml b/ajsc-shared-config/etc/basic-logback_root_logger_level_off.xml
new file mode 100644 (file)
index 0000000..4ebe2db
--- /dev/null
@@ -0,0 +1,87 @@
+<!-- 
+ Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+-->
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+       <property name="logDirectory" value="${AJSC_HOME}/log" />
+       <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>ERROR</level>
+               </filter>
+               <encoder>
+                       <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n
+                       </pattern>
+               </encoder>
+       </appender>
+
+       <appender name="INFO"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>DEBUG</level>
+               </filter>
+               <file>${logDirectory}/info_ajsc.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+                       <fileNamePattern>${logDirectory}/info_ajsc.%i.log.zip
+                       </fileNamePattern>
+                       <minIndex>1</minIndex>
+                       <maxIndex>9</maxIndex>
+               </rollingPolicy>
+               <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy>
+               <encoder>
+                       <pattern>"%d [%thread] %-5level %logger{1024} - %msg%n"</pattern>
+               </encoder>
+       </appender>
+       <appender name="ERROR"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>ERROR</level>
+               </filter>
+               <file>${logDirectory}/error_ajsc.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+                       <fileNamePattern>${logDirectory}/error_ajsc.%i.log.zip
+                       </fileNamePattern>
+                       <minIndex>1</minIndex>
+                       <maxIndex>9</maxIndex>
+               </rollingPolicy>
+               <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy>
+               <encoder>
+                       <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n"</pattern> -->
+                       <pattern>"%d [%thread] %-5level %logger{1024} - %msg%n"</pattern>
+               </encoder>
+       </appender>
+
+       <appender name="AJSC-AUDIT" class="ch.qos.logback.classic.net.SyslogAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>INFO</level>
+               </filter>
+               <syslogHost>localhost</syslogHost>
+               <facility>USER</facility>
+               <!-- Note the colon character below - it is important part of "TAG" message 
+                       format You need a colon to determine where the TAG field ends and the CONTENT 
+                       begins -->
+               <suffixPattern>AJSC_AUDIT: [%thread] [%logger] %msg</suffixPattern>
+       </appender>
+       <appender name="CONTROLLER-AUDIT" class="ch.qos.logback.classic.net.SyslogAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>INFO</level>
+               </filter>
+               <syslogHost>localhost</syslogHost>
+               <facility>USER</facility>
+               <!-- Note the colon character below - it is important part of "TAG" message 
+                       format You need a colon to determine where the TAG field ends and the CONTENT 
+                       begins -->
+               <suffixPattern>AJSC_AUDIT: [%thread] [%logger] mdc:[%mdc] %msg
+               </suffixPattern>
+       </appender>
+
+       <root level="off">
+               <appender-ref ref="ERROR" />
+               <appender-ref ref="INFO" />
+               <appender-ref ref="STDOUT" />
+       </root>
+</configuration>
diff --git a/ajsc-shared-config/etc/logback.xml b/ajsc-shared-config/etc/logback.xml
new file mode 100644 (file)
index 0000000..7830b10
--- /dev/null
@@ -0,0 +1,212 @@
+<configuration scan="true" scanPeriod="3 seconds" debug="false">
+  <!--<jmxConfigurator /> -->
+  <!-- directory path for all other type logs -->
+  
+  <property name="logDir"  value="${AJSC_HOME}/logs" />
+  
+  
+  <!--  specify the component name 
+       <ECOMP-component-name>::= "MSO" | "DCAE" | "ASDC " | "AAI" |"Policy" | "SDNC" | "AC"  -->
+  <property name="componentName" value="AAI-BAS" />
+  
+  <!--  default eelf log file names -->
+  <property name="generalLogName" value="error" />
+  <property name="metricsLogName" value="metrics" />
+  <property name="auditLogName" value="audit" />
+  <property name="debugLogName" value="debug" />
+  
+  <property name="errorLogPattern" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%mdc{RequestId}|%thread|Babel|%mdc{PartnerName}|%logger||%.-5level|%msg%n" />
+  <property name="auditMetricPattern" value="%m%n" />
+
+  <property name="logDirectory" value="${logDir}/${componentName}" />
+  
+  <!-- Example evaluator filter applied against console appender -->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>${errorLogPattern}</pattern>
+    </encoder>
+  </appender>
+
+  <!-- ============================================================================ -->
+  <!-- EELF Appenders -->
+  <!-- ============================================================================ -->
+  
+  <!-- The EELFAppender is used to record events to the general application 
+       log -->
+  
+  <appender name="EELF"
+            class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${generalLogName}.log</file>
+    <rollingPolicy
+        class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+      <fileNamePattern>${logDirectory}/${generalLogName}.%d{yyyy-MM-dd}.log.zip
+      </fileNamePattern>
+      <maxHistory>60</maxHistory>
+    </rollingPolicy>
+    <encoder>
+      <pattern>${errorLogPattern}</pattern>
+    </encoder>
+  </appender>
+  <appender name="asyncEELF" class="ch.qos.logback.classic.AsyncAppender">
+    <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+      <level>INFO</level>
+    </filter>
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELF" />
+  </appender>
+
+  
+  <!-- EELF Audit Appender. This appender is used to record audit engine 
+       related logging events. The audit logger and appender are specializations 
+       of the EELF application root logger and appender. This can be used to segregate 
+       Policy engine events from other components, or it can be eliminated to record 
+       these events as part of the application root log. -->
+  
+  <appender name="EELFAudit"
+            class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${auditLogName}.log</file>
+    <rollingPolicy
+        class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+      <fileNamePattern>${logDirectory}/${auditLogName}.%d{yyyy-MM-dd}.log.zip
+      </fileNamePattern>
+      <maxHistory>60</maxHistory>
+    </rollingPolicy>
+    <encoder>
+      <pattern>${auditMetricPattern}</pattern>
+    </encoder>
+  </appender>
+  <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFAudit" />
+  </appender>
+  
+  <appender name="EELFMetrics"
+            class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${metricsLogName}.log</file>
+    <rollingPolicy
+        class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+      <fileNamePattern>${logDirectory}/${metricsLogName}.%d{yyyy-MM-dd}.log.zip
+      </fileNamePattern>
+      <maxHistory>60</maxHistory>
+    </rollingPolicy>
+    <encoder>
+      <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - 
+           %msg%n"</pattern> -->
+      <pattern>${auditMetricPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  
+  <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFMetrics"/>
+  </appender>
+  
+  <appender name="EELFDebug"
+            class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${logDirectory}/${debugLogName}.log</file>
+    <rollingPolicy
+        class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+      <fileNamePattern>${logDirectory}/${debugLogName}.%d{yyyy-MM-dd}.log.zip
+      </fileNamePattern>
+      <maxHistory>60</maxHistory>
+    </rollingPolicy>
+    <encoder>
+      <pattern>${errorLogPattern}</pattern>
+    </encoder>
+  </appender>
+  
+  <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+    <queueSize>256</queueSize>
+    <appender-ref ref="EELFDebug" />
+    <includeCallerData>false</includeCallerData>
+  </appender>
+  
+  
+  <!-- ============================================================================ -->
+  <!--  EELF loggers -->
+  <!-- ============================================================================ -->
+  <logger name="com.att.eelf" level="info" additivity="false">
+    <appender-ref ref="asyncEELF" />
+    <appender-ref ref="asyncEELFDebug" />
+  </logger>
+
+  <logger name="com.att.eelf.security" level="info" additivity="false">
+    <appender-ref ref="asyncEELFSecurity" /> 
+  </logger>
+  <logger name="com.att.eelf.perf" level="info" additivity="false">
+    <appender-ref ref="asyncEELFPerformance" />
+  </logger>
+  <logger name="com.att.eelf.server" level="info" additivity="false">
+    <appender-ref ref="asyncEELFServer" />
+  </logger>
+  <logger name="com.att.eelf.policy" level="info" additivity="false">
+    <appender-ref ref="asyncEELFPolicy" />
+  </logger>
+  <logger name="com.att.eelf.audit" level="info" additivity="false">
+    <appender-ref ref="asyncEELFAudit" />
+  </logger>
+  <logger name="com.att.eelf.metrics" level="info" additivity="false">
+    <appender-ref ref="asyncEELFMetrics" />
+  </logger>
+  
+  <!-- Spring related loggers -->
+  <logger name="org.springframework" level="WARN" />
+  <logger name="org.springframework.beans" level="WARN" />
+  <logger name="org.springframework.web" level="WARN" />
+  <logger name="com.blog.spring.jms" level="WARN" />
+
+  <!-- AJSC Services (bootstrap services) -->
+  <logger name="ajsc" level="WARN" />
+  <logger name="ajsc.RouteMgmtService" level="WARN" />
+  <logger name="ajsc.ComputeService" level="WARN" />
+  <logger name="ajsc.VandelayService" level="WARN" />
+  <logger name="ajsc.FilePersistenceService" level="WARN" />
+  <logger name="ajsc.UserDefinedJarService" level="WARN" />
+  <logger name="ajsc.UserDefinedBeansDefService" level="WARN" />
+  <logger name="ajsc.LoggingConfigurationService" level="WARN" />
+  
+  <!-- AJSC related loggers (DME2 Registration, csi logging, restlet, servlet 
+       logging) -->
+  <logger name="ajsc.utils" level="WARN" />
+  <logger name="ajsc.utils.DME2Helper" level="WARN" />
+  <logger name="ajsc.filters" level="WARN" />
+  <logger name="ajsc.beans.interceptors" level="WARN" />
+  <logger name="ajsc.restlet" level="WARN" />
+  <logger name="ajsc.servlet" level="WARN" />
+  <logger name="com.att" level="INFO" />
+  <logger name="com.att.ajsc.csi.logging" level="WARN" />
+  <logger name="com.att.ajsc.filemonitor" level="WARN" />
+
+  <!-- CRUD Service loggers -->
+  <logger name="org.onap.aai.babel" level="INFO" />
+
+  <!-- Other Loggers that may help troubleshoot -->
+  <logger name="net.sf" level="WARN" />
+  <logger name="org.apache" level="WARN" />
+  <logger name="org.apache.commons.httpclient" level="WARN" />
+  <logger name="org.apache.commons" level="WARN" />
+  <logger name="org.apache.coyote" level="WARN" />
+  <logger name="org.apache.jasper" level="WARN" />
+
+  <!-- Camel Related Loggers (including restlet/servlet/jaxrs/cxf logging. 
+       May aid in troubleshooting) -->
+  <logger name="org.apache.camel" level="WARN" />
+  <logger name="org.apache.cxf" level="WARN" />
+  <logger name="org.apache.camel.processor.interceptor" level="WARN" />
+  <logger name="org.apache.cxf.jaxrs.interceptor" level="WARN" />
+  <logger name="org.apache.cxf.service" level="WARN" />
+  <logger name="org.restlet" level="WARN" />
+  <logger name="org.apache.camel.component.restlet" level="WARN" />
+
+  <!-- logback internals logging -->
+  <logger name="ch.qos.logback.classic" level="WARN" />
+  <logger name="ch.qos.logback.core" level="WARN" />
+
+  <root>
+    <appender-ref ref="asyncEELF" /> 
+    <!-- <appender-ref ref="asyncEELFDebug" /> -->
+  </root>
+  
+</configuration>
diff --git a/ajsc-shared-config/etc/spm2.jks b/ajsc-shared-config/etc/spm2.jks
new file mode 100644 (file)
index 0000000..8ff2a00
Binary files /dev/null and b/ajsc-shared-config/etc/spm2.jks differ
diff --git a/antBuild/build.xml b/antBuild/build.xml
new file mode 100644 (file)
index 0000000..ab0f890
--- /dev/null
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+ Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+-->
+<project>
+       <target name="runLocal">
+               <java dir="${basedir}" fork="yes" newenvironment="true"
+                       failonerror="true" classname="com.att.ajsc.runner.Runner">
+                       <classpath
+                               path="${classpath}:${basedir}/ajsc-shared-config/etc:${runAjscHome}/lib/ajsc-runner-${ajscRuntimeVersion}.jar" />
+
+                       <!-- Windows Users may need to add a jvmarg arg to create a temp directory 
+                               properly. -->
+                       <!-- <jvmarg value="-Djava.io.tmpdir=C:/yourTempDirectory"/> -->
+
+                       <!-- Uncomment the following 2 jvmarg values to enable Remote Debugging. 
+                        -->
+                       <!-- <jvmarg value="-Xdebug" /> -->
+                       <!-- <jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5432" 
+                               /> -->
+
+                       <jvmarg value="-XX:MaxPermSize=512m" />
+                       <jvmarg value="-Xmx1024m" />
+
+                       <!-- Main ajsc Variables below (Variables necessary for proper startup 
+                               of AJSC) -->
+                       <env key="AJSC_HOME" value="${runAjscHome}" />
+                       <sysproperty key="AJSC_HOME" value="${runAjscHome}" />
+                       <!-- you may specify any external location for AJSC_CONF_HOME where etc 
+                               folder & all other configs can be found under it. If not specified, it will 
+                               default to AJSC_HOME -->
+                       <sysproperty key="AJSC_CONF_HOME" value="${basedir}/bundleconfig-local" />
+                       <sysproperty key="AJSC_SHARED_CONFIG" value="${basedir}/ajsc-shared-config" />
+
+                       <!-- Location of logback.xml file used for logging configurations. Please, 
+                               note, when deploying a service to either CSI or NON-CSI environment, this 
+                               system property will be set in sys-props.properties file. We are setting 
+                               it here for running locally due to the ease of use of maven variable for 
+                               basedir. -->
+                       <sysproperty key="logback.configurationFile"
+                               value="${basedir}/ajsc-shared-config/etc/logback.xml" />
+
+                       <!-- Setting system properties for the AJSC external libs and properties 
+                               folders below. When deploying to a node, these properties will be set within 
+                               the bundleconfig/etc/sysprops/sys-props.properties file. However, when running 
+                               locally, the ${basedir} substitution works more efficiently in this manner. -->
+                       <sysproperty key="AJSC_EXTERNAL_LIB_FOLDERS" value="${basedir}/target/commonLibs" />
+                       <sysproperty key="AJSC_EXTERNAL_PROPERTIES_FOLDERS"
+                               value="${basedir}/ajsc-shared-config/etc" />
+
+                       <!-- End of Main ajsc Variables below (Variables necessary for proper 
+                               startup of AJSC) -->
+
+                       <!-- Uncomment the following line to add oauthentication to your Service -->
+                       <!-- <sysproperty key="spring.profiles.active" value="oauth" /> -->
+
+                       <!-- If using Cassandra as Database, Enter the ip/host and port below 
+                               based on your known configuration -->
+                       <!-- <sysproperty key="cassandra.ip" value="hostname" /> -->
+                       <!-- <sysproperty key="cassandra.port" value="9042" /> -->
+
+                       <!-- The APP_SERVLET_URL_PATTERN variable is defaulted to "/services" 
+                               within the initial configuration of the AJSC. If you are changing the CamelServlet 
+                               Filter within the ajsc-override-web.xml, you should use that url-pattern 
+                               here. This is necessary to properly register your service with dme2. An empty 
+                               value, "", is used when NO value is wanted (url-pattern would be /* for CamelServlet 
+                               Filter) -->
+                       <!-- As of 4.5.1, this property is no longer needed -->
+                       <!-- <sysproperty key="APP_SERVLET_URL_PATTERN" value="/services" /> -->
+
+                       <!-- GRM/DME2 System Properties below -->
+                       <sysproperty key="AJSC_SERVICE_NAMESPACE" value="${module.ajsc.namespace.name}" />
+                       <sysproperty key="AJSC_SERVICE_VERSION" value="${module.ajsc.namespace.version}" />
+                       <sysproperty key="SOACLOUD_SERVICE_VERSION" value="${project.version}" />
+                       <!-- End of GRM/DME2 System Property Variables -->
+
+                       <!-- The following server.port variable was necessary for the proper registration 
+                               of the AJSC to dme2. This value may still need to be used if the Developer 
+                               is hardcoding their port (example: 8080). Then, the server.port value="8080". 
+                               The default functionality for the AJSC is to use EPHEMERAL ports. In this 
+                               case, you do NOT need to set the server.port value. The AJSC will find the 
+                               proper port value and register to dme2 correctly -->
+                       <!-- <sysproperty key="server.port" value="${serverPort}" /> -->
+
+                       <!-- Command Line Arguments to add to the java command. Here, you can 
+                               specify the port as well as the Context you want your service to run in. 
+                               Use context=/ to run in an unnamed Context (Root Context). The default configuration 
+                               of the AJSC is to run under the /ajsc Context. Setting the port here can 
+                               aid during the development phase of your service. However, you can leave 
+                               this argument out entirely, and the AJSC will default to using an Ephemeral 
+                               port. -->
+                       <arg line="context=/ port=${serverPort} sslport=${sslport}" />
+               </java>
+       </target>
+       <target name="prep_home_directory_for_swm_pkgcreate">
+
+<!-- ********* GENERATE CADI KEY AND ENCRYPTED PASSWORD ***********
+     
+            Uncomment the following if your cadi key get corrupted , It would 
+                       generate the Cadi key and password in the package phase and keep the key 
+                       in the 'src/main/config/ajscKey' and password in the bottom of cadi.properties(you 
+                       need to modify the 'aaf_pass' variable with this value . Plese modify the 
+                       template.cadi.properties as well before uploading to SOA node 
+-->
+
+<!-- 
+               <java jar="${basedir}/target/userjars/cadi-core-1.2.5.jar" fork="true"> 
+               <arg value="keygen" /> <arg value="src/main/config/ajscKey" /> 
+               </java> 
+               
+               <echo>***Cadi Key file generated ****</echo> 
+               
+               <java jar="${basedir}/target/userjars/cadi-core-1.2.5.jar" 
+               fork="true" append="true" output="${basedir}/src/main/config/cadi.properties"> 
+               <arg value="digest" /> <arg value="ajscRocks!" /> <arg value="src/main/config/ajscKey" 
+               /> 
+               </java> 
+               
+-->
+
+
+
+               <!-- These tasks are copying contents from the installHomeDirectory into 
+                       the eventual $AJSC_HOME directory for running locally and soa cloud installation -->
+               <echo message="ENTERING 'prep_home_directory_for_swm_pkgcreate' ant tasks" />
+
+               <!-- Please, NOTE: The ajsc-archetype is setup for a default CSI Env deployment. 
+                       If you are deploying to a CSI Env, you should NOT have to change anything 
+                       within this build file. However, if you are NOT deploying to a CSI Env, you 
+                       should comment OUT the CSI related portion of this build.xml. -->
+
+               <!-- The following code snippet is copying the bundleconfig-csi directory 
+                       to the proper installation/bundleconfig directory used in CSI envs. If you 
+                       are NOT installing to a CSI node, you should comment out (or delete) the 
+                       following snippet, and uncomment the NON-CSI copy task to copy EVERYTHING 
+                       to the installation/bundleconfig directory. -->
+
+               <!-- CSI related bundleconfig copy task. If you are NOT deploying to a 
+                       CSI Env, please COMMENT OUT or delete the following copy task code snippet. -->
+               <!--<copy toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/bundleconfig" 
+                       failonerror="true"> <fileset dir="${basedir}/bundleconfig-csi" /> </copy> -->
+               <!-- End of CSI related bundleconfig copy task -->
+
+               <!-- NOTE: If you are NOT deploying to CSI environment, and you are NOT 
+                       using an AJSC_SHARED_CONFIG location on a node, you should go ahead and copy 
+                       EVERYTHING from bundleconfig and ajsc-shared-config (logback.xml) directory 
+                       to utilize proper logging from logback.xml. Simply, uncomment the following 
+                       code snippet below to copy EVERYTHING and comment out the CSI related build 
+                       script above. -->
+               <!-- NON-CSI related build copy task. Please, uncomment the following code 
+                       snippet to deploy the proper artifacts to a NON-CSI Env. -->
+               <copy
+                       toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/bundleconfig"
+                       failonerror="true">
+                       <fileset dir="${basedir}/bundleconfig-local" includes="**/**" />
+               </copy>
+               <copy
+                       toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/bundleconfig/etc"
+                       failonerror="true">
+                       <fileset dir="${basedir}/ajsc-shared-config/etc" includes="**/**" />
+               </copy>
+               <!-- End of NON-CSI related build copy task. -->
+
+               <!-- Copying any zips (deployment packages) to $AJSC_HOME/services for 
+                       auto-deployment -->
+               <copy
+                       toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/services"
+                       failonerror="false">
+                       <fileset dir="${basedir}/services" includes="*.zip" />
+               </copy>
+
+               <!-- Copying runtimeEnvironment zip file to $AJSC_HOME/runtime and renaming 
+                       runtimeEnvironment.zip for proper auto-deployment of ajsc services. 
+               <copy
+                       tofile="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/runtime/runtimeEnvironment.zip">
+                       <fileset dir="target" includes="*-runtimeEnvironment.zip" />
+               </copy>-->
+
+               <!-- Copying dependencies from the service project (not provided by AJSC 
+                       Container) to the $AJSC_HOME/extJars folder to be accessible on the classpath -->
+               <copy
+                       toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/extJars"
+                       failonerror="false">
+                       <fileset dir="target/userjars" includes="*" />
+               </copy>
+
+               <!-- extApps directory MUST be created for ajsc-runner to run correctly, 
+                       even if empty. DO NOT REMOVE!!! -->
+               <!-- extApps directory created to deploy other war files on startup or 
+                       hot deploy War files after ajsc starts up. -->
+               <mkdir
+                       dir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/extApps" />
+
+               <!-- Copying any extra wars to $AJSC_HOME/extApps to be deployed within 
+                       AJSC -->
+               <copy
+                       toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/extApps"
+                       failonerror="false">
+                       <fileset dir="${basedir}/src/main/resources/extApps"
+                               includes="*" />
+               </copy>
+
+               <!-- staticContent folder is for serving static content within an ajsc 
+                       service. Any static content to be served will be copyied to the ultimate 
+                       $AJSC_HOME/staticContent folder and can be served with the att-static-content 
+                       camel component. -->
+               <!-- Uncomment the following snippet to copy items from staticContent folder 
+                       to ultimate $AJSC_HOME/staticConent -->
+               <!-- <copy toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/staticContent" 
+                       failonerror="false"> <fileset dir="${basedir}/staticContent" includes="**/**" 
+                       /> </copy> -->
+
+               <!-- Copying extra jar files that have been labeled as dependencies in 
+                       service project to /extJars folder to be made available on the classpath 
+                       for your service -->
+               <copy
+                       toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/extJars"
+                       failonerror="false">
+                       <fileset dir="target" includes="*.jar" />
+               </copy>
+
+               <!-- Copying deployment packages created within the project to the $AJSC_HOME/services 
+                       folder to be auto deployed. -->
+               <copy
+                       toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/services">
+                       <fileset dir="target" includes="*.zip" excludes="*-runtimeEnvironment.zip" />
+               </copy>
+
+               <echo message="EXITING 'prep_assembly_output_for_swm_plugin' ant tasks" />
+       </target>
+</project>
diff --git a/appconfig-local/readme.txt b/appconfig-local/readme.txt
new file mode 100644 (file)
index 0000000..79cf29e
--- /dev/null
@@ -0,0 +1 @@
+Relevant configuration files need to be copied here to successfully run this service locally.
\ No newline at end of file
diff --git a/bundleconfig-local/README.txt b/bundleconfig-local/README.txt
new file mode 100644 (file)
index 0000000..37f2670
--- /dev/null
@@ -0,0 +1,2 @@
+#Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+The bundleconfig-local directory contains the necessary configuration files 
\ No newline at end of file
diff --git a/bundleconfig-local/RELEASE_NOTES.txt b/bundleconfig-local/RELEASE_NOTES.txt
new file mode 100644 (file)
index 0000000..3cc5590
--- /dev/null
@@ -0,0 +1,2 @@
+#Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+Place Release Notes here to provide updated Release information 
\ No newline at end of file
diff --git a/bundleconfig-local/etc/appprops/AAFUserRoles.properties b/bundleconfig-local/etc/appprops/AAFUserRoles.properties
new file mode 100644 (file)
index 0000000..adb7a10
--- /dev/null
@@ -0,0 +1,13 @@
+#Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+
+#If using AAF for Role based authentication/authorization, define your routes/services which will utilize AAF. The AJSC will
+#read this file and protect the routes given with the AAF role defined.
+
+#The following example would protect the JAXRS echo example service provided with the archetype.
+#/services/${namespace}/v1/jaxrs-services/jaxrsExample/echo/*=com.att.ajsc.myper|mymachine|manage
+
+#The following example would protect ALL AJSC services running within your project.
+#/**=com.att.ajsc.myperm|mymachine|manage
+
+#The following example would protect ALL REST services utilizing the Camel restlet routes.
+#/rest/**=com.att.ajsc.myperm|mymachine|manage
diff --git a/bundleconfig-local/etc/appprops/PostProcessorInterceptors.properties b/bundleconfig-local/etc/appprops/PostProcessorInterceptors.properties
new file mode 100644 (file)
index 0000000..08ffefa
--- /dev/null
@@ -0,0 +1,3 @@
+#Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+#This properties file is for defining any PostProcessorInterceptors that have been created for your AJSC service.
+
diff --git a/bundleconfig-local/etc/appprops/PreProcessorInterceptors.properties b/bundleconfig-local/etc/appprops/PreProcessorInterceptors.properties
new file mode 100644 (file)
index 0000000..1383071
--- /dev/null
@@ -0,0 +1,4 @@
+#Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+#This properties file is for defining any PreProcessorInterceptors that have been created for your AJSC service. 
+
+/**=com.att.ajsc.csi.restmethodmap.RestMethodMapInterceptor
diff --git a/bundleconfig-local/etc/appprops/app-intercepts.properties b/bundleconfig-local/etc/appprops/app-intercepts.properties
new file mode 100644 (file)
index 0000000..4dc09b9
--- /dev/null
@@ -0,0 +1,8 @@
+#Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+
+#This is where all your application intercept strategies must be configured. AJSC reads this property file and adds
+#the list of intercepts specified here to the camel context. This can be useful for accessing every exchange object transferred from/to
+#each endpoint in the request/response flow and can allow for more precise debugging and/or processing of the exchange. 
+
+#e.g. 
+#intercepts=org.onap.aai.JaxrsEchoService,packagename.class1name,packagename.class2name
diff --git a/bundleconfig-local/etc/appprops/methodMapper.properties b/bundleconfig-local/etc/appprops/methodMapper.properties
new file mode 100644 (file)
index 0000000..45ab671
--- /dev/null
@@ -0,0 +1,46 @@
+//
+//Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+//     Json object holds the method mapping.Update the JSON object with the proper route to logical mapping based 
+//     on the example provided below : 
+//     "helloWorld"  = Service Name
+//     "method"   = http method
+//     "url" = the url component from the route
+//     "logicalName"=  When a combination of method and url from the route matches the json object , 
+//     the logical name is put in the http header as "x-CSI-ServiceName" and "x-CSI-MethodName" 
+//     "dme2url"= if provided it register the endpoint to GRM, it is optional. This is useful for JAX-RS services.
+  
+{
+    "helloWorld": [
+        {
+            "method": "get",
+            "url": "/rest/babel/v1/helloWorld",
+            "logicalName": "GetMethod(Logical)"
+        },
+        {
+            "method": "get",
+            "url": "/services/babel/v1/jaxrsExample/jaxrs-services/echo/{input}",
+            "logicalName": "GetJaxrsExampleEcho(Logical)",
+            "dme2url": "/services/babel/v1/jaxrsExample/jaxrs-services/echo/{input}"
+        },
+        {
+            "method": "get",
+            "url": "/services/babel/v1/jaxrsExample/jaxrs-services/property/{fileName}/{input}",
+            "logicalName": "GetJaxrsExampleProperty(Logical)",
+            "dme2url": "/services/babel/v1/jaxrsExample/jaxrs-services/property/{fileName}/{input}"
+        }
+    ],
+            "errormessage":
+           [
+               {
+                       "method": "get",
+                       "url": "/services/babel/v1/jaxrsExample/errormessage/emls",
+                       "logicalName": "setCAETHeaders(Logical)"
+               },
+               {
+                       "method": "get",
+                       "url": "/services/babel/v1/errorMessageLookupService2",
+                       "logicalName": "setCAETHeaders(Logical)"
+               }        
+           
+           ]
+}
\ No newline at end of file
diff --git a/bundleconfig-local/etc/sysprops/sys-props.properties b/bundleconfig-local/etc/sysprops/sys-props.properties
new file mode 100644 (file)
index 0000000..6657f45
--- /dev/null
@@ -0,0 +1,115 @@
+#Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+#This file is used for defining AJSC system properties for different configuration schemes and is necessary for the AJSC to run properly.
+#The sys-props.properties file is used for running locally. The template.sys-props.properties file will be used when deployed
+#to a SOA/CSI Cloud node. 
+
+#AJSC System Properties. The following properties are required for ALL AJSC services. If you are adding System Properties for your
+#particular service, please add them AFTER all AJSC related System Properties. 
+
+#For Cadi Authorization, use value="authentication-scheme-1
+CadiAuthN=authentication-scheme-1
+
+#For Basic Authorization, use value="authentication-scheme-1
+authN=authentication-scheme-2
+
+#Persistence used for AJSC meta-data storage. For most environments, "file" should be used.
+ajscPersistence=file
+
+#For Direct Invocation to be enabled (values=true/false)
+directInvocationEnable=false
+
+# If using hawtio for local development, these properties will allow for faster server startup and usage for local development
+
+hawtio.authenticationEnabled=false
+hawtio.config.pullOnStartup=false
+
+#Removes the extraneous restlet console output
+org.restlet.engine.loggerFacadeClass=org.restlet.ext.slf4j.Slf4jLoggerFacade
+
+#server.host property to be enabled for local DME2 related testing
+#server.host=<Your network IP address> 
+
+#Enable/disable SSL (values=true/false). This property also determines which protocol to use (https if true, http otherwise), to register services into GRM through DME2.
+enableSSL=true
+
+
+#Enable/disable EJB Container
+ENABLE_EJB=false
+
+#Enable/disable OSGI
+isOSGIEnable=false
+
+#Generate/Skip api docs
+isApiDoc=false
+
+#CSI related variables for CSM framework
+csm.hostname=servername
+
+
+#SOA_CLOUD_ENV is used to register your service with dme2 and can be turned off for local development (values=true/false).
+SOA_CLOUD_ENV=false
+
+#CONTINUE_ON_LISTENER_EXCEPTION will exit the application if there is a DME2 exception at the time of registration.
+CONTINUE_ON_LISTENER_EXCEPTION=false
+
+#Jetty Container ThreadCount Configuration Variables
+AJSC_JETTY_ThreadCount_MIN=1
+AJSC_JETTY_ThreadCount_MAX=200
+AJSC_JETTY_IDLETIME_MAX=3000
+
+#Camel Context level default threadPool Profile configuration
+CAMEL_POOL_SIZE=10
+CAMEL_MAX_POOL_SIZE=20
+CAMEL_KEEP_ALIVE_TIME=60
+CAMEL_MAX_QUEUE_SIZE=1000
+
+#GRM/DME2 System Properties
+AFT_DME2_CONN_IDLE_TIMEOUTMS=5000
+AJSC_ENV=SOACLOUD
+
+SOACLOUD_NAMESPACE=com.att.ajsc
+SOACLOUD_ENV_CONTEXT=DEV
+SOACLOUD_PROTOCOL=http
+SOACLOUD_ROUTE_OFFER=DEFAULT
+
+AFT_LATITUDE=23.4
+AFT_LONGITUDE=33.6
+AFT_ENVIRONMENT=AFTUAT
+
+#Restlet Component Default Properties
+RESTLET_COMPONENT_CONTROLLER_DAEMON=true
+RESTLET_COMPONENT_CONTROLLER_SLEEP_TIME_MS=100
+RESTLET_COMPONENT_INBOUND_BUFFER_SIZE=8192
+RESTLET_COMPONENT_MIN_THREADS=1
+RESTLET_COMPONENT_MAX_THREADS=10
+RESTLET_COMPONENT_LOW_THREADS=8
+RESTLET_COMPONENT_MAX_QUEUED=0
+RESTLET_COMPONENT_MAX_CONNECTIONS_PER_HOST=-1
+RESTLET_COMPONENT_MAX_TOTAL_CONNECTIONS=-1
+RESTLET_COMPONENT_OUTBOUND_BUFFER_SIZE=8192
+RESTLET_COMPONENT_PERSISTING_CONNECTIONS=true
+RESTLET_COMPONENT_PIPELINING_CONNECTIONS=false
+RESTLET_COMPONENT_THREAD_MAX_IDLE_TIME_MS=60000
+RESTLET_COMPONENT_USE_FORWARDED_HEADER=false
+RESTLET_COMPONENT_REUSE_ADDRESS=true
+
+#Externalized jar and properties file location. In CSI environments, there are a few libs that have been externalized to aid
+#in CSTEM maintenance of the versions of these libs. The most important to the AJSC is the DME2 lib. Not only is this lib necessary
+#for proper registration of your AJSC service on a node, but it is also necessary for running locally as well. Another framework
+#used in CSI envs is the CSM framework. These 2 framework libs are shown as "provided" dependencies within the pom.xml. These
+#dependencies will be copied into the target/commonLibs folder with the normal "mvn clean package" goal of the AJSC. They will
+#then be added to the classpath via AJSC_EXTERNAL_LIB_FOLDERS system property. Any files (mainly property files) that need
+#to be on the classpath should be added to the AJSC_EXTERNAL_PROPERTIES_FOLDERS system property. The default scenario when 
+#testing your AJSC service locally will utilize the target/commonLibs directory for DME2 and CSM related artifacts and 2 
+#default csm properties files will be used for local testing with anything CSM knorelated.
+#NOTE: we are using maven-replacer-plugin to replace "(doubleUnderscore)basedir(doubleUnderscore)" with ${basedir} within the 
+#target directory for running locally. Multiple folder locations can be separated by the pipe ("|") character.
+#Please, NOTE: for running locally, we are setting this system property in the antBuild/build.xml "runLocal" target and in the 
+#"runAjsc" profile within the pom.xml. This is to most effectively use maven variables (${basedir}, most specifically. Therefore,
+#when running locally, the following 2 properties should be set within the profile(s) themselves. 
+#Example: target/commonLibs|target/otherLibs
+#AJSC_EXTERNAL_LIB_FOLDERS=__basedir__/target/commonLibs
+#AJSC_EXTERNAL_PROPERTIES_FOLDERS=__basedir__/ajsc-shared-config/etc
+#End of AJSC System Properties
+
+#Service System Properties. Please, place any Service related System Properties below.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644 (file)
index 0000000..fc50e2c
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,453 @@
+<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>
+               <artifactId>ajsc-archetype-parent</artifactId>
+               <groupId>com.att.ajsc</groupId>
+               <version>2.0.0</version>
+       </parent>
+       <groupId>org.onap.aai</groupId>
+       <artifactId>babel</artifactId>
+       <version>1.0.0-SNAPSHOT</version>
+
+       <properties>
+               <module.ajsc.namespace.name>babel-service</module.ajsc.namespace.name>
+               <module.ajsc.namespace.version>v1</module.ajsc.namespace.version>
+               <ajscRuntimeVersion>2.0.0</ajscRuntimeVersion>
+               <absoluteDistFilesRoot>/appl/${project.artifactId}</absoluteDistFilesRoot>
+
+               <!-- For NO Versioning, REMOVE the /${project.version} from the <distFilesRoot> 
+                       property, below. PLEASE, NOTE: If your ${project.version} is a "-SNAPSHOT" 
+                       version, THIS will be used as your directory structure. If you do NOT want 
+                       this, simply remove the "-SNAPSHOT" from your <version> declaration at the 
+                       top of pom.xml -->
+               <distFilesRoot>/appl/${project.artifactId}/${project.version}</distFilesRoot>
+               <runAjscHome>${basedir}/target/swm/package/nix/dist_files${distFilesRoot}</runAjscHome>
+
+               <!-- For SOA Cloud Installation -->
+               <installOwnerUser>aaiadmin</installOwnerUser>
+               <installOwnerGroup>aaiadmin</installOwnerGroup>
+               <ownerManagementGroup>com.att.csid.lab</ownerManagementGroup>
+
+               <!-- Port Selection. A value of 0 will allow for dynamic port selection. 
+                       For local testing, you may choose to hardcode this value to something like 
+                       8080 -->
+               <serverPort>9515</serverPort>
+               <sslport>9516</sslport>
+
+               <testRouteOffer>workstation</testRouteOffer>
+               <testEnv>DEV</testEnv>
+               <checkstyle.config.location>google_checks.xml</checkstyle.config.location>
+               <nexusproxy>https://nexus.onap.org</nexusproxy>
+
+               <!-- Dependency Versions -->
+               <aai.artifact.generator.version>1.1.0</aai.artifact.generator.version>
+               <apache.lang3.version>3.6</apache.lang3.version> 
+               <commons-compress.version>1.14</commons-compress.version>
+               <common.logging.version>1.1.0</common.logging.version>
+               <dom4j.version>1.6.1</dom4j.version>
+               <fasterxml.version>2.8.1</fasterxml.version>
+               <hamcrest.version>1.3</hamcrest.version>
+               <javaassist.version>3.21.0-GA</javaassist.version>
+               <logback.version>1.1.9</logback.version>
+               <mockito.version>1.10.19</mockito.version>
+               <powermock.version>1.6.2</powermock.version>
+               <sdc.distribution.client.version>1.1.32-SNAPSHOT</sdc.distribution.client.version>
+               <snakeyamle.version>1.18</snakeyamle.version>
+               <jacoco.version>0.7.9</jacoco.version>
+       </properties>
+
+       <dependencies>
+               <dependency>
+                       <groupId>javax.ws.rs</groupId>
+                       <artifactId>javax.ws.rs-api</artifactId>
+                       <version>2.0.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>dom4j</groupId>
+                       <artifactId>dom4j</artifactId>
+                       <version>${dom4j.version}</version>
+                       <scope>provided</scope>
+               </dependency>
+
+               <!-- Common logging framework -->
+               <dependency>
+                       <groupId>org.onap.aai.logging-service</groupId>
+                       <artifactId>common-logging</artifactId>
+                       <version>${common.logging.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.hamcrest</groupId>
+                       <artifactId>hamcrest-library</artifactId>
+                       <version>1.3</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.google.code.gson</groupId>
+                       <artifactId>gson</artifactId>
+                       <version>2.8.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>ch.qos.logback</groupId>
+                       <artifactId>logback-core</artifactId>
+                       <version>${logback.version}</version>
+               </dependency>
+
+               <!-- apache commons -->
+               <dependency>
+                       <groupId>org.apache.commons</groupId>
+                       <artifactId>commons-compress</artifactId>
+                       <version>${commons-compress.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>commons-io</groupId>
+                       <artifactId>commons-io</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.commons</groupId>
+                       <artifactId>commons-lang3</artifactId>
+                       <version>${apache.lang3.version}</version>
+               </dependency>
+
+               <!-- Artifact generation -->
+               <dependency>
+                       <groupId>org.openecomp.sdc.common</groupId>
+                       <artifactId>openecomp-sdc-artifact-generator-core</artifactId>
+                       <version>${aai.artifact.generator.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.fasterxml.jackson.core</groupId>
+                       <artifactId>jackson-core</artifactId>
+                       <version>${fasterxml.version}</version>
+               </dependency>
+
+               <!-- Testing -->
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-core</artifactId>
+                       <version>${mockito.version}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-junit4</artifactId>
+                       <version>${powermock.version}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-api-mockito</artifactId>
+                       <version>${powermock.version}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-javaagent</artifactId>
+                       <version>${powermock.version}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-junit4-rule-agent</artifactId>
+                       <version>${powermock.version}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.javassist</groupId>
+                       <artifactId>javassist</artifactId>
+                       <version>${javaassist.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.sdc.sdc-distribution-client</groupId>
+                       <artifactId>sdc-distribution-client</artifactId>
+                       <version>${sdc.distribution.client.version}</version>
+               </dependency>
+          <dependency>
+              <groupId>xmlunit</groupId>
+              <artifactId>xmlunit</artifactId>
+              <version>1.6</version>
+              <scope>test</scope>
+          </dependency>
+       </dependencies>
+
+       <build>
+               <plugins>
+
+                       <plugin>
+                               <groupId>org.codehaus.mojo</groupId>
+                               <artifactId>cobertura-maven-plugin</artifactId>
+                               <version>2.7</version>
+                               <executions>
+                                       <execution>
+                                               <phase />
+                                       </execution>
+                               </executions>
+                       </plugin>
+
+                       <plugin>
+                               <groupId>org.jacoco</groupId>
+                               <artifactId>jacoco-maven-plugin</artifactId>
+                               <version>${jacoco.version}</version>
+
+                               <executions>
+                                       <execution>
+                                               <id>prepare-agent</id>
+                                               <goals>
+                                                       <goal>prepare-agent</goal>
+                                               </goals>
+                                       </execution>
+
+                                       <execution>
+                                               <id>report</id>
+                                               <phase>package</phase>
+                                               <goals>
+                                                       <goal>report</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+
+                       </plugin>
+
+                       <plugin>
+                               <groupId>org.codehaus.groovy</groupId>
+                               <artifactId>groovy-eclipse-compiler</artifactId>
+                               <version>2.9.2-01</version>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>3.0.2</version>
+                               <executions>
+                                       <execution>
+                                               <id>copy-docker-file</id>
+                                               <phase>package</phase>
+                                               <goals>
+                                                       <goal>copy-resources</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <outputDirectory>target</outputDirectory>
+                                                       <overwrite>true</overwrite>
+                                                       <resources>
+                                                               <resource>
+                                                                       <directory>${basedir}/src/main/docker</directory>
+                                                                       <filtering>true</filtering>
+                                                                       <includes>
+                                                                               <include>**/*</include>
+                                                                       </includes>
+                                                               </resource>
+                                                               <resource>
+                                                                       <directory>${basedir}/src/main/bin/</directory>
+                                                               </resource>
+                                                       </resources>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-jar-plugin</artifactId>
+                               <version>3.0.2</version>
+                               <executions>
+                                       <execution>
+                                               <phase>package</phase>
+                                               <goals>
+                                                       <goal>jar</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <classifier>client</classifier>
+                                                       <includes>
+                                                               <include>**/babel/service/data/*</include>
+                                                       </includes>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+
+                       <!-- license plugin -->
+                       <plugin>
+                               <groupId>com.mycila</groupId>
+                               <artifactId>license-maven-plugin</artifactId>
+                               <version>3.0</version>
+                               <configuration>
+                                       <header>License.txt</header>
+                                       <includes>
+                                               <include>src/main/java/**</include>
+                                               <include>src/test/java/**</include>
+                                       </includes>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       <goal>format</goal>
+                                               </goals>
+                                               <phase>process-sources</phase>
+                                       </execution>
+                               </executions>
+                       </plugin>
+
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-deploy-plugin</artifactId>
+                               <configuration>
+                                       <classifier>client</classifier>
+                               </configuration>
+                       </plugin>
+
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-site-plugin</artifactId>
+                               <version>3.3</version>
+                               <configuration>
+                                       <reportPlugins>
+                                               <plugin>
+                                                       <groupId>org.apache.maven.plugins</groupId>
+                                                       <artifactId>maven-checkstyle-plugin</artifactId>
+                                                       <version>2.17</version>
+                                                       <reportSets>
+                                                               <reportSet>
+                                                                       <reports>
+                                                                               <report>checkstyle</report>
+                                                                       </reports>
+                                                               </reportSet>
+                                                       </reportSets>
+                                               </plugin>
+                                       </reportPlugins>
+                               </configuration>
+                       </plugin>
+                       <!-- Strong recommendation to use forkCount and reuseForks parameters as forkMode is deprecated since v2.14 -->
+                       <plugin>
+                           <groupId>org.apache.maven.plugins</groupId>
+                           <artifactId>maven-surefire-plugin</artifactId>
+                           <configuration>
+                               <reuseForks>false</reuseForks>
+                               <forkCount>1</forkCount>
+                           </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+
+       <!-- Added to fix build warnings caused by parent pom and bom -->
+
+       <profiles>
+               <profile>
+                       <id>runAjsc</id>
+                       <build>
+                               <defaultGoal>initialize</defaultGoal>
+                               <plugins>
+                                       <plugin>
+                                               <groupId>org.codehaus.mojo</groupId>
+                                               <artifactId>exec-maven-plugin</artifactId>
+                                               <version>1.3.2</version>
+                                               <executions>
+                                                       <execution>
+                                                               <phase>initialize</phase>
+                                                               <goals>
+                                                                       <goal>java</goal>
+                                                               </goals>
+                                                               <configuration>
+                                                                       <includeProjectDependencies>false</includeProjectDependencies>
+                                                                       <includePluginDependencies>true</includePluginDependencies>
+                                                                       <executable>java</executable>
+                                                                       <mainClass>com.att.ajsc.runner.Runner</mainClass>
+                                                                       <executableDependency>
+                                                                               <groupId>com.att.ajsc</groupId>
+                                                                               <artifactId>ajsc-runner</artifactId>
+                                                                       </executableDependency>
+                                                                       <additionalClasspathElements>
+                                                                               <additionalClasspathElement>${basedir}/ajsc-shared-config/etc</additionalClasspathElement>
+                                                                       </additionalClasspathElements>
+
+                                                                       <environmentVariables>
+                                                                               <AJSC_HOME>${runAjscHome}</AJSC_HOME>
+                                                                       </environmentVariables>
+
+                                                                       <!-- Main AJSC System Properties below (necessary for proper startup) -->
+                                                                       <systemProperties>
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_HOME</key>
+                                                                                       <value>${runAjscHome}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_HOME</key>
+                                                                                       <value>${runAjscHome}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_CONF_HOME</key>
+                                                                                       <value>${basedir}/bundleconfig-local</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>logback.configurationFile</key>
+                                                                                       <value>${basedir}/ajsc-shared-config/etc/logback.xml</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_SHARED_CONFIG</key>
+                                                                                       <value>${basedir}/ajsc-shared-config</value>
+                                                                               </systemProperty>
+                                                                               <sysproperty>
+                                                                                       <key>AJSC_EXTERNAL_LIB_FOLDERS</key>
+                                                                                       <value>${basedir}/target/commonLibs</value>
+                                                                               </sysproperty>
+                                                                               <sysproperty>
+                                                                                       <key>AJSC_EXTERNAL_PROPERTIES_FOLDERS</key>
+                                                                                       <value>${basedir}/ajsc-shared-config/etc</value>
+                                                                               </sysproperty>
+
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_SERVICE_NAMESPACE</key>
+                                                                                       <value>${module.ajsc.namespace.name}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_SERVICE_VERSION</key>
+                                                                                       <value>${module.ajsc.namespace.version}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>SOACLOUD_SERVICE_VERSION</key>
+                                                                                       <value>${project.version}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>server.port</key>
+                                                                                       <value>${serverPort}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>CONFIG_HOME</key>
+                                                                                       <value>${basedir}/appconfig-local</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>artifactgenerator.config</key>
+                                                                                       <value>${basedir}/appconfig-local/artifact-generator.properties</value>
+                                                                               </systemProperty>
+                                                                       </systemProperties>
+
+                                                                       <!-- Command Line Arguments to add to the java command. Here, you 
+                                                                               can specify the port as well as the Context you want your service to run 
+                                                                               in. Use context=/ to run in an unnamed Context (Root Context). The default 
+                                                                               configuration of the AJSC is to run under the / Context. Setting the port 
+                                                                               here can aid during the development phase of your service. However, you can 
+                                                                               leave this argument out entirely, and the AJSC will default to using an Ephemeral 
+                                                                               port. -->
+                                                                       <arguments>
+                                                                               <argument>context=/</argument>
+                                                                               <argument>port=${serverPort}</argument>
+                                                                               <argument>sslport=${sslport}</argument>
+                                                                       </arguments>
+                                                               </configuration>
+                                                       </execution>
+                                               </executions>
+                                               <configuration>
+                                                       <executable>java</executable>
+                                               </configuration>
+                                               <dependencies>
+                                                       <dependency>
+                                                               <groupId>com.att.ajsc</groupId>
+                                                               <artifactId>ajsc-runner</artifactId>
+                                                               <version>${ajscRuntimeVersion}</version>
+                                                       </dependency>
+                                               </dependencies>
+                                       </plugin>
+                               </plugins>
+                       </build>
+               </profile>
+       </profiles>
+
+</project>
diff --git a/src/main/ajsc/babel_v1/babel/v1/conf/babel-beans.xml b/src/main/ajsc/babel_v1/babel/v1/conf/babel-beans.xml
new file mode 100644 (file)
index 0000000..f4cc32c
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="
+               http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
+
+       <!-- ////////////////////////////////////////////////////////////////// -->
+       <!-- PROPERTY AND CONFIGURATION FILES -->
+       <!-- ////////////////////////////////////////////////////////////////// -->
+
+       <context:property-placeholder location="file:${CONFIG_HOME}/babel-auth.properties" ignore-unresolvable="true" />
+
+       <!-- ////////////////////////////////////////////////////////////////// -->
+       <!-- CONFIG BEANS -->
+       <!-- ////////////////////////////////////////////////////////////////// -->
+
+       <bean id="babelAuthConfig" class="org.onap.aai.babel.config.BabelAuthConfig">
+               <property name="authenticationDisable" value="${auth.authentication.disable}" />
+               <property name="authPolicyFile" value="${auth.policy.file}" />
+       </bean>
+
+       <!-- ////////////////////////////////////////////////////////////////// -->
+       <!-- IMPLEMENTATION BEANS -->
+       <!-- ////////////////////////////////////////////////////////////////// -->
+
+       <bean id="aaiMicroServiceAuth" class="org.onap.aai.auth.AAIMicroServiceAuth" >
+               <constructor-arg ref="babelAuthConfig" />
+       </bean>
+
+
+       <bean id="generateArtifacts" class="org.onap.aai.babel.service.GenerateArtifactsServiceImpl" >
+               <constructor-arg ref="aaiMicroServiceAuth" />   
+       </bean>
+
+</beans>
diff --git a/src/main/ajsc/babel_v1/babel/v1/docs/README.txt b/src/main/ajsc/babel_v1/babel/v1/docs/README.txt
new file mode 100644 (file)
index 0000000..3707179
--- /dev/null
@@ -0,0 +1 @@
+Place any docs here that you want to access within the ajsc upon deployment of your service.
diff --git a/src/main/ajsc/babel_v1/babel/v1/lib/README.txt b/src/main/ajsc/babel_v1/babel/v1/lib/README.txt
new file mode 100644 (file)
index 0000000..639e21b
--- /dev/null
@@ -0,0 +1 @@
+3rd party JAR's needed by your jars (if any) for a ajsc deployment package go here...
\ No newline at end of file
diff --git a/src/main/ajsc/babel_v1/babel/v1/props/module.props b/src/main/ajsc/babel_v1/babel/v1/props/module.props
new file mode 100644 (file)
index 0000000..17ebc08
--- /dev/null
@@ -0,0 +1 @@
+EXAMPLE.PROPERTY=EXAMLE_VALUE
\ No newline at end of file
diff --git a/src/main/ajsc/babel_v1/babel/v1/routes/babel-service.route b/src/main/ajsc/babel_v1/babel/v1/routes/babel-service.route
new file mode 100644 (file)
index 0000000..c12bc67
--- /dev/null
@@ -0,0 +1,4 @@
+<route xmlns="http://camel.apache.org/schema/spring" trace="true">
+  <from uri="att-dme2-servlet:///__module_ajsc_namespace_name__/__module_ajsc_namespace_version__/app?matchOnUriPrefix=true" />        
+  <to uri="cxfbean:generateArtifacts" />
+</route>
diff --git a/src/main/assemble/ajsc_module_assembly.xml b/src/main/assemble/ajsc_module_assembly.xml
new file mode 100644 (file)
index 0000000..359f792
--- /dev/null
@@ -0,0 +1,69 @@
+<!-- 
+ Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+-->
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+       <id>${version}</id>
+       <includeBaseDirectory>false</includeBaseDirectory>
+       <formats>
+               <format>zip</format>
+       </formats>
+       <fileSets>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/routes/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/routes/</outputDirectory>
+                       <includes>
+                               <include>*.route</include>
+                       </includes>
+
+               </fileSet>
+
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/docs/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/docs/</outputDirectory>
+                       <includes>
+                               <include>*.*</include>
+                               <!-- <include>*.vm</include>  -->
+                       </includes>
+
+               </fileSet>
+
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/lib/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/lib/</outputDirectory>
+                       <includes>
+                               <include>*.jar</include>
+                       </includes>
+
+               </fileSet>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/extJars/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/extJars/</outputDirectory>
+                       <includes>
+                               <include>*.jar</include>
+                       </includes>
+               </fileSet>
+               
+               <!-- also try to grab outputs from the "jar" plugin's package phase -->
+               <fileSet>
+                       <directory>${project.basedir}/target/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/lib/</outputDirectory>
+                       <includes>
+                               <include>*.jar</include>
+                       </includes>
+               </fileSet>
+
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/conf/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/conf/</outputDirectory>
+                       <includes>
+                               <include>*.*</include>
+                       </includes>
+
+               </fileSet>
+       </fileSets>
+
+</assembly>
+
diff --git a/src/main/assemble/ajsc_props_assembly.xml b/src/main/assemble/ajsc_props_assembly.xml
new file mode 100644 (file)
index 0000000..6ee4093
--- /dev/null
@@ -0,0 +1,26 @@
+<!-- 
+ Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+-->
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+       <id>${version}_properties</id>
+       <includeBaseDirectory>false</includeBaseDirectory>
+       <formats>
+               <format>zip</format>
+       </formats>
+       <fileSets>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/props</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/props/</outputDirectory>
+                       <includes>
+                               <include>*.props</include>
+                       </includes>
+
+               </fileSet>
+
+       </fileSets>
+
+</assembly>
+
diff --git a/src/main/assemble/ajsc_runtime_assembly.xml b/src/main/assemble/ajsc_runtime_assembly.xml
new file mode 100644 (file)
index 0000000..c86d265
--- /dev/null
@@ -0,0 +1,47 @@
+<!-- 
+ Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+-->
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+       <id>runtimeEnvironment</id>
+       <includeBaseDirectory>false</includeBaseDirectory>
+       <formats>
+               <format>zip</format>
+       </formats>
+       <fileSets>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/context/</directory>
+                       <outputDirectory>runtime/context/</outputDirectory>
+                       <includes>
+                               <include>*.context</include>
+                       </includes>
+               </fileSet>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/serviceProperties/</directory>
+                       <outputDirectory>runtime/serviceProperties/</outputDirectory>
+                       <includes>
+                               <include>*.props</include>
+                       </includes>
+               </fileSet><fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/shiroRole</directory>
+                       <outputDirectory>runtime/shiroRole/</outputDirectory>
+                       <includes>
+                               <include>*.json</include>
+                       </includes>
+               </fileSet><fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/shiroUser</directory>
+                       <outputDirectory>runtime/shiroUser/</outputDirectory>
+                       <includes>
+                               <include>*.json</include>
+                       </includes>
+               </fileSet><fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/shiroUserRole</directory>
+                       <outputDirectory>runtime/shiroUserRole</outputDirectory>
+                       <includes>
+                               <include>*.json</include>
+                       </includes>
+               </fileSet>
+       </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/src/main/bin/start.sh b/src/main/bin/start.sh
new file mode 100644 (file)
index 0000000..1854884
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# ============LICENSE_START=======================================================
+# org.onap.aai
+# ================================================================================
+# Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+# Copyright Â© 2017 European Software Marketing Ltd.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+
+BASEDIR="/opt/app/babel/"
+AJSC_HOME="$BASEDIR"
+
+if [ -z "$CONFIG_HOME" ]; then
+       echo "CONFIG_HOME must be set in order to start up process"
+       exit 1
+fi
+
+CLASSPATH="$AJSC_HOME/lib/*"
+CLASSPATH="$CLASSPATH:$AJSC_HOME/extJars/"
+CLASSPATH="$CLASSPATH:$AJSC_HOME/etc/"
+PROPS="-DAJSC_HOME=$AJSC_HOME"
+PROPS="$PROPS -DAJSC_CONF_HOME=$BASEDIR/bundleconfig/"
+PROPS="$PROPS -Dlogback.configurationFile=$BASEDIR/bundleconfig/etc/logback.xml"
+PROPS="$PROPS -DAJSC_SHARED_CONFIG=$AJSC_CONF_HOME"
+PROPS="$PROPS -DAJSC_SERVICE_NAMESPACE=babel"
+PROPS="$PROPS -DAJSC_SERVICE_VERSION=v1"
+PROPS="$PROPS -Dserver.port=9516"
+PROPS="$PROPS -DCONFIG_HOME=$CONFIG_HOME"
+PROPS="$PROPS -Dartifactgenerator.config=$CONFIG_HOME/artifact-generator.properties"
+PROPS="$PROPS -DKEY_STORE_PASSWORD=$KEY_STORE_PASSWORD"
+PROPS="$PROPS -DKEY_MANAGER_PASSWORD=$KEY_MANAGER_PASSWORD"
+JVM_MAX_HEAP=${MAX_HEAP:-1024}
+
+echo $CLASSPATH
+
+exec java -Xmx${JVM_MAX_HEAP}m $PROPS -classpath $CLASSPATH com.att.ajsc.runner.Runner context=// sslport=9516
diff --git a/src/main/config/ajsc-chef.jks b/src/main/config/ajsc-chef.jks
new file mode 100644 (file)
index 0000000..aeca770
Binary files /dev/null and b/src/main/config/ajsc-chef.jks differ
diff --git a/src/main/config/ajsc-jetty.xml b/src/main/config/ajsc-jetty.xml
new file mode 100644 (file)
index 0000000..68306d4
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version="1.0"  encoding="UTF-8"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+<!-- 
+ Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+-->
+<Configure id="ajsc-server" class="org.eclipse.jetty.server.Server">
+       <!-- DO NOT REMOVE!!!! This is setting up the AJSC Context -->
+       <New id="ajscContext" class="org.eclipse.jetty.webapp.WebAppContext">
+               <Set name="contextPath"><SystemProperty name="AJSC_CONTEXT_PATH" /></Set>
+               <Set name="extractWAR">true</Set>
+               <Set name="tempDirectory"><SystemProperty name="AJSC_TEMP_DIR" /></Set>
+               <Set name="war"><SystemProperty name="AJSC_WAR_PATH" /></Set>
+               <Set name="descriptor"><SystemProperty name="AJSC_HOME" />/etc/runner-web.xml</Set>
+               <Set name="overrideDescriptor"><SystemProperty name="AJSC_HOME" />/etc/ajsc-override-web.xml</Set>
+               <Set name="throwUnavailableOnStartupException">true</Set>
+               <Set name="servletHandler">
+                       <New class="org.eclipse.jetty.servlet.ServletHandler">
+                               <Set name="startWithUnavailable">false</Set>
+                       </New>
+               </Set>
+       </New>
+       
+       <Set name="handler">
+               <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
+                       <Set name="Handlers">
+                               <Array type="org.eclipse.jetty.webapp.WebAppContext">
+                                       <Item>
+                                               <Ref refid="ajscContext" />
+                                       </Item>
+                               </Array>
+                       </Set>
+               </New>
+       </Set>
+       
+       <Call name="addBean">
+               <Arg>
+                       <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
+                               <Set name="contexts">
+                                       <Ref refid="Contexts" />
+                               </Set>
+                               <Call id="extAppHotDeployProvider" name="addAppProvider">
+                                       <Arg>
+                                               <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
+                                                       <Set name="monitoredDirName"><SystemProperty name="AJSC_HOME" />/extApps</Set>
+                                                       <Set name="scanInterval">10</Set>
+                                                       <Set name="extractWars">true</Set>
+                                               </New>
+                                       </Arg>
+                               </Call>
+                       </New>
+               </Arg>
+       </Call>
+       
+<!--   <Call name="addConnector"> -->
+<!--           <Arg> -->
+<!--                   <New class="org.eclipse.jetty.server.ServerConnector"> -->
+<!--                           <Arg name="server"> -->
+<!--                                   <Ref refid="ajsc-server" /> -->
+<!--                           </Arg> -->
+<!--                           <Set name="port"><SystemProperty name="AJSC_HTTP_PORT" default="8080" /></Set> -->
+<!--                   </New> -->
+<!--           </Arg> -->
+<!--   </Call> -->
+       
+<!-- The following commented out code is for ssl connection setup. Default setup is for the AJSC to run as http server and 
+allow other components (such as CSI Gateway) to handle the https calls to end user. Please, verify with your team and/or
+CSI/CSTEM whether or not you would need to add an ssl connector.  -->
+       <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
+               <Set name="keyStorePath"><SystemProperty name="CONFIG_HOME" />/auth/tomcat_keystore</Set>
+               <Set name="keyStorePassword">
+                       <Call class="org.eclipse.jetty.util.security.Password" name="deobfuscate">
+                               <Arg><SystemProperty name="KEY_STORE_PASSWORD" /></Arg>
+                       </Call>
+               </Set>
+               <Set name="keyManagerPassword">
+                       <Call class="org.eclipse.jetty.util.security.Password" name="deobfuscate">
+                               <Arg><SystemProperty name="KEY_MANAGER_PASSWORD" /></Arg>
+                       </Call>
+               </Set>
+               <Set name="needClientAuth">true</Set>
+               <Set name="wantClientAuth">true</Set>
+       </New>
+
+       <Call id="sslConnector" name="addConnector">
+               <Arg>
+                       <New class="org.eclipse.jetty.server.ServerConnector">
+                               <Arg name="server">
+                                       <Ref refid="ajsc-server" />
+                               </Arg>
+                               <Arg name="factories">
+                                       <Array type="org.eclipse.jetty.server.ConnectionFactory">
+                                               <Item>
+                                                       <New class="org.eclipse.jetty.server.SslConnectionFactory">
+                                                               <Arg name="next">http/1.1</Arg>
+                                                               <Arg name="sslContextFactory">
+                                                                       <Ref refid="sslContextFactory" />
+                                                               </Arg>
+                                                       </New>
+                                               </Item>
+                                               <Item>
+                                                       <New class="org.eclipse.jetty.server.HttpConnectionFactory">
+                                                               <Arg name="config">
+                                                                       <New class="org.eclipse.jetty.server.HttpConfiguration">
+                                                                               <Call name="addCustomizer">
+                                                                                       <Arg>
+                                                                                               <New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
+                                                                                       </Arg>
+                                                                               </Call>
+                                                                       </New>
+                                                               </Arg>
+                                                       </New>
+                                               </Item>
+                                       </Array>
+                               </Arg>
+                               <Set name="port"><SystemProperty name="AJSC_HTTPS_PORT" default="0" /></Set>
+                               <Set name="idleTimeout">30000</Set>
+                       </New>
+               </Arg>
+       </Call>
+
+<!--   <Get name="ThreadPool">
+               <Set name="minThreads"><SystemProperty name="AJSC_JETTY_ThreadCount_MIN" /></Set>
+               <Set name="maxThreads"><SystemProperty name="AJSC_JETTY_ThreadCount_MAX" /></Set>
+               <Set name="idleTimeout"><SystemProperty name="AJSC_JETTY_IDLETIME_MAX" /></Set>
+               <Set name="detailedDump">false</Set>
+       </Get>-->
+       
+</Configure>
\ No newline at end of file
diff --git a/src/main/config/ajsc-override-web.xml b/src/main/config/ajsc-override-web.xml
new file mode 100644 (file)
index 0000000..84a7920
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+ Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+       metadata-complete="false" version="3.0">
+
+       <filter-mapping>
+               <filter-name>InterceptorFilter</filter-name>
+               <url-pattern>/services/*</url-pattern>
+       </filter-mapping> 
+       <filter-mapping>
+               <filter-name>InterceptorFilter</filter-name>
+               <url-pattern>/rest/*</url-pattern>
+       </filter-mapping>  
+
+       <filter-mapping>
+               <filter-name>springSecurityFilterChain</filter-name>
+               <url-pattern>/*</url-pattern>
+       </filter-mapping>
+               
+       <servlet-mapping>
+               <servlet-name>ManagementServlet</servlet-name>
+               <url-pattern>/mgmt</url-pattern>
+       </servlet-mapping>
+        
+        <servlet-mapping>
+                       <servlet-name>RestletServlet</servlet-name>
+                       <url-pattern>/rest/*</url-pattern>
+       </servlet-mapping>
+
+       <servlet-mapping>
+               <servlet-name>CamelServlet</servlet-name>
+               <url-pattern>/services/*</url-pattern>
+       </servlet-mapping>
+
+       <servlet-mapping>
+               <servlet-name>jsp</servlet-name>
+               <url-pattern>*.jsp</url-pattern>
+               <url-pattern>*.jspf</url-pattern>
+               <url-pattern>*.jspx</url-pattern>
+               <url-pattern>*.xsp</url-pattern>
+               <url-pattern>*.JSP</url-pattern>
+               <url-pattern>*.JSPF</url-pattern>
+               <url-pattern>*.JSPX</url-pattern>
+               <url-pattern>*.XSP</url-pattern>
+       </servlet-mapping>
+       <servlet-mapping>
+               <servlet-name>default</servlet-name>
+               <url-pattern>/*</url-pattern>
+       </servlet-mapping>
+</web-app>
\ No newline at end of file
diff --git a/src/main/config/ajscJetty.jks b/src/main/config/ajscJetty.jks
new file mode 100644 (file)
index 0000000..48cdbff
Binary files /dev/null and b/src/main/config/ajscJetty.jks differ
diff --git a/src/main/config/cadi.properties b/src/main/config/cadi.properties
new file mode 100644 (file)
index 0000000..d250fec
--- /dev/null
@@ -0,0 +1,36 @@
+#This properties file is used for defining AAF properties related to the CADI framework. This file is used for running AAF framework
+
+#In order to test functionality of cadi-ajsc-plugin locally cross domain cookie. Cadi "should" find your hostname for you. 
+#However, we have seen some situations where this fails. A Local testing
+#modification can include modifying your hosts file so that you can use "mywebserver.att.com" for your localhost in order
+#to test/verify GLO functionality locally. If you are on a Windows machine, you will already have a machine name associated with 
+#it that will utilize an AT&T domain such as "sbc.com". You may need to add your  domain to this as a comma separated list depending
+#upon your particular machine domain. This property is commented out as cadi SHOULD find your machine name. With version 1.2.1 of cadi, 
+#it appears to resolve Mac machine names as well, now. But, this can be somewhat inconsistent depending on your specific working envrironment.
+hostname=mywebserver.att.com
+
+#Setting csp_domain to PROD will allow for testing using your attuid and password through GLO.
+csp_domain=PROD
+csp_devl_localhost=true
+
+basic_realm=csp.att.com
+#basic_realm=aaf.att.com
+basic_warn=TRUE
+
+cadi_loglevel=WARN
+cadi_keyfile=target/swm/package/nix/dist_files/appl/babel/etc/keyfile
+
+# Configure AAF
+#These are dummy values add appropriate values required
+aaf_url=url
+
+#AJSC - MECHID
+#These are dummy values add appropriate values required
+aaf_id=dummyid@ajsc.att.com
+aaf_password=enc:277edqJCjT0RlUI3BtbDQa-3Ha-CQGd
+aaf_timeout=5000
+aaf_clean_interval=30000
+aaf_user_expires=5000
+aaf_high_count=1000
+
+
diff --git a/src/main/config/jul-redirect.properties b/src/main/config/jul-redirect.properties
new file mode 100644 (file)
index 0000000..8b6624d
--- /dev/null
@@ -0,0 +1,13 @@
+
+#      Bridge JUL->slf4j Logging Configuration File
+#
+# This file bridges the JUL logging infrastructure into
+# SLF4J so JUL logs go to logback implementation provided
+# in this project.  SLF4J also captures log4j and has 
+# other framework options as well providing a common
+# logging infrastructure for capturing all logs from different
+# libraries using different frameworks in one place.
+
+#      Global properties
+handlers=org.slf4j.bridge.SLF4JBridgeHandler
+.level= ALL
diff --git a/src/main/config/keyfile b/src/main/config/keyfile
new file mode 100644 (file)
index 0000000..882e86a
--- /dev/null
@@ -0,0 +1,27 @@
+ZuIwp0TkyVPDeX1Up-8JtkMWvjsCpoiu1_VKeWrtrvxunvAke8_tiFyHPPyb2nkhepFYj6tXzpfS
+rGz5XF_TH9NbsKaP8u0HV5clz2WriYQRvHS85vjY7hXxkpFuLb7zkLAPqTyIDpj7FiW61NzsRUAq
+TM8jH16jr7mBNnb56w24mNGOwznMPcIZKcjgZU1ekaPDFpWyhQElU7Y0q_94P_Gkk45r66Hj22sU
+OiOaaftmudZlswLw8-8Zaakqf2yW9HjMVfuYCwSodBHCW5rdB3Ctb5W36rnD_AQco3Ky2PgPmqvk
+QkJYuUHpbuDqVHqLOajlKSIGMTIqAIBg51fRaaONtD-Q5xzY8E5wO1YWTLKcP5tsNvUpzM8Wu3NS
+ynpGpUcvlTqWWsGzTbzOyamyKkdNdx97sSqjM25Zh1-ps48h6cddGYWpab7SUvqRCS11QBUyLTry
+2iwTEHMhHRIbo7PO99ALQfuq9gI1zKGfurJdvLBeBaFs5SCF0AiCZ3WcDO8Rv3HpxVZ2_ShbDxb0
+eMoO6SotXu51fj8Y3-WqsfZziQyEsHyqpg5uQ6yUtz01h5YHLEoVuotF1U4agmQR6kEkYk-wNOiZ
+v-8gaA9gtbLoAdKhuKFxQgQLNMf6GzVzZNujbmDzLoZAP_mXAv29aBPaf64Ugzv-Oa5GZdBgD-Xd
+_pahML-ionw99r0TnkpShYmDqMKhMdjaP3m87WIAZkIB-L-VTyKcEsJ4340VSzCOsv3waiM0S89u
+4cMcG5y-PLY8IoipIlLUPTWD3SjcQ9DV1Dt3T5KjdWLsj48D3W4K4e9PB8yxs0gtUjgVUR2_xEir
+G5eDO9Ac1eHFWGDFFP0SgG-TbHJUKlvy9mwLzmU0fC3xPjhqmIr-v0HxF7HN-tmb1LHDorno8tSN
+u7kUGcKSchIiFfvkd066crUb2mH7PnXTaWmAjyVj9VsBExFUYEdpHMAV4sAP9-RxZGDRt46UhrDK
+QZvvNhBVyOEjHPHWI4vl1r1v8HNH1_2jZu5DVJWyHWR56aCo1lhFH9_X6UAHUHbnXViDONZOVXlT
+9-WD0tk2zJGuwrhdZDAnPnAmjfwbwbpnr5Hmex1i1JiD7WVyP1kbfoej2TmdiYbxr9oBYaGQ29JI
+aHod7MQCLtvL1z5XgnDPLZ4y3_9SbqHKYbNa8UgZkTLF5EacGThYVFDLA9cbafHDtR1kMGE3vv4D
+EJ-0pAYTOGmKlVI7DwNyKsY9JTyudrxTqhOxi9jgcJNWiUaNe9yhL8Pyc2YBqUTTYhh_a2d1rvkZ
+0Gh1crviVxqBrIkRKaMRXZ4f1vDLz-3NvG_vwPOo8WRFo5nGmSdTw7CjBaigJ_cYCfDhoP11pEnw
+cndsZNcHs-v05LlxeIIMDD_f5Bvz-il_DLA4eK2HqgLdxh8ziSDl2azk14MJY4amzz6reEXUuKLV
+RsZGf_jbDGKhE2HuDQ5ovoLOi4OqE1oRuqh-dGxitrYouP2SN1l_1tCEMRth86FMV-6AQtZsvdUo
+y9MtQ7e35atjA8nHtgADlDTmJBKQiUHUsOZ77p1qp17HAFMovUkc739opfEYnKUn6Itpw5Ipm_Is
+ra6chJUfMpOFof5rb5OjqFAN27c_-mPo1lQU3ndYlKGh_n5V8ufX6v2Yri8WzOPf6hjVYotkmoMP
+NPAICDCB8W5ddBjsopzLVVEtaXDu9Qj6-zf77hT4iQ7rBd2Ner8iLqN3Kis0dvkNM3_uH8onau1G
+Y_YYw7PPSZyd2S_7Dd6G-IG4ayO6e5DD6oUwwekyiQI_3rTXNa_wldGxqW9u818010ekE4Qdlfcj
+beIn7fAeaOjReZ87hRgWyMs-EgTVHw8RL3yI_O6VvRTVRONRF1Y4C_-IYa8z-bfrwXx3BBd9TTgb
+EnS9wVOyC2OgUN6BhPLGLhxzkJ05nEjizXEc9t5EPYoSRwesajGGrrG_0-qWbuU5hKLPLkyeJLHb
+5HXOTVsrUR59Vov2M3_EswkxcImblox3k3VS2yihZMGyfqLzZIUXgd8ufkevKKU6DxwacGTb
\ No newline at end of file
diff --git a/src/main/config/runner-web.xml b/src/main/config/runner-web.xml
new file mode 100644 (file)
index 0000000..b51aff4
--- /dev/null
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+ Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+       metadata-complete="false" version="3.0">
+
+       <context-param>
+               <param-name>contextConfigLocation</param-name>
+               <param-value>/WEB-INF/spring-servlet.xml,
+                                       classpath:applicationContext.xml
+               </param-value>
+       </context-param>
+       
+       <context-param>
+        <param-name>spring.profiles.default</param-name>
+        <param-value>nooauth</param-value>
+    </context-param>
+    
+       <listener>
+               <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+       </listener>
+       
+       <servlet>
+               <servlet-name>ManagementServlet</servlet-name>
+               <servlet-class>ajsc.ManagementServlet</servlet-class>
+       </servlet>
+
+    
+       <filter> 
+               <filter-name>InterceptorFilter</filter-name>
+               <filter-class>ajsc.filters.InterceptorFilter</filter-class>
+               <init-param>
+                <param-name>preProcessor_interceptor_config_file</param-name>
+                <param-value>/etc/PreProcessorInterceptors.properties</param-value>
+        </init-param>
+        <init-param>
+                <param-name>postProcessor_interceptor_config_file</param-name>
+                <param-value>/etc/PostProcessorInterceptors.properties</param-value>
+        </init-param>
+        
+       </filter>
+
+        <servlet>
+               <servlet-name>RestletServlet</servlet-name>
+               <servlet-class>ajsc.restlet.RestletSpringServlet</servlet-class>
+               <init-param>
+                               <param-name>org.restlet.component</param-name>
+                               <param-value>restletComponent</param-value>
+               </init-param>
+       </servlet>
+       
+       <servlet>
+               <servlet-name>CamelServlet</servlet-name>
+               <servlet-class>ajsc.servlet.AjscCamelServlet</servlet-class>
+       </servlet>
+
+
+       <filter>
+               <filter-name>springSecurityFilterChain</filter-name>
+               <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+       </filter>
+
+       <servlet>
+               <servlet-name>spring</servlet-name>
+               <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+               <load-on-startup>1</load-on-startup>
+       </servlet>      
+       
+<!--   <servlet-mapping>
+               <servlet-name>spring</servlet-name>
+               <url-pattern>/</url-pattern>
+       </servlet-mapping>-->
+
+<!-- BEGIN jsp -->
+
+  <servlet id="jsp">
+    <servlet-name>jsp</servlet-name>
+    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
+  </servlet>
+
+       
+       
+
+         
+       <!-- BEGIN static content -->
+       <servlet>
+          <servlet-name>default</servlet-name>
+           <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
+           <init-param>
+               <param-name>dirAllowed</param-name>
+               <param-value>true</param-value>
+           </init-param>
+       </servlet>
+       <!-- END static content -->     
+</web-app>
diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile
new file mode 100644 (file)
index 0000000..6fac6e2
--- /dev/null
@@ -0,0 +1,24 @@
+FROM ubuntu:14.04
+
+ARG MICRO_HOME=/opt/app/babel
+ARG BIN_HOME=$MICRO_HOME/bin
+
+RUN apt-get update
+
+# Install and setup java8
+RUN apt-get update && apt-get install -y software-properties-common
+## sudo -E is required to preserve the environment. If you remove that line, it will most like freeze at this step
+RUN sudo -E add-apt-repository ppa:openjdk-r/ppa && apt-get update && apt-get install -y openjdk-8-jdk
+## Setup JAVA_HOME, this is useful for docker commandline
+ENV JAVA_HOME usr/lib/jvm/java-8-openjdk-amd64
+RUN export JAVA_HOME
+
+# Build up the deployment folder structure
+RUN mkdir -p $MICRO_HOME
+ADD swm/package/nix/dist_files/appl/babel/* $MICRO_HOME/
+RUN mkdir -p $BIN_HOME
+COPY *.sh $BIN_HOME
+RUN chmod 755 $BIN_HOME/*
+RUN ln -s /logs $MICRO_HOME/logs
+
+CMD ["/opt/app/babel/bin/start.sh"]
diff --git a/src/main/java/org/onap/aai/auth/AAIAuthException.java b/src/main/java/org/onap/aai/auth/AAIAuthException.java
new file mode 100644 (file)
index 0000000..13593ab
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.auth;
+
+public class AAIAuthException extends Exception {
+       /**
+        * 
+        */
+       private static final long serialVersionUID = 1L;
+
+       public AAIAuthException(String string) {
+               super(string);
+       }
+       
+       public AAIAuthException(String string, Exception e) {
+               super(string, e);
+       }
+
+}
diff --git a/src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java
new file mode 100644 (file)
index 0000000..f678498
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.auth;
+
+import java.security.cert.X509Certificate;
+import javax.inject.Inject;
+import javax.security.auth.x500.X500Principal;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.HttpHeaders;
+import org.onap.aai.babel.config.BabelAuthConfig;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+
+
+/**
+ * Public class for authentication and authorization operations. Authorization is applied according to user and role
+ */
+public class AAIMicroServiceAuth {
+
+    private static Logger applicationLogger = LoggerFactory.getInstance().getLogger(AAIMicroServiceAuth.class);
+
+    private BabelAuthConfig babelAuthConfig;
+
+    /**
+     * @param babelAuthConfig
+     * @throws AAIAuthException
+     */
+    @Inject
+    public AAIMicroServiceAuth(final BabelAuthConfig babelAuthConfig) throws AAIAuthException {
+        this.babelAuthConfig = babelAuthConfig;
+        if (!babelAuthConfig.isAuthenticationDisable()) {
+            AAIMicroServiceAuthCore.init(babelAuthConfig.getAuthPolicyFile());
+        }
+    }
+
+    /**
+     * @param username
+     * @param policyFunction
+     * @return
+     * @throws AAIAuthException
+     */
+    public boolean authorize(String username, String policyFunction) throws AAIAuthException {
+        return AAIMicroServiceAuthCore.authorize(username, policyFunction);
+    }
+
+    /**
+     * @param authUser
+     * @param policyFunction
+     * @return
+     * @throws AAIAuthException
+     */
+    public String authenticate(String authUser, String policyFunction) throws AAIAuthException {
+        if (authorize(authUser, policyFunction)) {
+            return "OK";
+        } else {
+            return "AAI_9101";
+        }
+    }
+
+    /**
+     * @param headers
+     * @param req
+     * @param action
+     * @param apiPath
+     * @return
+     * @throws AAIAuthException
+     */
+    public boolean validateRequest(HttpHeaders headers /* NOSONAR */, HttpServletRequest req,
+            AAIMicroServiceAuthCore.HTTP_METHODS action, String apiPath) throws AAIAuthException {
+
+        applicationLogger.debug("validateRequest: " + apiPath);
+        applicationLogger
+                .debug("babelAuthConfig.isAuthenticationDisable(): " + babelAuthConfig.isAuthenticationDisable());
+
+        if (babelAuthConfig.isAuthenticationDisable()) {
+            return true;
+        }
+
+        String[] ps = apiPath.split("/");
+        String authPolicyFunctionName = ps[0];
+        if (ps.length > 1 && authPolicyFunctionName.matches("v\\d+")) {
+            authPolicyFunctionName = ps[1];
+        }
+
+        String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");
+        String authUser = null;
+
+        if (cipherSuite != null) {
+            X509Certificate[] certChain = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
+            X509Certificate clientCert = certChain[0];
+            X500Principal subjectDN = clientCert.getSubjectX500Principal();
+            authUser = subjectDN.toString();
+        }
+
+        if (authUser != null) {
+            return "OK".equals(authenticate(authUser.toLowerCase(), action.toString() + ":" + authPolicyFunctionName));
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java
new file mode 100644 (file)
index 0000000..b148440
--- /dev/null
@@ -0,0 +1,287 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.auth;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.TimeUnit;
+import org.onap.aai.babel.logging.ApplicationMsgs;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+
+/**
+ * Authentication and authorization by user and role.
+ *
+ */
+public class AAIMicroServiceAuthCore {
+
+    private static Logger applicationLogger = LoggerFactory.getInstance().getLogger(AAIMicroServiceAuthCore.class);
+
+    public static final String FILESEP =
+            (System.getProperty("file.separator") == null) ? "/" : System.getProperty("file.separator");
+    public static final String APPCONFIG_DIR = (System.getProperty("CONFIG_HOME") == null)
+            ? System.getProperty("AJSC_HOME") + FILESEP + "appconfig" : System.getProperty("CONFIG_HOME");
+
+    private static String appConfigAuthDir = APPCONFIG_DIR + FILESEP + "auth";
+    private static String defaultAuthFileName = appConfigAuthDir + FILESEP + "auth_policy.json";
+
+    private static boolean usersInitialized = false;
+    private static HashMap<String, AAIAuthUser> users;
+    private static boolean timerSet = false;
+    private static Timer timer = null;
+    private static String policyAuthFileName;
+
+    public enum HTTP_METHODS {
+        GET,
+        PUT,
+        DELETE,
+        HEAD,
+        POST
+    }
+
+    // Don't instantiate
+    private AAIMicroServiceAuthCore() {}
+
+    public static String getDefaultAuthFileName() {
+        return defaultAuthFileName;
+    }
+
+    public static void setDefaultAuthFileName(String defaultAuthFileName) {
+        AAIMicroServiceAuthCore.defaultAuthFileName = defaultAuthFileName;
+    }
+
+    public static synchronized void init(String authPolicyFile) throws AAIAuthException {
+
+        try {
+            policyAuthFileName = AAIMicroServiceAuthCore.getConfigFile(authPolicyFile);
+        } catch (IOException e) {
+            applicationLogger.debug("Exception while retrieving policy file.");
+            applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e);
+            throw new AAIAuthException(e.getMessage());
+        }
+        if (policyAuthFileName == null) {
+            throw new AAIAuthException("Auth policy file could not be found");
+        }
+        AAIMicroServiceAuthCore.reloadUsers();
+
+        TimerTask task = new FileWatcher(new File(policyAuthFileName)) {
+            @Override
+            protected void onChange(File file) {
+                // here we implement the onChange
+                applicationLogger.debug("File " + file.getName() + " has been changed!");
+                try {
+                    AAIMicroServiceAuthCore.reloadUsers();
+                } catch (AAIAuthException e) {
+                    applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e);
+                }
+                applicationLogger.debug("File " + file.getName() + " has been reloaded!");
+            }
+        };
+
+        if (!timerSet) {
+            timerSet = true;
+            timer = new Timer();
+            long period = TimeUnit.SECONDS.toMillis(1);
+            timer.schedule(task, new Date(), period);
+            applicationLogger.debug("Config Watcher Interval = " + period);
+        }
+    }
+
+    public static void cleanup() {
+        timer.cancel();
+    }
+
+    public static String getConfigFile(String authPolicyFile) throws IOException {
+        File authFile = new File(authPolicyFile);
+        if (authFile.exists()) {
+            return authFile.getCanonicalPath();
+        }
+        authFile = new File(appConfigAuthDir + FILESEP + authPolicyFile);
+        if (authFile.exists()) {
+            return authFile.getCanonicalPath();
+        }
+        if (defaultAuthFileName != null) {
+            authFile = new File(defaultAuthFileName);
+            if (authFile.exists()) {
+                return defaultAuthFileName;
+            }
+        }
+        return null;
+    }
+
+    public static synchronized void reloadUsers() throws AAIAuthException {
+        users = new HashMap<>();
+
+        ObjectMapper mapper = new ObjectMapper();
+        try {
+            applicationLogger.debug("Reading from " + policyAuthFileName);
+            JsonNode rootNode = mapper.readTree(new File(policyAuthFileName));
+            for (JsonNode roleNode : rootNode.path("roles")) {
+                String roleName = roleNode.path("name").asText();
+                AAIAuthRole r = new AAIAuthRole();
+                installFunctionOnRole(roleNode.path("functions"), roleName, r);
+                assignRoleToUsers(roleNode.path("users"), roleName, r);
+            }
+        } catch (FileNotFoundException e) {
+            throw new AAIAuthException("Auth policy file could not be found", e);
+        } catch (JsonProcessingException e) {
+            throw new AAIAuthException("Error processing Auth policy file ", e);
+        } catch (IOException e) {
+            throw new AAIAuthException("Error reading Auth policy file", e);
+        }
+
+        usersInitialized = true;
+    }
+
+    private static void installFunctionOnRole(JsonNode functionsNode, String roleName, AAIAuthRole r) {
+        for (JsonNode functionNode : functionsNode) {
+            String function = functionNode.path("name").asText();
+            JsonNode methodsNode = functionNode.path("methods");
+            boolean hasMethods = false;
+            for (JsonNode method_node : methodsNode) {
+                String methodName = method_node.path("name").asText();
+                hasMethods = true;
+                String func = methodName + ":" + function;
+                applicationLogger.debug("Installing function " + func + " on role " + roleName);
+                r.addAllowedFunction(func);
+            }
+
+            if (!hasMethods) {
+                for (HTTP_METHODS meth : HTTP_METHODS.values()) {
+                    String func = meth.toString() + ":" + function;
+                    applicationLogger.debug("Installing (all methods) " + func + " on role " + roleName);
+                    r.addAllowedFunction(func);
+                }
+            }
+        }
+    }
+
+    private static void assignRoleToUsers(JsonNode usersNode, String roleName, AAIAuthRole r) {
+        for (JsonNode userNode : usersNode) {
+            String name = userNode.path("username").asText().toLowerCase();
+            AAIAuthUser user;
+            if (users.containsKey(name)) {
+                user = users.get(name);
+            } else {
+                user = new AAIAuthUser();
+            }
+            applicationLogger.debug("Assigning " + roleName + " to user " + name);
+            user.setUser(name);
+            user.addRole(roleName, r);
+            users.put(name, user);
+        }
+    }
+
+    public static class AAIAuthUser {
+        private String username;
+        private HashMap<String, AAIAuthRole> roles;
+
+        public AAIAuthUser() {
+            this.roles = new HashMap<>();
+        }
+
+        public String getUser() {
+            return this.username;
+        }
+
+        public Map<String, AAIAuthRole> getRoles() {
+            return this.roles;
+        }
+
+        public void addRole(String roleName, AAIAuthRole r) {
+            this.roles.put(roleName, r);
+        }
+
+        public boolean checkAllowed(String checkFunc) {
+            for (Entry<String, AAIAuthRole> role_entry : roles.entrySet()) {
+                AAIAuthRole role = role_entry.getValue();
+                if (role.hasAllowedFunction(checkFunc)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public void setUser(String myuser) {
+            this.username = myuser;
+        }
+
+    }
+
+    public static class AAIAuthRole {
+
+        private List<String> allowedFunctions;
+
+        public AAIAuthRole() {
+            this.allowedFunctions = new ArrayList<>();
+        }
+
+        public void addAllowedFunction(String func) {
+            this.allowedFunctions.add(func);
+        }
+
+        public void delAllowedFunction(String delFunc) {
+            if (this.allowedFunctions.contains(delFunc)) {
+                this.allowedFunctions.remove(delFunc);
+            }
+        }
+
+        public boolean hasAllowedFunction(String afunc) {
+            return this.allowedFunctions.contains(afunc) ? true : false;
+        }
+    }
+
+    public static boolean authorize(String username, String authFunction) throws AAIAuthException {
+        if (!usersInitialized || users == null) {
+            throw new AAIAuthException("Auth module not initialized");
+        }
+        if (users.containsKey(username)) {
+            if (users.get(username).checkAllowed(authFunction)) {
+                logAuthenticationResult(username, authFunction, "AUTH ACCEPTED");
+                return true;
+            } else {
+                logAuthenticationResult(username, authFunction, "AUTH FAILED");
+                return false;
+            }
+        } else {
+            logAuthenticationResult(username, authFunction, "User not found");
+            return false;
+        }
+    }
+
+    private static void logAuthenticationResult(String username, String authFunction, String result) {
+        applicationLogger.debug(result + ": " + username + " on function " + authFunction);
+    }
+}
diff --git a/src/main/java/org/onap/aai/auth/FileWatcher.java b/src/main/java/org/onap/aai/auth/FileWatcher.java
new file mode 100644 (file)
index 0000000..e3b9923
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.auth;
+
+import java.io.File;
+import java.util.TimerTask;
+
+public abstract class FileWatcher extends TimerTask {
+    private long timeStamp;
+    private File file;
+
+    /**
+     * Instantiates a new file watcher.
+     *
+     * @param file the file
+     */
+    public FileWatcher(File file) {
+        this.file = file;
+        this.timeStamp = file.lastModified();
+    }
+
+    /**
+     * runs a timer task
+     * 
+     * @see java.util.TimerTask.run
+     */
+    @Override
+    public final void run() {
+        long newTimeStamp = file.lastModified();
+
+        if ((newTimeStamp - this.timeStamp) > 500) {
+            this.timeStamp = newTimeStamp;
+            onChange(file);
+        }
+    }
+
+    /**
+     * On change.
+     *
+     * @param file the file
+     */
+    protected abstract void onChange(File file);
+}
diff --git a/src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java b/src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java
new file mode 100644 (file)
index 0000000..5fdc01f
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.config;
+
+import org.springframework.beans.factory.annotation.Value;
+
+public class BabelAuthConfig {
+
+       @Value("${auth.authentication.disable}")
+       private boolean authenticationDisable;
+
+       @Value("${auth.policy.file}")
+       private String authPolicyFile;
+
+       public boolean isAuthenticationDisable() {
+               return authenticationDisable;
+       }
+
+       public void setAuthenticationDisable(boolean authenticationDisable) {
+               this.authenticationDisable = authenticationDisable;
+       }
+
+       public String getAuthPolicyFile() {
+               return authPolicyFile;
+       }
+
+       public void setAuthPolicyFile(String authPolicyFile) {
+               this.authPolicyFile = authPolicyFile;
+       }
+
+}
diff --git a/src/main/java/org/onap/aai/babel/csar/CsarConverterException.java b/src/main/java/org/onap/aai/babel/csar/CsarConverterException.java
new file mode 100644 (file)
index 0000000..b9316fc
--- /dev/null
@@ -0,0 +1,40 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.csar;
+
+/**
+ * This class represents an exception encountered when attempting to convert the yml files in a csar archive into xml.
+ */
+public class CsarConverterException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor for an instance of this exception with just a message.
+     *
+     * @param message information about the exception
+     */
+    public CsarConverterException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java b/src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java
new file mode 100644 (file)
index 0000000..55cf652
--- /dev/null
@@ -0,0 +1,88 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.csar;
+
+import java.util.List;
+import java.util.Objects;
+import org.onap.aai.babel.csar.extractor.InvalidArchiveException;
+import org.onap.aai.babel.csar.extractor.YamlExtractor;
+import org.onap.aai.babel.logging.ApplicationMsgs;
+import org.onap.aai.babel.service.data.BabelArtifact;
+import org.onap.aai.babel.xml.generator.XmlArtifactGenerationException;
+import org.onap.aai.babel.xml.generator.ArtifactGenerator;
+import org.onap.aai.babel.xml.generator.ModelGenerator;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+
+import org.openecomp.sdc.generator.data.Artifact;
+
+/**
+ * This class is responsible for converting content in a csar archive into one or more xml artifacts.
+ */
+public class CsarToXmlConverter {
+    private static Logger logger = LoggerFactory.getInstance().getLogger(CsarToXmlConverter.class);
+
+    /**
+     * This method is responsible for extracting one or more yaml files from the given csarArtifact and then using them
+     * to generate xml artifacts.
+     *
+     * @param csarArchive the artifact that contains the csar archive to generate xml artifacts from
+     * @param name the name of the archive file
+     * @param version the version of the archive file
+     * @return List<org.openecomp.sdc.generator.data.Artifact> a list of generated xml artifacts
+     * @throws CsarConverterException if there is an error either extracting the yaml files or generating xml artifacts
+     */
+    public List<BabelArtifact> generateXmlFromCsar(byte[] csarArchive, String name, String version)
+            throws CsarConverterException {
+        validateArguments(csarArchive, name, version);
+
+        logger.info(ApplicationMsgs.DISTRIBUTION_EVENT,
+                "Starting to process csarArchive to convert contents to xml artifacts");
+        List<BabelArtifact> xmlArtifacts;
+
+        try {
+            logger.debug("Calling YamlExtractor to extract ymlFiles");
+            List<Artifact> ymlFiles = YamlExtractor.extract(csarArchive, name, version);
+
+            logger.debug("Calling XmlArtifactGenerator to generateXmlArtifacts");
+            ArtifactGenerator modelGenerator = new ModelGenerator();
+            xmlArtifacts = modelGenerator.generateArtifacts(ymlFiles);
+
+            logger.debug(xmlArtifacts.size() + " xml artifacts have been generated");
+        } catch (InvalidArchiveException e) {
+            throw new CsarConverterException(
+                    "An error occurred trying to extract the yml files from the csar file : " + e);
+        } catch (XmlArtifactGenerationException e) {
+            throw new CsarConverterException(
+                    "An error occurred trying to generate xml files from a collection of yml files : " + e);
+        }
+
+        return xmlArtifacts;
+    }
+
+    private void validateArguments(byte[] csarArchive, String name, String version) {
+        Objects.requireNonNull(csarArchive);
+        Objects.requireNonNull(name);
+        Objects.requireNonNull(version);
+    }
+}
diff --git a/src/main/java/org/onap/aai/babel/csar/extractor/InvalidArchiveException.java b/src/main/java/org/onap/aai/babel/csar/extractor/InvalidArchiveException.java
new file mode 100644 (file)
index 0000000..aac893b
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.csar.extractor;
+
+/**
+ * This class represents an exception encountered when processing an archive in memory.
+ */
+public class InvalidArchiveException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor for an instance of this exception with just a message.
+     *
+     * @param message information about the exception
+     */
+    InvalidArchiveException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor for an instance of this exception with a message and actual exception encountered.
+     *
+     * @param message information about the exception
+     * @param cause the actual exception that was encountered
+     */
+    InvalidArchiveException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/src/main/java/org/onap/aai/babel/csar/extractor/YamlExtractor.java b/src/main/java/org/onap/aai/babel/csar/extractor/YamlExtractor.java
new file mode 100644 (file)
index 0000000..fb51933
--- /dev/null
@@ -0,0 +1,149 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.csar.extractor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipFile;
+import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.aai.babel.logging.ApplicationMsgs;
+import org.onap.aai.babel.xml.generator.ModelGenerator;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+import org.openecomp.sdc.generator.data.Artifact;
+import org.yaml.snakeyaml.Yaml;
+
+/**
+ * The purpose of this class is to process a .csar file in the form of a byte array and extract yaml files from it.
+ *
+ * A .csar file is a compressed archive like a zip file and this class will treat the byte array as it if were a zip
+ * file.
+ */
+public class YamlExtractor {
+    private static Logger logger = LoggerFactory.getInstance().getLogger(YamlExtractor.class);
+
+    private static final String TYPE = "type";
+    private static final Pattern YAMLFILE_EXTENSION_REGEX = Pattern.compile("(?i).*\\.ya?ml$");
+    private static final Set<String> INVALID_TYPES = new HashSet<>();
+
+    static {
+        Collections.addAll(INVALID_TYPES, "CP", "VL", "VFC", "VFCMT", "ABSTRACT");
+    }
+
+    /**
+     * Private constructor
+     */
+    private YamlExtractor() {
+        throw new IllegalAccessError("Utility class");
+    }
+
+    /**
+     * This method is responsible for filtering the contents of the supplied archive and returning a collection of
+     * {@link Artifact}s that represent the yml files that have been found in the archive.<br>
+     * <br>
+     * If the archive contains no yml files it will return an empty list.<br>
+     *
+     * @param archive the zip file in the form of a byte array containing one or more yml files
+     * @param name the name of the archive file
+     * @param version the version of the archive file
+     * @return List<Artifact> collection of yml files found in the archive
+     * @throws InvalidArchiveException if an error occurs trying to extract the yml files from the archive, if the
+     *         archive is not a zip file or there are no yml files
+     */
+    public static List<Artifact> extract(byte[] archive, String name, String version) throws InvalidArchiveException {
+        validateRequest(archive, name, version);
+
+        logger.info(ApplicationMsgs.DISTRIBUTION_EVENT, "Extracting CSAR archive: " + name);
+
+        List<Artifact> ymlFiles = new ArrayList<>();
+        try (SeekableInMemoryByteChannel inMemoryByteChannel = new SeekableInMemoryByteChannel(archive);
+                ZipFile zipFile = new ZipFile(inMemoryByteChannel)) {
+            for (Enumeration<ZipArchiveEntry> enumeration = zipFile.getEntries(); enumeration.hasMoreElements();) {
+                ZipArchiveEntry entry = enumeration.nextElement();
+                if (fileShouldBeExtracted(zipFile, entry)) {
+                    ymlFiles.add(ModelGenerator.createArtifact(IOUtils.toByteArray(zipFile.getInputStream(entry)),
+                            entry.getName(), version));
+                }
+            }
+            if (ymlFiles.isEmpty()) {
+                throw new InvalidArchiveException("No valid yml files were found in the csar file.");
+            }
+        } catch (IOException e) {
+            throw new InvalidArchiveException(
+                    "An error occurred trying to create a ZipFile. Is the content being converted really a csar file?",
+                    e);
+        }
+
+        logger.debug(ApplicationMsgs.DISTRIBUTION_EVENT, ymlFiles.size() + " YAML files extracted.");
+
+        return ymlFiles;
+    }
+
+    private static void validateRequest(byte[] archive, String name, String version) throws InvalidArchiveException {
+        if (archive == null || archive.length == 0) {
+            throw new InvalidArchiveException("An archive must be supplied for processing.");
+        } else if (StringUtils.isBlank(name)) {
+            throw new InvalidArchiveException("The name of the archive must be supplied for processing.");
+        } else if (StringUtils.isBlank(version)) {
+            throw new InvalidArchiveException("The version must be supplied for processing.");
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static boolean fileShouldBeExtracted(ZipFile zipFile, ZipArchiveEntry entry) throws IOException {
+        logger.debug(ApplicationMsgs.DISTRIBUTION_EVENT, "Checking if " + entry.getName() + " should be extracted...");
+
+        boolean extractFile = false;
+        if (YAMLFILE_EXTENSION_REGEX.matcher(entry.getName()).matches()) {
+            try {
+                Yaml yamlParser = new Yaml();
+                HashMap<String, Object> yaml =
+                        (LinkedHashMap<String, Object>) yamlParser.load(zipFile.getInputStream(entry));
+                HashMap<String, Object> metadata = (LinkedHashMap<String, Object>) yaml.get("metadata");
+
+                extractFile = metadata != null && metadata.containsKey(TYPE)
+                        && !INVALID_TYPES.contains(metadata.get(TYPE).toString().toUpperCase())
+                        && !metadata.get(TYPE).toString().isEmpty();
+            } catch (Exception e) {
+                logger.error(ApplicationMsgs.DISTRIBUTION_EVENT,
+                        "Unable to verify " + entry.getName() + " contains a valid resource type: " + e.getMessage());
+            }
+        }
+
+        logger.debug(ApplicationMsgs.DISTRIBUTION_EVENT, "Keeping file: " + entry.getName() + "? : " + extractFile);
+
+        return extractFile;
+    }
+}
+
diff --git a/src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java b/src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java
new file mode 100644 (file)
index 0000000..9b9f9d5
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.logging;
+
+import com.att.eelf.i18n.EELFResourceManager;
+import org.onap.aai.cl.eelf.LogMessageEnum;
+
+public enum ApplicationMsgs implements LogMessageEnum {
+    //@formatter:off
+    /**
+     * Arguments: {0} = message.
+     */
+    DISTRIBUTION_EVENT,
+
+       PROCESS_REQUEST_ERROR,
+
+    INVALID_CSAR_FILE,
+    
+    INVALID_REQUEST_JSON;
+
+    //@formatter:on
+
+    /**
+     * Static initializer to ensure the resource bundles for this class are loaded... Here this application loads
+     * messages from three bundles
+     */
+    static {
+        EELFResourceManager.loadMessageBundle("babel-logging-resources");
+    }
+}
diff --git a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java
new file mode 100644 (file)
index 0000000..bb7b721
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.service;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import org.onap.aai.auth.AAIAuthException;
+
+/**
+ * Generate artifacts from the specified request content
+ */
+@Path("/")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public interface GenerateArtifactsService {
+
+    @POST
+    @Path("/generateArtifacts")
+    Response generateArtifacts(@Context UriInfo uriInfo, @Context HttpHeaders headers,
+            @Context HttpServletRequest servletRequest, String request) throws AAIAuthException;
+
+
+}
diff --git a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java
new file mode 100644 (file)
index 0000000..bdb45b5
--- /dev/null
@@ -0,0 +1,148 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.service;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+import java.util.Base64;
+import java.util.List;
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
+import org.onap.aai.auth.AAIAuthException;
+import org.onap.aai.auth.AAIMicroServiceAuth;
+import org.onap.aai.auth.AAIMicroServiceAuthCore;
+import org.onap.aai.babel.csar.CsarConverterException;
+import org.onap.aai.babel.csar.CsarToXmlConverter;
+import org.onap.aai.babel.logging.ApplicationMsgs;
+import org.onap.aai.babel.service.data.BabelArtifact;
+import org.onap.aai.babel.service.data.BabelRequest;
+import org.onap.aai.babel.util.RequestValidationException;
+import org.onap.aai.babel.util.RequestValidator;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+
+
+/**
+ * Generate SDC Artifacts by passing in a CSAR payload, Artifact Name and Artifact version
+ */
+public class GenerateArtifactsServiceImpl implements GenerateArtifactsService {
+    private static Logger applicationLogger = LoggerFactory.getInstance().getLogger(GenerateArtifactsServiceImpl.class);
+
+    private AAIMicroServiceAuth aaiMicroServiceAuth;
+
+    /**
+     * @param authorization
+     */
+    @Inject
+    public GenerateArtifactsServiceImpl(final AAIMicroServiceAuth authorization) {
+        this.aaiMicroServiceAuth = authorization;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.onap.aai.babel.service.GenerateArtifactsService#generateArtifacts(javax.ws.rs.core.UriInfo,
+     * javax.ws.rs.core.HttpHeaders, javax.servlet.http.HttpServletRequest, java.lang.String)
+     */
+    @Override
+    public Response generateArtifacts(UriInfo uriInfo, HttpHeaders headers, HttpServletRequest servletRequest,
+            String requestBody) throws AAIAuthException {
+        applicationLogger.debug("Received request: " + requestBody);
+
+        Response response;
+        try {
+            boolean authorized = aaiMicroServiceAuth.validateRequest(headers, servletRequest,
+                    AAIMicroServiceAuthCore.HTTP_METHODS.POST, uriInfo.getPath(false));
+
+            response = authorized ? generateArtifacts(requestBody)
+                    : buildResponse(Status.UNAUTHORIZED, "User not authorized to perform the operation.");
+        } catch (AAIAuthException e) {
+            applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e);
+            throw e;
+        }
+
+        applicationLogger.debug("Sending response: " + response.getStatus() + " " + response.getEntity().toString());
+        return response;
+    }
+
+
+    /**
+     * Generate XML model artifacts from request body.
+     * 
+     * @param requestBody the request body in JSON format
+     * @return response object containing the generated XML models
+     */
+    protected Response generateArtifacts(String requestBody) {
+        Response response;
+
+        try {
+            Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+
+            BabelRequest babelRequest = gson.fromJson(requestBody, BabelRequest.class);
+            RequestValidator.validateRequest(babelRequest);
+            byte[] csarFile = Base64.getDecoder().decode(babelRequest.getCsar());
+            List<BabelArtifact> xmlArtifacts = new CsarToXmlConverter().generateXmlFromCsar(csarFile,
+                    babelRequest.getArtifactName(), babelRequest.getArtifactVersion());
+            response = buildResponse(Status.OK, gson.toJson(xmlArtifacts));
+
+        } catch (JsonSyntaxException e) {
+            applicationLogger.error(ApplicationMsgs.INVALID_REQUEST_JSON, e);
+            response = buildResponse(Status.BAD_REQUEST, "Malformed request.");
+        } catch (CsarConverterException e) {
+            applicationLogger.error(ApplicationMsgs.INVALID_CSAR_FILE, e);
+            response = buildResponse(Status.INTERNAL_SERVER_ERROR, "Error converting CSAR artifact to XML model.");
+        } catch (RequestValidationException e) {
+            applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e);
+            response = buildResponse(Status.BAD_REQUEST, e.getLocalizedMessage());
+        } catch (Exception e) {
+            applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e);
+            response = buildResponse(Status.INTERNAL_SERVER_ERROR,
+                    "Error while processing request. Please check the babel service logs for more details.\n");
+        }
+
+        return response;
+    }
+
+    /**
+     * Helper method to create a REST response object.
+     * 
+     * @param status response status code
+     * @param entity response payload
+     * @return
+     */
+    private Response buildResponse(Status status, String entity) {
+        //@formatter:off
+        return Response
+                .status(status)
+                .entity(entity)
+                .type(MediaType.TEXT_PLAIN)
+                .build();
+        //@formatter:on
+    }
+}
diff --git a/src/main/java/org/onap/aai/babel/service/data/BabelArtifact.java b/src/main/java/org/onap/aai/babel/service/data/BabelArtifact.java
new file mode 100644 (file)
index 0000000..986aed9
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.service.data;
+
+/**
+ * Bean representing the return artifacts of the Babel microservice.
+ */
+public class BabelArtifact {
+    String name;
+    String type;
+    byte[] payload;
+
+    public BabelArtifact(String name, String type, byte[] payload) {
+        super();
+        this.name = name;
+        this.type = type;
+        this.payload = payload;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public byte[] getPayload() {
+        return payload;
+    }
+
+    public void setPayload(byte[] payload) {
+        this.payload = payload;
+    }
+}
diff --git a/src/main/java/org/onap/aai/babel/service/data/BabelRequest.java b/src/main/java/org/onap/aai/babel/service/data/BabelRequest.java
new file mode 100644 (file)
index 0000000..20a101f
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.service.data;
+
+public class BabelRequest {
+    private String csar;
+       private String artifactVersion;
+    private String artifactName;
+
+    public String getCsar() {
+        return csar;
+    }
+
+    public void setCsar(String csar) {
+        this.csar = csar;
+    }
+    
+    public String getArtifactVersion() {
+               return artifactVersion;
+       }
+
+       public void setArtifactVersion(String artifactVersion) {
+               this.artifactVersion = artifactVersion;
+       }
+
+       public String getArtifactName() {
+               return artifactName;
+       }
+
+       public void setArtifactName(String artifactName) {
+               this.artifactName = artifactName;
+       }
+}
diff --git a/src/main/java/org/onap/aai/babel/util/RequestValidationException.java b/src/main/java/org/onap/aai/babel/util/RequestValidationException.java
new file mode 100644 (file)
index 0000000..5e3be5e
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.util;
+
+/**
+ * This exception is thrown when the request fails validation.
+ */
+public class RequestValidationException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor for an instance of this exception with just a message.
+     *
+     * @param message information about the exception
+     */
+    public RequestValidationException(String message) {
+        super(message);
+    }
+}
+
+
diff --git a/src/main/java/org/onap/aai/babel/util/RequestValidator.java b/src/main/java/org/onap/aai/babel/util/RequestValidator.java
new file mode 100644 (file)
index 0000000..ecc9d2b
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.util;
+
+import org.onap.aai.babel.service.data.BabelRequest;
+
+public class RequestValidator {
+
+    private RequestValidator() {}
+
+
+    /**
+     * Validates that the request body contains the required attributes
+     * 
+     * @param request the request body to validate
+     */
+    public static void validateRequest(BabelRequest request) throws RequestValidationException {
+        if (request.getCsar() == null) {
+            throw new RequestValidationException("No csar attribute found in the request body.");
+        }
+
+        if (request.getArtifactVersion() == null) {
+            throw new RequestValidationException("No artifact version attribute found in the request body.");
+        }
+
+        if (request.getArtifactName() == null) {
+            throw new RequestValidationException("No artifact name attribute found in the request body.");
+        }
+    }
+}
diff --git a/src/main/java/org/onap/aai/babel/xml/generator/ArtifactGenerator.java b/src/main/java/org/onap/aai/babel/xml/generator/ArtifactGenerator.java
new file mode 100644 (file)
index 0000000..4fd51aa
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.xml.generator;
+
+import java.util.List;
+import org.onap.aai.babel.service.data.BabelArtifact;
+import org.openecomp.sdc.generator.data.Artifact;
+
+public interface ArtifactGenerator {
+
+    /**
+     * Generate a {@link List} of {@link BabelArtifact}s from the Artifacts obtained from the CSAR
+     * 
+     * @param csarArtifacts artifacts obtained from the CSAR file
+     * @return generated {@link BabelArtifact}s
+     */
+    List<BabelArtifact> generateArtifacts(List<Artifact> csarArtifacts) throws XmlArtifactGenerationException;
+    
+}
diff --git a/src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java b/src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java
new file mode 100644 (file)
index 0000000..c6def3d
--- /dev/null
@@ -0,0 +1,136 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.xml.generator;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import org.onap.aai.babel.logging.ApplicationMsgs;
+import org.onap.aai.babel.service.data.BabelArtifact;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+import org.openecomp.sdc.generator.data.AdditionalParams;
+import org.openecomp.sdc.generator.data.Artifact;
+import org.openecomp.sdc.generator.data.GenerationData;
+import org.openecomp.sdc.generator.data.GeneratorUtil;
+import org.openecomp.sdc.generator.data.GroupType;
+import org.openecomp.sdc.generator.service.ArtifactGenerationService;
+
+/**
+ * This class is responsible for generating xml model artifacts from a collection of csar file artifacts
+ */
+public class ModelGenerator implements ArtifactGenerator {
+
+    private static Logger logger = LoggerFactory.getInstance().getLogger(ModelGenerator.class);
+
+    private static final String GENERATORCONFIG = "{\"artifactTypes\": [\"AAI\"]}";
+    private static final Pattern UUID_NORMATIVE_NEW_VERSION = Pattern.compile("^\\d{1,}.0");
+    private static final String VERSION_DELIMITER = ".";
+    private static final String VERSION_DELIMITER_REGEXP = "\\" + VERSION_DELIMITER;
+    private static final String DEFAULT_SERVICE_VERSION = "1.0";
+
+    /**
+     * Invokes the TOSCA artifact generator API with the input artifacts.
+     *
+     * @param csarArtifacts the input artifacts
+     * @return {@link List} of output artifacts
+     * @throws XmlArtifactGenerationException if there is an error trying to generate xml artifacts
+     */
+    @Override
+    public List<BabelArtifact> generateArtifacts(List<Artifact> csarArtifacts) throws XmlArtifactGenerationException {
+        logger.info(ApplicationMsgs.DISTRIBUTION_EVENT,
+                "Generating XML for " + csarArtifacts.size() + " CSAR artifacts.");
+
+        // Get the service version to pass into the generator
+        String toscaVersion = csarArtifacts.get(0).getVersion();
+        logger.debug(
+                "Getting the service version for Tosca Version of the yml file.  The Tosca Version is " + toscaVersion);
+        String serviceVersion = getServiceVersion(toscaVersion);
+        logger.debug("The service version is " + serviceVersion);
+        Map<String, String> additionalParams = new HashMap<>();
+        additionalParams.put(AdditionalParams.ServiceVersion.getName(), serviceVersion);
+
+        // Call ArtifactGenerator API
+        logger.debug("Obtaining instance of ArtifactGenerationService");
+        ArtifactGenerationService generationService = ArtifactGenerationService.lookup();
+        logger.debug("About to call generationService.generateArtifact()");
+        GenerationData data = generationService.generateArtifact(csarArtifacts, GENERATORCONFIG, additionalParams);
+        logger.debug("Call generationService.generateArtifact() has finished");
+
+        // Convert results into BabelArtifacts
+        if (data.getErrorData().isEmpty()) {
+            return data.getResultData().stream().map(a -> new BabelArtifact(a.getName(), a.getType(), a.getPayload()))
+                    .collect(Collectors.toList());
+        } else {
+            throw new XmlArtifactGenerationException(
+                    "Error occurred during artifact generation: " + data.getErrorData().toString());
+        }
+    }
+
+    /**
+     * Creates an instance of an input artifact for the generator.
+     *
+     * @param payload the payload downloaded from SDC
+     * @param artifactName name of the artifact to create
+     * @param artifactVersion version of the artifact to create
+     * @return an {@link Artifact} object constructed from the payload and artifactInfo
+     */
+    public static Artifact createArtifact(byte[] payload, String artifactName, String artifactVersion) {
+        logger.info(ApplicationMsgs.DISTRIBUTION_EVENT, "Creating artifact for: " + artifactName);
+
+        // Convert payload into an input Artifact
+        String checksum = GeneratorUtil.checkSum(payload);
+        byte[] encodedPayload = GeneratorUtil.encode(payload);
+        Artifact artifact = new Artifact("TOSCA", GroupType.DEPLOYMENT.name(), checksum, encodedPayload);
+        artifact.setName(artifactName);
+        artifact.setLabel(artifactName);
+        artifact.setDescription(artifactName);
+        artifact.setVersion(artifactVersion);
+        return artifact;
+    }
+
+    private static String getServiceVersion(String artifactVersion) {
+        String serviceVersion;
+
+        try {
+            if (UUID_NORMATIVE_NEW_VERSION.matcher(artifactVersion).matches()) {
+                serviceVersion = artifactVersion;
+            } else {
+                String[] versionParts = artifactVersion.split(VERSION_DELIMITER_REGEXP);
+                Integer majorVersion = Integer.parseInt(versionParts[0]);
+
+                serviceVersion = (majorVersion + 1) + VERSION_DELIMITER + "0";
+            }
+        } catch (Exception e) {
+            logger.warn(ApplicationMsgs.DISTRIBUTION_EVENT,
+                    "Error generating service version from artifact version: " + artifactVersion
+                            + ". Using default service version of: " + DEFAULT_SERVICE_VERSION + ". Error details: "
+                            + e);
+            return DEFAULT_SERVICE_VERSION;
+        }
+
+        return serviceVersion;
+    }
+}
diff --git a/src/main/java/org/onap/aai/babel/xml/generator/XmlArtifactGenerationException.java b/src/main/java/org/onap/aai/babel/xml/generator/XmlArtifactGenerationException.java
new file mode 100644 (file)
index 0000000..bff6ab3
--- /dev/null
@@ -0,0 +1,40 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.xml.generator;
+
+/**
+ * This class represents an exception encountered when generating an Artifact.
+ */
+public class XmlArtifactGenerationException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor for an instance of this exception with just a message.
+     *
+     * @param message information about the exception
+     */
+    public XmlArtifactGenerationException(String message) {
+        super(message);
+    }
+}
diff --git a/src/main/resources/babel-logging-resources.properties b/src/main/resources/babel-logging-resources.properties
new file mode 100644 (file)
index 0000000..3cd23ab
--- /dev/null
@@ -0,0 +1,59 @@
+###
+# ============LICENSE_START=======================================================
+# MODEL LOADER SERVICE
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# Copyright (C) 2017 European Software Marketing Ltd.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+#Resource key=Error Code|Message text|Resolution text |Description text
+#######
+#Newlines can be utilized to add some clarity ensuring continuing line
+#has at least one leading space
+#ResourceKey=\
+#             ERR0000E\
+#             Sample error msg txt\
+#             Sample resolution msg\
+#             Sample description txt
+#
+######
+#Error code classification category
+#000 Info/Debug
+#100 Permission errors
+#200 Availability errors/Timeouts
+#300 Data errors
+#400 Schema Interface type/validation errors
+#500 Business process errors
+#900 Unknown errors
+#
+########################################################################
+
+DISTRIBUTION_EVENT=\
+                  BABEL0001I|\
+                  Distribution event: {0}|\
+                  A distribution event was received from ASDC|\
+
+PROCESS_REQUEST_ERROR=\
+                  BABEL0002E|\
+                  Error while processing REST request.|\
+
+INVALID_REQUEST_JSON=\
+                  BABEL0003E|\
+                  Error while processing JSON in request body.|\
+
+INVALID_CSAR_FILE=\
+                  BABEL0004E|\
+                  Error while processing CSAR file.|\
\ No newline at end of file
diff --git a/src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context b/src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context
new file mode 100644 (file)
index 0000000..8514196
--- /dev/null
@@ -0,0 +1 @@
+{"context":{"contextClass":"ajsc.Context","contextId":"__module_ajsc_namespace_name__:__module_ajsc_namespace_version__","contextName":"__module_ajsc_namespace_name__","contextVersion":"__module_ajsc_namespace_version__","description":"__module_ajsc_namespace_name__ Context"}}
\ No newline at end of file
diff --git a/src/main/runtime/context/default#0.context b/src/main/runtime/context/default#0.context
new file mode 100644 (file)
index 0000000..d1b5ab4
--- /dev/null
@@ -0,0 +1 @@
+{"context":{"contextClass":"ajsc.Context","contextId":"default:0","contextName":"default","contextVersion":"0","description":"Default Context"}}
\ No newline at end of file
diff --git a/src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json b/src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json
new file mode 100644 (file)
index 0000000..d0954cf
--- /dev/null
@@ -0,0 +1 @@
+{"deploymentPackage":{"Class":"ajsc.DeploymentPackage","Id":"__module.ajsc.namespace.name__:__module_ajsc_namespace_version__","namespace":"__module_ajsc_namespace_name__","namespaceVersion":"__module_ajsc_namespace_version__","description":"__module_ajsc_namespace_name__ __module_ajsc_namespace_version__ - default description","userId":"ajsc"}}
\ No newline at end of file
diff --git a/src/main/runtime/shiroRole/ajscadmin.json b/src/main/runtime/shiroRole/ajscadmin.json
new file mode 100644 (file)
index 0000000..f5e981e
--- /dev/null
@@ -0,0 +1 @@
+{"shiroRoleClass":"ajsc.auth.ShiroRole","shiroRoleId":"ajscadmin","name":"ajscadmin","permissions":"[ajscadmin:*, ajsc:*]"}
\ No newline at end of file
diff --git a/src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json b/src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json
new file mode 100644 (file)
index 0000000..2dae9f5
--- /dev/null
@@ -0,0 +1 @@
+{"shiroRoleClass":"ajsc.auth.ShiroRole","shiroRoleId":"contextadmin:__module_ajsc_namespace_name__","name":"contextadmin:__module_ajsc_namespace_name__","permissions":"[]"}
\ No newline at end of file
diff --git a/src/main/runtime/shiroRole/contextadmin#default.json b/src/main/runtime/shiroRole/contextadmin#default.json
new file mode 100644 (file)
index 0000000..5de814e
--- /dev/null
@@ -0,0 +1 @@
+{"shiroRoleClass":"ajsc.auth.ShiroRole","shiroRoleId":"contextadmin:default","name":"contextadmin:default","permissions":"[]"}
\ No newline at end of file
diff --git a/src/main/runtime/shiroUser/ajsc.json b/src/main/runtime/shiroUser/ajsc.json
new file mode 100644 (file)
index 0000000..f4c7855
--- /dev/null
@@ -0,0 +1 @@
+{"shiroUserClass":"ajsc.auth.ShiroUser","shiroUserId":"ajsc","passwordHash":"9471697417008c880720ba54c6038791ad7e98f3b88136fe34f4d31a462dd27a","permissions":"[*:*]","username":"ajsc"}
\ No newline at end of file
diff --git a/src/main/runtime/shiroUserRole/ajsc#ajscadmin.json b/src/main/runtime/shiroUserRole/ajsc#ajscadmin.json
new file mode 100644 (file)
index 0000000..cb8d483
--- /dev/null
@@ -0,0 +1 @@
+{"shiroUserRoleClass":"ajsc.auth.ShiroUserRole","shiroUserRoleId":"ajsc:ajscadmin","roleId":"ajscadmin","userId":"ajsc"}
\ No newline at end of file
diff --git a/src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json b/src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json
new file mode 100644 (file)
index 0000000..95d2361
--- /dev/null
@@ -0,0 +1 @@
+{"shiroUserRoleClass":"ajsc.auth.ShiroUserRole","shiroUserRoleId":"ajsc:contextadmin:__module_ajsc_namespace_name__","roleId":"contextadmin:__module_ajsc_namespace_name__","userId":"ajsc"}
\ No newline at end of file
diff --git a/src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json b/src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json
new file mode 100644 (file)
index 0000000..2bd5063
--- /dev/null
@@ -0,0 +1 @@
+{"shiroUserRoleClass":"ajsc.auth.ShiroUserRole","shiroUserRoleId":"ajsc:contextadmin:default","roleId":"contextadmin:default","userId":"ajsc"}
\ No newline at end of file
diff --git a/src/test/java/org/onap/aai/babel/MicroServiceAuthTest.java b/src/test/java/org/onap/aai/babel/MicroServiceAuthTest.java
new file mode 100644 (file)
index 0000000..f24cbf1
--- /dev/null
@@ -0,0 +1,211 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.Test;
+import org.onap.aai.auth.AAIAuthException;
+import org.onap.aai.auth.AAIMicroServiceAuth;
+import org.onap.aai.auth.AAIMicroServiceAuthCore;
+import org.onap.aai.babel.config.BabelAuthConfig;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+/**
+ * Tests @{link AAIMicroServiceAuth}
+ */
+
+public class MicroServiceAuthTest {
+
+    private static final String VALID_ADMIN_USER = "cn=common-name, ou=org-unit, o=org, l=location, st=state, c=us";
+    private static final String authPolicyFile = "auth_policy.json";
+
+    static {
+        System.setProperty("CONFIG_HOME",
+                System.getProperty("user.dir") + File.separator + "src/test/resources");
+    }
+
+    /**
+     * Temporarily invalidate the default policy file and then try to initialise the authorisation class using the name
+     * of a policy file that does not exist.
+     * 
+     * @throws AAIAuthException
+     * @throws IOException
+     */
+    @Test(expected = AAIAuthException.class)
+    public void missingPolicyFile() throws AAIAuthException, IOException {
+        String defaultFile = AAIMicroServiceAuthCore.getDefaultAuthFileName();
+        try {
+            AAIMicroServiceAuthCore.setDefaultAuthFileName("invalid.default.file");
+            BabelAuthConfig gapServiceAuthConfig = new BabelAuthConfig();
+            gapServiceAuthConfig.setAuthPolicyFile("invalid.file.name");
+            new AAIMicroServiceAuth(gapServiceAuthConfig);
+        } finally {
+            AAIMicroServiceAuthCore.setDefaultAuthFileName(defaultFile);
+        }
+    }
+
+    /**
+     * Test loading of a temporary file created with the specified roles
+     * 
+     * @throws AAIAuthException
+     * @throws IOException
+     * @throws JSONException
+     */
+    @Test
+    public void createLocalAuthFile() throws AAIAuthException, IOException, JSONException {
+        JSONObject roles = createRoleObject("role", createUserObject("user"), createFunctionObject("func"));
+        AAIMicroServiceAuth auth = createAuthService(roles);
+        assertThat(auth.authorize("nosuchuser", "method:func"), is(false));
+        assertThat(auth.authorize("user", "method:func"), is(true));
+    }
+
+    /**
+     * Test that the default policy file is loaded when a non-existent file is passed to the authorisation clas.
+     * 
+     * @throws AAIAuthException
+     */
+    @Test
+    public void createAuthFromDefaultFile() throws AAIAuthException {
+        BabelAuthConfig gapServiceAuthConfig = new BabelAuthConfig();
+        gapServiceAuthConfig.setAuthPolicyFile("non-existent-file");
+        AAIMicroServiceAuth auth = new AAIMicroServiceAuth(gapServiceAuthConfig);
+        // The default policy will have been loaded
+        assertAdminUserAuthorisation(auth, VALID_ADMIN_USER);
+    }
+
+    /**
+     * Test loading of the policy file relative to CONFIG_HOME
+     * 
+     * @throws AAIAuthException
+     */
+    @Test
+    public void createAuth() throws AAIAuthException {
+        AAIMicroServiceAuth auth = createStandardAuth();
+        assertAdminUserAuthorisation(auth, VALID_ADMIN_USER);
+    }
+
+    @Test
+    public void testAuthUser() throws AAIAuthException {
+        AAIMicroServiceAuth auth = createStandardAuth();
+        assertThat(auth.authenticate(VALID_ADMIN_USER, "GET:actions"), is(equalTo("OK")));
+        assertThat(auth.authenticate(VALID_ADMIN_USER, "WRONG:action"), is(equalTo("AAI_9101")));
+    }
+
+
+
+    @Test
+    public void testValidateRequest() throws AAIAuthException {
+        AAIMicroServiceAuth auth = createStandardAuth();
+        assertThat(auth.validateRequest(null, new MockHttpServletRequest(), null, "app/v1/gap"), is(false));
+    }
+
+    private AAIMicroServiceAuth createStandardAuth() throws AAIAuthException {
+        BabelAuthConfig gapServiceAuthConfig = new BabelAuthConfig();
+        gapServiceAuthConfig.setAuthPolicyFile(authPolicyFile);
+        return new AAIMicroServiceAuth(gapServiceAuthConfig);
+    }
+
+    /**
+     * @param rolesJson
+     * @return
+     * @throws IOException
+     * @throws AAIAuthException
+     */
+    private AAIMicroServiceAuth createAuthService(JSONObject roles) throws IOException, AAIAuthException {
+        BabelAuthConfig babelAuthConfig = new BabelAuthConfig();
+        File file = File.createTempFile("auth-policy", "json");
+        file.deleteOnExit();
+        FileWriter fileWriter = new FileWriter(file);
+        fileWriter.write(roles.toString());
+        fileWriter.flush();
+        fileWriter.close();
+
+        babelAuthConfig.setAuthPolicyFile(file.getAbsolutePath());
+        return new AAIMicroServiceAuth(babelAuthConfig);
+    }
+
+    /**
+     * Assert authorisation results for an admin user based on the test policy file
+     * 
+     * @param auth
+     * @param adminUser
+     * @throws AAIAuthException
+     */
+    private void assertAdminUserAuthorisation(AAIMicroServiceAuth auth, String adminUser) throws AAIAuthException {
+        assertThat(auth.authorize(adminUser, "GET:actions"), is(true));
+        assertThat(auth.authorize(adminUser, "POST:actions"), is(true));
+        assertThat(auth.authorize(adminUser, "PUT:actions"), is(true));
+        assertThat(auth.authorize(adminUser, "DELETE:actions"), is(true));
+    }
+
+    private JSONArray createFunctionObject(String functionName) throws JSONException {
+        JSONArray functionsArray = new JSONArray();
+        JSONObject func = new JSONObject();
+        func.put("name", functionName);
+        func.put("methods", createMethodObject("method"));
+        functionsArray.put(func);
+        return functionsArray;
+    }
+
+    private JSONArray createMethodObject(String methodName) throws JSONException {
+        JSONArray methodsArray = new JSONArray();
+        JSONObject method = new JSONObject();
+        method.put("name", methodName);
+        methodsArray.put(method);
+        return methodsArray;
+    }
+
+    private JSONArray createUserObject(String username) throws JSONException {
+        JSONArray usersArray = new JSONArray();
+        JSONObject user = new JSONObject();
+        user.put("username", username);
+        usersArray.put(user);
+        return usersArray;
+    }
+
+    private JSONObject createRoleObject(String roleName, JSONArray usersArray, JSONArray functionsArray)
+            throws JSONException {
+        JSONObject roles = new JSONObject();
+
+        JSONObject role = new JSONObject();
+        role.put("name", roleName);
+        role.put("functions", functionsArray);
+        role.put("users", usersArray);
+
+        JSONArray rolesArray = new JSONArray();
+        rolesArray.put(role);
+        roles.put("roles", rolesArray);
+
+        return roles;
+    }
+
+}
diff --git a/src/test/java/org/onap/aai/babel/csar/extractor/YamlExtractorTest.java b/src/test/java/org/onap/aai/babel/csar/extractor/YamlExtractorTest.java
new file mode 100644 (file)
index 0000000..54f4c65
--- /dev/null
@@ -0,0 +1,141 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.csar.extractor;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.onap.aai.babel.util.ArtifactTestUtils;
+import org.openecomp.sdc.generator.data.Artifact;
+
+/**
+ * Tests @see YamlExtractor
+ */
+public class YamlExtractorTest {
+
+    private static final String FOO = "foo";
+    private static final String SOME_BYTES = "just some bytes that will pass the firsts validation";
+    private static final String SUPPLY_AN_ARCHIVE = "An archive must be supplied for processing.";
+    private static final String SUPPLY_NAME = "The name of the archive must be supplied for processing.";
+    private static final String SUPPLY_VERSION = "The version must be supplied for processing.";
+
+    @Test
+    public void extract_nullContentSupplied() {
+        invalidArgumentsTest(null, FOO, FOO, SUPPLY_AN_ARCHIVE);
+    }
+
+    private void invalidArgumentsTest(byte[] archive, String name, String version, String expectedErrorMessage) {
+        try {
+            YamlExtractor.extract(archive, name, version);
+            fail("An instance of InvalidArchiveException should have been thrown");
+        } catch (Exception ex) {
+            assertTrue(ex instanceof InvalidArchiveException);
+            assertEquals(expectedErrorMessage, ex.getLocalizedMessage());
+        }
+    }
+
+    @Test
+    public void extract_emptyContentSupplied() {
+        invalidArgumentsTest(new byte[0], FOO, FOO, SUPPLY_AN_ARCHIVE);
+    }
+
+    @Test
+    public void extract_nullNameSupplied() {
+        invalidArgumentsTest(SOME_BYTES.getBytes(), null, FOO, SUPPLY_NAME);
+    }
+
+    @Test
+    public void extract_blankNameSupplied() {
+        invalidArgumentsTest("just some bytes that will pass the firsts validation".getBytes(), "  \t  ", FOO,
+                SUPPLY_NAME);
+    }
+
+    @Test
+    public void extract_emptyNameSupplied() {
+        invalidArgumentsTest("just some bytes that will pass the firsts validation".getBytes(), "", FOO, SUPPLY_NAME);
+    }
+
+    @Test
+    public void extract_nullVersionSupplied() {
+        invalidArgumentsTest("just some bytes that will pass the firsts validation".getBytes(), FOO, null,
+                SUPPLY_VERSION);
+    }
+
+    @Test
+    public void extract_blankVersionSupplied() {
+        invalidArgumentsTest("just some bytes that will pass the firsts validation".getBytes(), FOO, "  \t  ",
+                SUPPLY_VERSION);
+    }
+
+    @Test
+    public void extract_emptyVersionSupplied() {
+        invalidArgumentsTest("just some bytes that will pass the firsts validation".getBytes(), FOO, "",
+                SUPPLY_VERSION);
+    }
+
+    @Test
+    public void extract_invalidContentSupplied() {
+        invalidArgumentsTest("This is a piece of nonsense and not a zip file".getBytes(), FOO, FOO,
+                "An error occurred trying to create a ZipFile. Is the content being converted really a csar file?");
+    }
+
+    @Test
+    public void extract_archiveContainsNoYmlFiles() throws IOException {
+        try {
+            YamlExtractor.extract(loadResource("compressedArtifacts/noYmlFilesArchive.zip"), "noYmlFilesArchive.zip",
+                    "v1");
+            fail("An instance of InvalidArchiveException should have been thrown.");
+        } catch (Exception e) {
+            assertTrue("An instance of InvalidArchiveException should have been thrown.",
+                    e instanceof InvalidArchiveException);
+            assertEquals("Incorrect message was returned", "No valid yml files were found in the csar file.",
+                    e.getMessage());
+        }
+    }
+
+    private byte[] loadResource(final String archiveName) throws IOException {
+        return IOUtils.toByteArray(YamlExtractor.class.getClassLoader().getResource(archiveName));
+    }
+
+    @Test
+    public void extract_archiveContainsThreeRelevantYmlFilesFromSdWanService()
+            throws IOException, InvalidArchiveException {
+        List<Artifact> ymlFiles =
+                YamlExtractor.extract(loadResource("compressedArtifacts/service-SdWanServiceTest-csar.csar"),
+                        "service-SdWanServiceTest-csar.csar", "v1");
+
+        List<String> payloads = new ArrayList<>();
+        payloads.add("ymlFiles/resource-SdWanTestVsp-template.yml");
+        payloads.add("ymlFiles/resource-TunnelXconntest-template.yml");
+        payloads.add("ymlFiles/service-SdWanServiceTest-template.yml");
+
+        new ArtifactTestUtils().performYmlAsserts(ymlFiles, payloads);
+    }
+}
+
diff --git a/src/test/java/org/onap/aai/babel/csar/fixture/ArtifactInfoBuilder.java b/src/test/java/org/onap/aai/babel/csar/fixture/ArtifactInfoBuilder.java
new file mode 100644 (file)
index 0000000..0ff8fa1
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.csar.fixture;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+
+/**
+ * This class builds an instance of IArtifactInfo for test purposes.
+ */
+public class ArtifactInfoBuilder {
+
+    /**
+     * Builds an implementation of IArtifactInfo for test purposes.
+     * <p/>
+     *
+     * @param type type of artifact
+     * @param name name of artifact
+     * @param description description of artifact
+     * @param version version of artifact
+     * @return IArtifactInfo implementation of IArtifactInfo from given parameters for test purposes
+     */
+    public static IArtifactInfo build(final String type, final String name, final String description,
+            final String version) {
+        IArtifactInfo artifact = new TestArtifactInfoImpl();
+
+        ((TestArtifactInfoImpl) artifact).setArtifactType(type);
+        ((TestArtifactInfoImpl) artifact).setArtifactName(name);
+        ((TestArtifactInfoImpl) artifact).setArtifactDescription(description);
+        ((TestArtifactInfoImpl) artifact).setArtifactVersion(version);
+
+        return artifact;
+    }
+
+    /**
+     * This method is responsible for building a collection of artifacts from a given set of info.
+     * <p/>
+     * The info supplied is a two dimensional array with each element of the first dimension representing a single
+     * artifact and each element of the second dimension represents a property of the artifact.
+     * <p/>
+     * The method will call {@link #build(String, String, String, String)} to build each element in the first dimension
+     * where the elements of the second dimension are the arguments to {@link #build(String, String, String, String)}.
+     * <p/>
+     *
+     * @param artifactInfoBits a two dimensional array of data used to build the artifacts
+     * @return List<IArtifactInfo> a list of artifacts built from the given array of info
+     */
+    static List<IArtifactInfo> buildArtifacts(final String[][] artifactInfoBits) {
+        List<IArtifactInfo> artifacts = new ArrayList<>();
+
+        for (String[] artifactInfoBit : artifactInfoBits) {
+            artifacts.add(build(artifactInfoBit[0], artifactInfoBit[1], artifactInfoBit[2], artifactInfoBit[3]));
+        }
+
+        return artifacts;
+    }
+}
diff --git a/src/test/java/org/onap/aai/babel/csar/fixture/TestArtifactInfoImpl.java b/src/test/java/org/onap/aai/babel/csar/fixture/TestArtifactInfoImpl.java
new file mode 100644 (file)
index 0000000..bbf4a43
--- /dev/null
@@ -0,0 +1,135 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.csar.fixture;
+
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+
+/**
+ * This class is an implementation of IArtifactInfo for test purposes.
+ */
+public class TestArtifactInfoImpl implements IArtifactInfo {
+
+    private String artifactName;
+    private String artifactType;
+    private String artifactDescription;
+    private String artifactVersion;
+
+    @Override
+    public String getArtifactName() {
+        return artifactName;
+    }
+
+    void setArtifactName(String artifactName) {
+        this.artifactName = artifactName;
+    }
+
+    @Override
+    public String getArtifactType() {
+        return artifactType;
+    }
+
+    void setArtifactType(String artifactType) {
+        this.artifactType = artifactType;
+    }
+
+    @Override
+    public String getArtifactURL() {
+        return null;
+    }
+
+    @Override
+    public String getArtifactChecksum() {
+        return null;
+    }
+
+    @Override
+    public String getArtifactDescription() {
+        return artifactDescription;
+    }
+
+    void setArtifactDescription(String artifactDescription) {
+        this.artifactDescription = artifactDescription;
+    }
+
+    @Override
+    public Integer getArtifactTimeout() {
+        return null;
+    }
+
+    @Override
+    public String getArtifactVersion() {
+        return artifactVersion;
+    }
+
+    void setArtifactVersion(String artifactVersion) {
+        this.artifactVersion = artifactVersion;
+    }
+
+    @Override
+    public String getArtifactUUID() {
+        return null;
+    }
+
+    @Override
+    public IArtifactInfo getGeneratedArtifact() {
+        return null;
+    }
+
+    @Override
+    public java.util.List<IArtifactInfo> getRelatedArtifacts() {
+        return null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        TestArtifactInfoImpl that = (TestArtifactInfoImpl) o;
+
+        if (artifactName != null ? !artifactName.equals(that.artifactName) : that.artifactName != null) {
+            return false;
+        }
+        if (artifactType != null ? !artifactType.equals(that.artifactType) : that.artifactType != null) {
+            return false;
+        }
+        if (artifactDescription != null ? !artifactDescription.equals(that.artifactDescription)
+                : that.artifactDescription != null) {
+            return false;
+        }
+        return artifactVersion != null ? artifactVersion.equals(that.artifactVersion) : that.artifactVersion == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = artifactName != null ? artifactName.hashCode() : 0;
+        result = 31 * result + (artifactType != null ? artifactType.hashCode() : 0);
+        result = 31 * result + (artifactDescription != null ? artifactDescription.hashCode() : 0);
+        result = 31 * result + (artifactVersion != null ? artifactVersion.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/src/test/java/org/onap/aai/babel/service/CsarToXmlConverterTest.java b/src/test/java/org/onap/aai/babel/service/CsarToXmlConverterTest.java
new file mode 100644 (file)
index 0000000..5c1e213
--- /dev/null
@@ -0,0 +1,170 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.service;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.custommonkey.xmlunit.XMLTestCase;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.onap.aai.babel.csar.CsarConverterException;
+import org.onap.aai.babel.csar.CsarToXmlConverter;
+import org.onap.aai.babel.service.data.BabelArtifact;
+import org.onap.aai.babel.util.ArtifactTestUtils;
+import org.onap.aai.babel.xml.generator.ModelGenerator;
+import org.onap.aai.babel.xml.generator.XmlArtifactGenerationException;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.xml.sax.SAXException;
+
+/**
+ * Tests {@link CsarToXmlConverter}
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(ModelGenerator.class)
+public class CsarToXmlConverterTest extends XMLTestCase {
+
+    private static final String NAME = "the_name_of_the_csar_file.csar";
+    private static final String VERSION = "v1";
+
+    private CsarToXmlConverter converter;
+
+    @Rule
+    public ExpectedException exception = ExpectedException.none();
+
+    @Before
+    public void setUp() {
+        converter = new CsarToXmlConverter();
+        URL url = CsarToXmlConverterTest.class.getClassLoader().getResource("artifact-generator.properties");
+        System.setProperty("artifactgenerator.config", url.getPath());
+    }
+
+    @After
+    public void tearDown() {
+        converter = null;
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void generateXmlFromCsar_nullArtifactSupplied() throws CsarConverterException {
+        converter.generateXmlFromCsar(null, null, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void generateXmlFromCsar_missingName() throws CsarConverterException, IOException {
+        byte[] csarArchive = new ArtifactTestUtils().loadResource("compressedArtifacts/service-VscpaasTest-csar.csar");
+        converter.generateXmlFromCsar(csarArchive, null, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void generateXmlFromCsar_missingVersion() throws CsarConverterException, IOException {
+        byte[] csarArchive = new ArtifactTestUtils().loadResource("compressedArtifacts/service-VscpaasTest-csar.csar");
+        converter.generateXmlFromCsar(csarArchive, NAME, null);
+    }
+
+    @Test(expected = CsarConverterException.class)
+    public void generateXmlFromCsar_noPayloadExists() throws CsarConverterException {
+        converter.generateXmlFromCsar(new byte[0], NAME, VERSION);
+    }
+
+    @Test(expected = CsarConverterException.class)
+    public void generateXmlFromCsar_csarFileHasNoYmlFiles() throws CsarConverterException, IOException {
+        byte[] csarArchive = new ArtifactTestUtils().loadResource("compressedArtifacts/noYmlFilesArchive.zip");
+        converter.generateXmlFromCsar(csarArchive, "noYmlFilesArchive.zip", VERSION);
+    }
+
+    @Test
+    public void generateXmlFromCsar_artifactgenerator_config_systemPropertyNotSet()
+            throws IOException, XmlArtifactGenerationException, CsarConverterException {
+        exception.expect(CsarConverterException.class);
+        exception.expectMessage("Cannot generate artifacts. artifactgenerator.config system property not configured");
+
+        byte[] csarArchive =
+                new ArtifactTestUtils().loadResource("compressedArtifacts/service-SdWanServiceTest-csar.csar");
+
+        // Unset the required system property
+        System.clearProperty("artifactgenerator.config");
+        converter.generateXmlFromCsar(csarArchive, VERSION, "service-SdWanServiceTest-csar.csar");
+    }
+
+    @Test
+    public void generateXmlFromCsar() throws CsarConverterException, IOException, XmlArtifactGenerationException {
+        byte[] csarArchive =
+                new ArtifactTestUtils().loadResource("compressedArtifacts/service-SdWanServiceTest-csar.csar");
+
+        Map<String, String> expectedXmlFiles = createExpectedXmlFiles();
+        List<BabelArtifact> generatedArtifacts =
+                converter.generateXmlFromCsar(csarArchive, VERSION, "service-SdWanServiceTest-csar.csar");
+
+        generatedArtifacts.forEach(ga -> {
+            try {
+
+                String x1 = expectedXmlFiles.get(ga.getName());
+
+                String x2 = bytesToString(ga.getPayload());
+
+                assertXMLEqual("The content of " + ga.getName() + " must match the expected content", x1, x2);
+
+            } catch (SAXException | IOException e) {
+                fail("There was an Exception parsing the XML: "+e.getMessage());
+            }
+        });
+    }
+
+    public String bytesToString(byte[] source) {
+        ByteArrayInputStream bis = new ByteArrayInputStream(Base64.getDecoder().decode(source));
+
+        String result = new BufferedReader(new InputStreamReader(bis)).lines().collect(Collectors.joining("\n"));
+
+        return result;
+
+    }
+
+    private Map<String, String> createExpectedXmlFiles() throws IOException {
+        Map<String, String> xml = new HashMap<>();
+
+        ArtifactTestUtils utils = new ArtifactTestUtils();
+
+        String[] filesToLoad =
+                {"AAI-SD-WAN-Service-Test-service-1.0.xml", "AAI-SdWanTestVsp..DUMMY..module-0-resource-2.xml",
+                        "AAI-Tunnel_XConnTest-resource-2.0.xml", "AAI-SD-WAN-Test-VSP-resource-1.0.xml"};
+
+        for (String s : filesToLoad) {
+            xml.put(s, utils.loadResourceAsString("generatedXml/" + s));
+
+        }
+
+        return xml;
+    }
+}
diff --git a/src/test/java/org/onap/aai/babel/service/TestGenerateArtifactsServiceImpl.java b/src/test/java/org/onap/aai/babel/service/TestGenerateArtifactsServiceImpl.java
new file mode 100644 (file)
index 0000000..5d2309f
--- /dev/null
@@ -0,0 +1,111 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.service;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.stream.Collectors;
+import javax.ws.rs.core.Response;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Direct invocation of the generate artifacts service implementation
+ *
+ */
+public class TestGenerateArtifactsServiceImpl {
+    
+    @BeforeClass
+    public static void setup() {
+        URL url = TestGenerateArtifactsServiceImpl.class.getClassLoader().getResource("artifact-generator.properties");
+        System.setProperty("artifactgenerator.config", url.getPath());
+    }
+    
+    @Test
+    public void testGenerateArtifacts() throws Exception {
+        String jsonRequest = readstringFromFile("jsonFiles/success_request.json");
+        Response response = processJsonRequest(jsonRequest);
+        assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+        assertThat(response.getEntity(), is(readstringFromFile("response/response.json")));
+    }
+
+    
+    @Test
+    public void testInvalidCsarFile() throws URISyntaxException, IOException{          
+        String jsonRequest = readstringFromFile("jsonFiles/invalid_csar_request.json");
+         Response response = processJsonRequest(jsonRequest);
+         assertThat(response.getStatus(), is(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())); 
+         assertThat(response.getEntity(), is("Error converting CSAR artifact to XML model."));
+    }
+    
+    @Test
+    public void testInvalidJsonFile() throws URISyntaxException, IOException{          
+        String jsonRequest = readstringFromFile("jsonFiles/invalid_json_request.json");
+         Response response = processJsonRequest(jsonRequest);
+         assertThat(response.getStatus(), is(Response.Status.BAD_REQUEST.getStatusCode())); 
+         assertThat(response.getEntity(), is("Malformed request."));
+    }
+    
+    @Test
+    public void testMissingArtifactName() throws Exception {
+        String jsonRequest = readstringFromFile("jsonFiles/missing_artifact_name_request.json");
+        Response response = processJsonRequest(jsonRequest);
+        assertThat(response.getStatus(), is(Response.Status.BAD_REQUEST.getStatusCode()));
+        assertThat(response.getEntity(), is("No artifact name attribute found in the request body." ));
+    }
+    
+    @Test
+    public void testMissingArtifactVersion() throws Exception {
+        String jsonRequest = readstringFromFile("jsonFiles/missing_artifact_version_request.json");
+        Response response = processJsonRequest(jsonRequest);
+        assertThat(response.getStatus(), is(Response.Status.BAD_REQUEST.getStatusCode()));
+        assertThat(response.getEntity(), is("No artifact version attribute found in the request body."));
+    }
+    
+    @Test
+    public void testMissingCsarFile() throws Exception {
+        String jsonRequest = readstringFromFile("jsonFiles/missing_csar_request.json");
+        Response response = processJsonRequest(jsonRequest);
+        assertThat(response.getStatus(), is(Response.Status.BAD_REQUEST.getStatusCode()));
+        assertThat(response.getEntity(), is("No csar attribute found in the request body."));
+    }
+    
+
+    private Response processJsonRequest(String jsonRequest) {
+        GenerateArtifactsServiceImpl service = new GenerateArtifactsServiceImpl(/* No authentiction required */ null);
+        return service.generateArtifacts(jsonRequest);
+    }
+
+    private String readstringFromFile(String resourceFile) throws IOException, URISyntaxException {
+        return Files.lines(Paths.get(ClassLoader.getSystemResource(resourceFile).toURI()))
+                .collect(Collectors.joining());
+    }
+    
+    
+}
diff --git a/src/test/java/org/onap/aai/babel/util/ArtifactTestUtils.java b/src/test/java/org/onap/aai/babel/util/ArtifactTestUtils.java
new file mode 100644 (file)
index 0000000..74f0c0e
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.util;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import com.google.common.base.Throwables;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Base64;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.commons.io.IOUtils;
+import org.openecomp.sdc.generator.data.Artifact;
+
+/**
+ * This class provides some utilities to assist with running tests.
+ */
+public class ArtifactTestUtils {
+
+    public void performYmlAsserts(List<Artifact> toscaFiles, List<String> ymlPayloadsToLoad) {
+        assertThat("An unexpected number of yml files have been extracted", toscaFiles.size(),
+                is(ymlPayloadsToLoad.size()));
+
+        Set<String> ymlPayloads = ymlPayloadsToLoad.stream().map(s -> {
+            try {
+                return loadResourceAsString(s);
+            } catch (IOException e) {
+                throw Throwables.propagate(e);
+            }
+        }).collect(Collectors.toSet());
+
+        toscaFiles.forEach(ts -> {
+            boolean payloadFound = false;
+
+            String s = bytesToString(ts.getPayload());
+
+            for (String ymlPayload : ymlPayloads) {
+                String tscontent = ymlPayload;
+
+                if (s.endsWith(tscontent)) {
+                    payloadFound = true;
+                    break;
+                }
+            }
+            assertThat("The content of each yml file must match the actual content of the file extracted ("
+                    + ts.getName() + ")", payloadFound, is(true));
+        });
+    }
+
+    public byte[] loadResource(String resourceName) throws IOException {
+
+        return IOUtils.toByteArray(ArtifactTestUtils.class.getClassLoader().getResource(resourceName));
+    }
+
+    public String loadResourceAsString(String resourceName) throws IOException {
+
+        InputStream is = ArtifactTestUtils.class.getClassLoader().getResource(resourceName).openStream();
+
+        String result = new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"));
+
+        return result;
+
+    }
+
+    public String bytesToString(byte[] source) {
+        ByteArrayInputStream bis = new ByteArrayInputStream(Base64.getDecoder().decode(source));
+
+        String result = new BufferedReader(new InputStreamReader(bis)).lines().collect(Collectors.joining("\n"));
+
+        return result;
+
+    }
+
+}
diff --git a/src/test/java/org/onap/aai/babel/util/TestRequestValidator.java b/src/test/java/org/onap/aai/babel/util/TestRequestValidator.java
new file mode 100644 (file)
index 0000000..030c24d
--- /dev/null
@@ -0,0 +1,72 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright Â© 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright Â© 2017 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.babel.util;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onap.aai.babel.service.data.BabelRequest;
+
+public class TestRequestValidator {
+    
+    @Rule
+    public ExpectedException exception = ExpectedException.none();
+    
+    @Test
+    public void testMissingArtifactNameExceptionThrown() throws Exception{
+        exception.expect(RequestValidationException.class);
+        exception.expectMessage("No artifact name attribute found in the request body.");
+        
+        BabelRequest request = new BabelRequest();
+        request.setCsar("UEsDBBQACAgIAGsrz0oAAAAAAAAAAAAAAAAJAAAAY3Nhci5tZXRhC3Z");
+        request.setArtifactVersion("1.0");
+        request.setArtifactName(null);
+        RequestValidator.validateRequest(request);       
+        }
+    
+
+       @Test
+    public void testMissingArtifactVersionExceptionThrown() throws Exception{
+           exception.expect(RequestValidationException.class);
+           exception.expectMessage("No artifact version attribute found in the request body.");
+           
+        BabelRequest request = new BabelRequest();
+        request.setCsar("UEsDBBQACAgIAGsrz0oAAAAAAAAAAAAAAAAJAAAAY3Nhci5tZXRhC3Z");
+        request.setArtifactVersion(null);
+        request.setArtifactName("hello");
+        RequestValidator.validateRequest(request);         
+    }
+    
+    @Test
+    public void testMissingCsarFile() throws Exception{
+        exception.expect(RequestValidationException.class);
+        exception.expectMessage("No csar attribute found in the request body.");
+        
+        BabelRequest request = new BabelRequest();
+        request.setCsar(null);
+        request.setArtifactVersion("1.0");
+        request.setArtifactName("hello");
+        RequestValidator.validateRequest(request);            
+    }
+
+}
diff --git a/src/test/resources/artifact-generator.properties b/src/test/resources/artifact-generator.properties
new file mode 100644 (file)
index 0000000..1d7e5fa
--- /dev/null
@@ -0,0 +1,264 @@
+#action widget details
+AAI.model-version-id.action=fd7fb09e-d930-41b9-b83f-cfde9df48640
+AAI.model-invariant-id.action=af593b4b-490e-4665-ad74-2f6351c0a7ce
+#action-data widget details
+AAI.model-invariant-id.action-data=9551346c-7d8b-4daf-9926-b93e96e2344a
+AAI.model-version-id.action-data=2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd
+#allotted-resource widget details
+AAI.model-invariant-id.allotted-resource=f6d6a23d-a1a9-48ff-8419-b6530da2d381
+AAI.model-version-id.allotted-resource=7ad0915f-25c0-4a70-b9bc-185a75f87564
+#availability-zone widget details
+AAI.model-version-id.availability-zone=6c092fb1-21b2-456b-9e01-67fb4de1896e
+AAI.model-invariant-id.availability-zone=61b88c01-d819-41c0-8e21-7fd7ba47148e
+#az-and-dvs-switches widget details
+AAI.model-version-id.az-and-dvs-switches=b2dea88d-78a0-49bf-95c9-5819df08e966
+AAI.model-invariant-id.az-and-dvs-switches=53dc00d4-e6d9-48ec-b6cc-3d3797e9b896
+#class-of-service widget details
+AAI.model-version-id.class-of-service=d2fb27cc-15eb-4c4e-828e-71d41aaecc5b
+AAI.model-invariant-id.class-of-service=18094b19-d16d-4822-8acf-e92c6aefa178
+#cloud-region widget details
+AAI.model-version-id.cloud-region=2a160989-b202-47dd-874b-4a0f275998f7
+AAI.model-invariant-id.cloud-region=425b2158-e51d-4509-9945-dad4556474a3
+#complex widget details
+AAI.model-invariant-id.complex=af91c2f7-35fc-43cf-a13d-443f385b2353
+AAI.model-version-id.complex=3a8ab1ee-9220-4fe8-b89c-9251d160ddc2
+#connector widget details
+AAI.model-version-id.connector=22104c9f-29fd-462f-be07-96cd6b46dd33
+AAI.model-invariant-id.connector=4c01c948-7607-4d66-8a6c-99c2c2717936
+#constrained-element-set widget details
+AAI.model-invariant-id.constrained-element-set=c0292b4f-ee97-40cc-8c2e-f967c48f5701
+AAI.model-version-id.constrained-element-set=01102126-9c04-4a89-945b-b131e61e95d7
+#ctag-assignment widget details
+AAI.model-version-id.ctag-assignment=44e5cb1f-0938-41aa-b766-d4595109fe89
+AAI.model-invariant-id.ctag-assignment=fcb8d46b-b656-4ad6-8fa4-22cef74b443f
+#ctag-pool widget details
+AAI.model-invariant-id.ctag-pool=46c51d4e-d67e-4a9c-b1f5-49b1e9c6fcaa
+AAI.model-version-id.ctag-pool=2056c41f-23b9-4de7-9f50-819adad37d76
+#customer widget details
+AAI.model-invariant-id.customer=c1d4305f-cdbd-4bbe-9069-a2f4978fd89e
+AAI.model-version-id.customer=d4df5c27-98a1-4812-a8aa-c17f055b7a3f
+#cvlan-tag-entry widget details
+AAI.model-version-id.cvlan-tag-entry=c3878ffb-8d85-4114-bee6-e4074a9db10b
+AAI.model-invariant-id.cvlan-tag-entry=245cf4b0-7cc5-4eea-bbd9-753e939adcab
+#dvs-switch widget details
+AAI.model-invariant-id.dvs-switch=98fbb471-1f86-428e-bd8a-c8a25de6fa23
+AAI.model-version-id.dvs-switch=4cb44ae8-e3ab-452a-9f95-bcc8a44c55ea
+#edge-prop-names widget details
+AAI.model-invariant-id.edge-prop-names=7a08cad4-8759-46a5-8245-095d1ba57ac6
+AAI.model-version-id.edge-prop-names=f0442326-8201-4d0e-857c-74b4ddcbfc9f
+#element-choice-set widget details
+AAI.model-invariant-id.element-choice-set=9a011958-7165-47a3-b872-00951d1f09ae
+AAI.model-version-id.element-choice-set=af27fbfd-598d-44da-aeae-0f9d3a5fcd6a
+#entitlement widget details
+AAI.model-version-id.entitlement=7e27ba2e-b7db-4e13-9fae-d142152ef98a
+AAI.model-invariant-id.entitlement=ae75b5a0-d5e1-4f3a-b8fb-37626a753da3
+#flavor widget details
+AAI.model-invariant-id.flavor=bace8d1c-a261-4041-9e37-823117415d0f
+AAI.model-version-id.flavor=36200fb5-f251-4f5d-a520-7c5ad5c2cd4b
+#generic-vnf widget details
+AAI.model-version-id.generic-vnf=93a6166f-b3d5-4f06-b4ba-aed48d009ad9
+AAI.model-invariant-id.generic-vnf=acc6edd8-a8d4-4b93-afaa-0994068be14c
+#group-assignment widget details
+AAI.model-invariant-id.group-assignment=7cc05f25-7ba2-42b7-a237-c5662a1689e1
+AAI.model-version-id.group-assignment=fe578080-ce19-4604-8760-fc264fbb2565
+#image widget details
+AAI.model-version-id.image=f6a038c2-820c-42ba-8c2b-375e24e8f932
+AAI.model-invariant-id.image=3f4c7204-739b-4bbb-87a7-8a6856439c90
+#include-node-filter widget details
+AAI.model-invariant-id.include-node-filter=2a2d8ad2-af0a-4e1f-9982-0c899e7dc827
+AAI.model-version-id.include-node-filter=f05f804d-7057-4ffe-bdc5-39f2f0c9c9fd
+#instance-group widget details
+AAI.model-version-id.instance-group=8e6ee9dc-9017-444a-83b3-219edb018128
+AAI.model-invariant-id.instance-group=3bf1e610-45f7-4ad6-b833-ca4c5ee6a3fd
+#inventory-item widget details
+AAI.model-invariant-id.inventory-item=cd57d844-9017-4078-aa19-926935a3d77c
+AAI.model-version-id.inventory-item=69957f4a-2155-4b95-8d72-d6dd9b88b27b
+#inventory-item-data widget details
+AAI.model-version-id.inventory-item-data=0e54bb87-bd6e-4a2b-ad1c-6d935b87ae51
+AAI.model-invariant-id.inventory-item-data=87a383ae-cf03-432e-a9de-04e6a622d0fd
+#ipsec-configuration widget details
+AAI.model-invariant-id.ipsec-configuration=aca4c310-cb45-42bd-9f88-73e40ba7b962
+AAI.model-version-id.ipsec-configuration=d949fd10-36bf-408a-ac7a-cad5004d2e0d
+#key-data widget details
+AAI.model-version-id.key-data=c23ea04d-1a3b-453d-bc49-a6c783a5e92b
+AAI.model-invariant-id.key-data=f5faa464-c2f2-4cc3-89d2-a90452dc3a07
+#l3-interface-ipv4-address-list widget details
+AAI.model-version-id.l3-interface-ipv4-address-list=41e76b6f-1e06-4fd4-82cd-81c50fc4574b
+AAI.model-invariant-id.l3-interface-ipv4-address-list=aad85df2-09be-40fa-b867-16415e4e10e2
+#l3-interface-ipv6-address-list widget details
+AAI.model-invariant-id.l3-interface-ipv6-address-list=82966045-43ee-4982-8307-7e9610866140
+AAI.model-version-id.l3-interface-ipv6-address-list=d040621d-541a-477b-bb1b-a2b61b14e295
+#l3-network widget details
+AAI.model-version-id.l3-network=9111f20f-e680-4001-b83f-19a2fc23bfc1
+AAI.model-invariant-id.l3-network=3d560d81-57d0-438b-a2a1-5334dba0651a
+#lag-interface widget details
+AAI.model-version-id.lag-interface=ce95f7c3-b61b-4758-ae9e-7e943b1c103d
+AAI.model-invariant-id.lag-interface=e0ee9bde-c1fc-4651-a95d-8e0597bf7d70
+#lag-link widget details
+AAI.model-version-id.lag-link=d29a087a-af59-4053-a3f8-0f95a92faa75
+AAI.model-invariant-id.lag-link=86ffe6e5-4d0e-4cec-80b5-5c38aa3eff98
+#license widget details
+AAI.model-invariant-id.license=b9a9b337-1f86-42d3-b9f9-f987a089507c
+AAI.model-version-id.license=6889274b-a1dc-40ab-9090-93677e13e2e6
+#license-key-resource widget details
+AAI.model-invariant-id.license-key-resource=9022ebfe-b54f-4911-a6b2-8c3f5ec189b7
+AAI.model-version-id.license-key-resource=24b25f8c-b8bd-4c62-9421-87c12667aac9
+#l-interface widget details
+AAI.model-version-id.l-interface=a32613fd-18b9-459e-aab8-fffb3912966a
+AAI.model-invariant-id.l-interface=cea0a982-8d55-4093-921e-418fbccf7060
+#logical-link widget details
+AAI.model-version-id.logical-link=a1481a38-f8ba-4ae4-bdf1-06c2c6af4c54
+AAI.model-invariant-id.logical-link=fe012535-2c31-4a39-a739-612374c638a0
+#metadatum widget details
+AAI.model-invariant-id.metadatum=86dbb63a-265e-4614-993f-6771c30b56a5
+AAI.model-version-id.metadatum=6bae950e-8939-41d3-a6a7-251b03e4c1fc
+#model widget details
+AAI.model-invariant-id.model=06d1418a-5faa-452d-a94b-a2829df5f67b
+AAI.model-version-id.model=1f51c05c-b164-4c27-9c03-5cbb239fd6be
+#model-constraint widget details
+AAI.model-invariant-id.model-constraint=c28966f3-e758-4483-b37b-a90b05d3dd33
+AAI.model-version-id.model-constraint=ad70dd19-f156-4fb5-a865-97b5563b0d37
+#model-element widget details
+AAI.model-invariant-id.model-element=2076e726-3577-477a-a300-7fa65cd4df11
+AAI.model-version-id.model-element=753e813a-ba9e-4a1d-ab34-b2f6dc6eec0c
+#multicast-configuration widget details
+AAI.model-invariant-id.multicast-configuration=ea78c9e3-514d-4a0a-9162-13837fa54c35
+AAI.model-version-id.multicast-configuration=666a06ee-4b57-46df-bacf-908da8f10c3f
+#named-query widget details
+AAI.model-version-id.named-query=5c3b7c33-afa3-4be5-8da7-1a5ac6f99896
+AAI.model-invariant-id.named-query=80b712fd-0ad3-4180-a99c-8c995cf1cc32
+#named-query-element widget details
+AAI.model-version-id.named-query-element=204c641a-3494-48c8-979a-86856f5fd32a
+AAI.model-invariant-id.named-query-element=3c504d40-b847-424c-9d25-4fb7e0a3e994
+#network-policy widget details
+AAI.model-invariant-id.network-policy=6aa05779-94d7-4d8b-9bee-59ef2ab0c246
+AAI.model-version-id.network-policy=a0ccd9dc-7062-4940-9bcc-e91dd28af510
+#network-profile widget details
+AAI.model-version-id.network-profile=01f45471-4240-498c-a9e1-235dc0b8b4a6
+AAI.model-invariant-id.network-profile=2734b44a-b8a2-40f6-957d-6256589e5d00
+#newvce widget details
+AAI.model-version-id.newvce=7c79e11f-a408-4593-aa86-ba948a1236af
+AAI.model-invariant-id.newvce=4b05ec9c-c55d-4987-83ff-e08d6ddb694f
+#oam-network widget details
+AAI.model-invariant-id.oam-network=2851cf01-9c40-4064-87d4-6184a6fcff35
+AAI.model-version-id.oam-network=f4fb34f3-fd6e-4a8f-a3fb-4ab61a343b79
+#physical-link widget details
+AAI.model-invariant-id.physical-link=c822d81f-822f-4304-9623-1025b53da568
+AAI.model-version-id.physical-link=9c523936-95b4-4d7f-9f53-6bdfe0cf2c05
+#p-interface widget details
+AAI.model-invariant-id.p-interface=94043c37-4e73-439c-a790-0fdd697924cd
+AAI.model-version-id.p-interface=d2cdb2d0-fc1f-4a57-a89e-591b1c4e3754
+#pnf widget details
+AAI.model-version-id.pnf=e9f1fa7d-c839-418a-9601-03dc0d2ad687
+AAI.model-invariant-id.pnf=862b25a1-262a-4961-bdaa-cdc55d69785a
+#port-group widget details
+AAI.model-version-id.port-group=03e8bb6b-b48a-46ae-b5d4-e5af577e6844
+AAI.model-invariant-id.port-group=8ce940fb-55d7-4230-9e7f-a56cc2741f77
+#property-constraint widget details
+AAI.model-version-id.property-constraint=81706bbd-981e-4362-ae20-995cbcb2d995
+AAI.model-invariant-id.property-constraint=f4a863c3-6886-470a-a6ae-05723837ea45
+#pserver widget details
+AAI.model-invariant-id.pserver=6d932c8f-463b-4e76-83fb-87acfbaa2e2d
+AAI.model-version-id.pserver=72f0d495-bc27-4653-9e1a-eef76bd34bc9
+#related-lookup widget details
+AAI.model-invariant-id.related-lookup=468f6f5b-2996-41bb-b2a3-7cf9613ebb9b
+AAI.model-version-id.related-lookup=0988bab5-bf4f-4938-a419-ab249867d12a
+#reserved-prop-names widget details
+AAI.model-invariant-id.reserved-prop-names=0c3e0ba3-618c-498d-9127-c8d42b00170f
+AAI.model-version-id.reserved-prop-names=ac49d26d-9163-430e-934a-13b738a04f5c
+#result-data widget details
+AAI.model-version-id.result-data=4e9b50aa-5227-4f6f-b489-62e6bbc03c79
+AAI.model-invariant-id.result-data=ff656f23-6185-406f-9006-4b26834f3e1c
+#route-table-reference widget details
+AAI.model-version-id.route-table-reference=fed7e326-03a7-45ff-a3f2-471470d268c4
+AAI.model-invariant-id.route-table-reference=a8614b63-2636-4c4f-98df-fd448c4241db
+#routing-instance widget details
+AAI.model-invariant-id.routing-instance=1c2ded4f-8b01-4193-829c-966847dfec3e
+AAI.model-version-id.routing-instance=3ccbcbc7-d19e-44d5-a52f-7e18aa8d69fa
+#secondary-filter widget details
+AAI.model-version-id.secondary-filter=1380619d-dd1a-4cec-b755-c6407833e065
+AAI.model-invariant-id.secondary-filter=738ff299-6290-4c00-8998-bd0e96a07b93
+#segmentation-assignment widget details
+AAI.model-invariant-id.segmentation-assignment=6e814aee-46e1-4583-a9d4-0049bfd2b59b
+AAI.model-version-id.segmentation-assignment=c5171ae0-44fb-4c04-b482-d56702241a44
+#service widget details
+AAI.model-version-id.service=ecce2c42-3957-4ae0-9442-54bc6afe27b6
+AAI.model-invariant-id.service=07a3a60b-1b6c-4367-8173-8014386f89e3
+#service-capability widget details
+AAI.model-invariant-id.service-capability=b1a7cc05-d19d-443b-a5d1-733e325c4232
+AAI.model-version-id.service-capability=f9cfec1b-18da-4bba-bd83-4b26cca115cd
+#service-instance widget details
+AAI.model-invariant-id.service-instance=82194af1-3c2c-485a-8f44-420e22a9eaa4
+AAI.model-version-id.service-instance=46b92144-923a-4d20-b85a-3cbd847668a9
+#service-subscription widget details
+AAI.model-invariant-id.service-subscription=2e1a602a-acd8-4f78-94ff-618b802a303b
+AAI.model-version-id.service-subscription=5e68299a-79f2-4bfb-8fbc-2bae877a2459
+#site-pair widget details
+AAI.model-version-id.site-pair=7106bc02-6552-4fc3-8a56-4f3df9034531
+AAI.model-invariant-id.site-pair=db63f3e6-f8d1-484e-8d5e-191600b7914b
+#site-pair-set widget details
+AAI.model-invariant-id.site-pair-set=5d4dae3e-b402-4bfd-909e-ece12ff75d26
+AAI.model-version-id.site-pair-set=a5c6c1bc-dc38-468e-9459-bb08f87247df
+#snapshot widget details
+AAI.model-version-id.snapshot=962a7c8b-687f-4d32-a775-fe098e214bcd
+AAI.model-invariant-id.snapshot=24de00ef-aead-4b52-995b-0adf8d4bd90d
+#sriov-vf widget details
+AAI.model-version-id.sriov-vf=1e8b331f-3d4a-4160-b7aa-f4d5a8916625
+AAI.model-invariant-id.sriov-vf=04b2935f-33c4-40a9-8af0-8b52690042dc
+#start-node-filter widget details
+AAI.model-version-id.start-node-filter=aad96fd3-e75f-42fc-9777-3450c36f1168
+AAI.model-invariant-id.start-node-filter=083093a3-e407-447a-ba5d-7583e4d23e1d
+#subnet widget details
+AAI.model-version-id.subnet=f902a6bc-6be4-4fe5-8458-a6ec0056b374
+AAI.model-invariant-id.subnet=1b2c9ba7-e449-4831-ba15-3073672f5ef2
+#tagged-inventory-item-list widget details
+AAI.model-invariant-id.tagged-inventory-item-list=e78a7eaa-f65d-4919-9c2b-5b258c8c4d7e
+AAI.model-version-id.tagged-inventory-item-list=c246f6e2-e3a1-4697-94c0-5672a7fbbf04
+#tenant widget details
+AAI.model-invariant-id.tenant=97c26c99-6870-44c1-8a07-1d900d3f4ce6
+AAI.model-version-id.tenant=abcc54bc-bb74-49dc-9043-7f7171707545
+#tunnel-xconnect widget details
+AAI.model-invariant-id.tunnel-xconnect=50b9e2fa-005c-4bbe-b651-3251dece4cd8
+AAI.model-version-id.tunnel-xconnect=e7cb4ca8-e1a5-4487-a716-4ae0bcd8aef5
+#update-node-key widget details
+AAI.model-version-id.update-node-key=6004cfa6-eb6d-4062-971f-b1fde6b74aa0
+AAI.model-invariant-id.update-node-key=fe81c801-f65d-408a-b2b7-a729a18f8154
+#vce widget details
+AAI.model-version-id.vce=b6cf54b5-ec45-43e1-be64-97b4e1513333
+AAI.model-invariant-id.vce=bab6dceb-e7e6-4301-a5e0-a7399b48d792
+#vf-module widget details
+AAI.model-invariant-id.vf-module=ef86f9c5-2165-44f3-8fc3-96018b609ea5
+AAI.model-version-id.vf-module=c00563ae-812b-4e62-8330-7c4d0f47088a
+#vig-server widget details
+AAI.model-version-id.vig-server=8e8c22f1-fbdf-48ea-844c-8bdeb44e7b16
+AAI.model-invariant-id.vig-server=bed7c3b7-35d0-4cd9-abde-41b20e68b28e
+#virtual-data-center widget details
+AAI.model-invariant-id.virtual-data-center=5150abcf-0c5f-4593-9afe-a19c48fc4824
+AAI.model-version-id.virtual-data-center=6dd43ced-d789-47af-a759-d3abc14e3ac1
+#vlan widget details
+AAI.model-version-id.vlan=257d88a5-a269-4c35-944f-aca04fbdb791
+AAI.model-invariant-id.vlan=d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8
+#vnfc widget details
+AAI.model-invariant-id.vnfc=96129eb9-f0de-4e05-8af2-73146473f766
+AAI.model-version-id.vnfc=5761e0a7-c6df-4d8a-9ebd-b8f445054dec
+#vnf-image widget details
+AAI.model-invariant-id.vnf-image=f9a628ff-7aa0-40e2-a93d-02d91c950982
+AAI.model-version-id.vnf-image=c4d3e747-ba4a-4b17-9896-94c6f18c19d3
+#volume widget details
+AAI.model-version-id.volume=0fbe2e8f-4d91-4415-a772-88387049b38d
+AAI.model-invariant-id.volume=ddd739b4-2b25-46c4-affc-41a32af5cc42
+#volume-group widget details
+AAI.model-invariant-id.volume-group=fcec1b02-b2d0-4834-aef8-d71be04717dd
+AAI.model-version-id.volume-group=99d44c90-1f61-4418-b9a6-56586bf38c79
+#vpe widget details
+AAI.model-invariant-id.vpe=053ec3a7-5b72-492d-b54d-123805a9b967
+AAI.model-version-id.vpe=203817d3-829c-42d4-942d-2a935478e993
+#vpls-pe widget details
+AAI.model-version-id.vpls-pe=b1566228-6785-4ce1-aea2-053736f80341
+AAI.model-invariant-id.vpls-pe=457ba89b-334c-4fbd-acc4-160ac0e0cdc0
+#vpn-binding widget details
+AAI.model-invariant-id.vpn-binding=9e23b675-db2b-488b-b459-57aa9857baa0
+AAI.model-version-id.vpn-binding=21a146e5-9901-448c-9197-723076770119
+#vserver widget details
+AAI.model-invariant-id.vserver=ff69d4e0-a8e8-4108-bdb0-dd63217e63c7
+AAI.model-version-id.vserver=8ecb2c5d-7176-4317-a255-26274edfdd53
\ No newline at end of file
diff --git a/src/test/resources/auth/auth_policy.json b/src/test/resources/auth/auth_policy.json
new file mode 100644 (file)
index 0000000..a0496b7
--- /dev/null
@@ -0,0 +1,55 @@
+{"roles": [
+    {
+        "name": "admin",
+        "functions": [
+            {
+                "name": "actions",
+                "methods": [
+                    {"name": "GET"},
+                    {"name": "DELETE"},
+                    {"name": "PUT"}
+                ]
+            },
+            {
+                "name": "getAndPublish",
+                "methods": [{"name": "POST"}]
+            }
+        ],
+        "users": [
+            {"username": "CN=common-name, OU=org-unit, O=org, L=location, ST=state, C=US"},
+            {"username": "CN=test, OU=qa, O=Test Ltd, L=London, ST=London, C=GB"}
+        ]
+    },
+    {
+        "name": "ops",
+        "functions": [{
+            "name": "actions",
+            "methods": [{"name": "POST"}]
+        }],
+        "users": [
+            {"username": "CN=common-name, OU=org-unit, O=org, L=location, ST=state, C=US"},
+            {"username": "CN=test, OU=qa, O=Test Ltd, L=London, ST=London, C=GB"}
+        ]
+    },
+    {
+        "name": "basicauth",
+        "functions": [{
+            "name": "util",
+            "methods": [{"name": "GET"}]
+        }],
+        "users": [{
+            "user": "aai",
+            "pass": "OBF:1u2a1t2v1vgb1s3g1s3m1vgj1t3b1u30"
+        }]
+    },
+    {
+        "name": "nofuncauth",
+        "functions": [{
+            "name": "nofuncutil"
+        }],        
+        "users": [{
+            "user": "aai",
+            "pass": "OBF:1u2a1t2v1vgb1s3g1s3m1vgj1t3b1u30"
+        }]
+    }    
+]}
diff --git a/src/test/resources/compressedArtifacts/noYmlFilesArchive.zip b/src/test/resources/compressedArtifacts/noYmlFilesArchive.zip
new file mode 100644 (file)
index 0000000..4fb37c2
Binary files /dev/null and b/src/test/resources/compressedArtifacts/noYmlFilesArchive.zip differ
diff --git a/src/test/resources/compressedArtifacts/service-SdWanServiceTest-csar.csar b/src/test/resources/compressedArtifacts/service-SdWanServiceTest-csar.csar
new file mode 100644 (file)
index 0000000..9d6132a
Binary files /dev/null and b/src/test/resources/compressedArtifacts/service-SdWanServiceTest-csar.csar differ
diff --git a/src/test/resources/generatedXml/AAI-SD-WAN-Service-Test-service-1.0.xml b/src/test/resources/generatedXml/AAI-SD-WAN-Service-Test-service-1.0.xml
new file mode 100644 (file)
index 0000000..7748998
--- /dev/null
@@ -0,0 +1,69 @@
+<model>
+    <model-invariant-id>1c111111-1111-1111-1111-111111111111</model-invariant-id>
+    <model-type>service</model-type>
+    <model-vers>
+        <model-ver>
+            <model-version-id>2c111111-1111-1111-1111-111111111111</model-version-id>
+            <model-name>SD-WAN-Service-Test</model-name>
+            <model-version>1.0</model-version>
+            <model-description>SD-WAN-Service-Test</model-description>
+            <model-elements>
+                <model-element>
+                    <new-data-del-flag>T</new-data-del-flag>
+                    <cardinality>unbounded</cardinality>
+                    <model-elements>
+                        <model-element>
+                            <new-data-del-flag>T</new-data-del-flag>
+                            <cardinality>unbounded</cardinality>
+                            <model-elements/>
+                            <relationship-list>
+                                <relationship>
+                                    <related-to>model-ver</related-to>
+                                    <relationship-data>
+                                        <relationship-key>model-ver.model-version-id</relationship-key>
+                                        <relationship-value>2a111111-1111-1111-1111-111111111111</relationship-value>
+                                    </relationship-data>
+                                    <relationship-data>
+                                        <relationship-key>model.model-invariant-id</relationship-key>
+                                        <relationship-value>1a111111-1111-1111-1111-111111111111</relationship-value>
+                                    </relationship-data>
+                                </relationship>
+                            </relationship-list>
+                        </model-element>
+                        <model-element>
+                            <new-data-del-flag>T</new-data-del-flag>
+                            <cardinality>unbounded</cardinality>
+                            <model-elements/>
+                            <relationship-list>
+                                <relationship>
+                                    <related-to>model-ver</related-to>
+                                    <relationship-data>
+                                        <relationship-key>model-ver.model-version-id</relationship-key>
+                                        <relationship-value>2b111111-1111-1111-1111-111111111111</relationship-value>
+                                    </relationship-data>
+                                    <relationship-data>
+                                        <relationship-key>model.model-invariant-id</relationship-key>
+                                        <relationship-value>1b111111-1111-1111-1111-111111111111</relationship-value>
+                                    </relationship-data>
+                                </relationship>
+                            </relationship-list>
+                        </model-element>
+                    </model-elements>
+                    <relationship-list>
+                        <relationship>
+                            <related-to>model-ver</related-to>
+                            <relationship-data>
+                                <relationship-key>model-ver.model-version-id</relationship-key>
+                                <relationship-value>46b92144-923a-4d20-b85a-3cbd847668a9</relationship-value>
+                            </relationship-data>
+                            <relationship-data>
+                                <relationship-key>model.model-invariant-id</relationship-key>
+                                <relationship-value>82194af1-3c2c-485a-8f44-420e22a9eaa4</relationship-value>
+                            </relationship-data>
+                        </relationship>
+                    </relationship-list>
+                </model-element>
+            </model-elements>
+        </model-ver>
+    </model-vers>
+</model>
diff --git a/src/test/resources/generatedXml/AAI-SD-WAN-Test-VSP-resource-1.0.xml b/src/test/resources/generatedXml/AAI-SD-WAN-Test-VSP-resource-1.0.xml
new file mode 100644 (file)
index 0000000..1cd85e8
--- /dev/null
@@ -0,0 +1,51 @@
+<model>
+    <model-invariant-id>1a111111-1111-1111-1111-111111111111</model-invariant-id>
+    <model-type>resource</model-type>
+    <model-vers>
+        <model-ver>
+            <model-version-id>2a111111-1111-1111-1111-111111111111</model-version-id>
+            <model-name>SD-WAN-Test-VSP</model-name>
+            <model-version>1.0</model-version>
+            <model-description>SD-WAN-Test-VSP</model-description>
+            <model-elements>
+                <model-element>
+                    <new-data-del-flag>T</new-data-del-flag>
+                    <cardinality>unbounded</cardinality>
+                    <model-elements>
+                        <model-element>
+                            <new-data-del-flag>T</new-data-del-flag>
+                            <cardinality>unbounded</cardinality>
+                            <model-elements/>
+                            <relationship-list>
+                                <relationship>
+                                    <related-to>model-ver</related-to>
+                                    <relationship-data>
+                                        <relationship-key>model-ver.model-version-id</relationship-key>
+                                        <relationship-value>7a111111-1111-1111-1111-111111111111</relationship-value>
+                                    </relationship-data>
+                                    <relationship-data>
+                                        <relationship-key>model.model-invariant-id</relationship-key>
+                                        <relationship-value>6a111111-1111-1111-1111-111111111111</relationship-value>
+                                    </relationship-data>
+                                </relationship>
+                            </relationship-list>
+                        </model-element>
+                    </model-elements>
+                    <relationship-list>
+                        <relationship>
+                            <related-to>model-ver</related-to>
+                            <relationship-data>
+                                <relationship-key>model-ver.model-version-id</relationship-key>
+                                <relationship-value>93a6166f-b3d5-4f06-b4ba-aed48d009ad9</relationship-value>
+                            </relationship-data>
+                            <relationship-data>
+                                <relationship-key>model.model-invariant-id</relationship-key>
+                                <relationship-value>acc6edd8-a8d4-4b93-afaa-0994068be14c</relationship-value>
+                            </relationship-data>
+                        </relationship>
+                    </relationship-list>
+                </model-element>
+            </model-elements>
+        </model-ver>
+    </model-vers>
+</model>
diff --git a/src/test/resources/generatedXml/AAI-SdWanTestVsp..DUMMY..module-0-resource-2.xml b/src/test/resources/generatedXml/AAI-SdWanTestVsp..DUMMY..module-0-resource-2.xml
new file mode 100644 (file)
index 0000000..6e221ce
--- /dev/null
@@ -0,0 +1,123 @@
+<model>
+    <model-invariant-id>6a111111-1111-1111-1111-111111111111</model-invariant-id>
+    <model-type>resource</model-type>
+    <model-vers>
+        <model-ver>
+            <model-version-id>7a111111-1111-1111-1111-111111111111</model-version-id>
+            <model-name>SdWanTestVsp..DUMMY..module-0</model-name>
+            <model-version>2</model-version>
+            <model-elements>
+                <model-element>
+                    <new-data-del-flag>T</new-data-del-flag>
+                    <cardinality>unbounded</cardinality>
+                    <model-elements>
+                        <model-element>
+                            <new-data-del-flag>T</new-data-del-flag>
+                            <cardinality>unbounded</cardinality>
+                            <model-elements>
+                                <model-element>
+                                    <new-data-del-flag>F</new-data-del-flag>
+                                    <cardinality>unbounded</cardinality>
+                                    <model-elements/>
+                                    <relationship-list>
+                                        <relationship>
+                                            <related-to>model-ver</related-to>
+                                            <relationship-data>
+                                                <relationship-key>model-ver.model-version-id</relationship-key>
+                                                <relationship-value>f6a038c2-820c-42ba-8c2b-375e24e8f932</relationship-value>
+                                            </relationship-data>
+                                            <relationship-data>
+                                                <relationship-key>model.model-invariant-id</relationship-key>
+                                                <relationship-value>3f4c7204-739b-4bbb-87a7-8a6856439c90</relationship-value>
+                                            </relationship-data>
+                                        </relationship>
+                                    </relationship-list>
+                                </model-element>
+                                <model-element>
+                                    <new-data-del-flag>F</new-data-del-flag>
+                                    <cardinality>unbounded</cardinality>
+                                    <model-elements/>
+                                    <relationship-list>
+                                        <relationship>
+                                            <related-to>model-ver</related-to>
+                                            <relationship-data>
+                                                <relationship-key>model-ver.model-version-id</relationship-key>
+                                                <relationship-value>abcc54bc-bb74-49dc-9043-7f7171707545</relationship-value>
+                                            </relationship-data>
+                                            <relationship-data>
+                                                <relationship-key>model.model-invariant-id</relationship-key>
+                                                <relationship-value>97c26c99-6870-44c1-8a07-1d900d3f4ce6</relationship-value>
+                                            </relationship-data>
+                                        </relationship>
+                                    </relationship-list>
+                                </model-element>
+                                <model-element>
+                                    <new-data-del-flag>F</new-data-del-flag>
+                                    <cardinality>unbounded</cardinality>
+                                    <model-elements/>
+                                    <relationship-list>
+                                        <relationship>
+                                            <related-to>model-ver</related-to>
+                                            <relationship-data>
+                                                <relationship-key>model-ver.model-version-id</relationship-key>
+                                                <relationship-value>36200fb5-f251-4f5d-a520-7c5ad5c2cd4b</relationship-value>
+                                            </relationship-data>
+                                            <relationship-data>
+                                                <relationship-key>model.model-invariant-id</relationship-key>
+                                                <relationship-value>bace8d1c-a261-4041-9e37-823117415d0f</relationship-value>
+                                            </relationship-data>
+                                        </relationship>
+                                    </relationship-list>
+                                </model-element>
+                                <model-element>
+                                    <new-data-del-flag>T</new-data-del-flag>
+                                    <cardinality>unbounded</cardinality>
+                                    <model-elements/>
+                                    <relationship-list>
+                                        <relationship>
+                                            <related-to>model-ver</related-to>
+                                            <relationship-data>
+                                                <relationship-key>model-ver.model-version-id</relationship-key>
+                                                <relationship-value>5761e0a7-c6df-4d8a-9ebd-b8f445054dec</relationship-value>
+                                            </relationship-data>
+                                            <relationship-data>
+                                                <relationship-key>model.model-invariant-id</relationship-key>
+                                                <relationship-value>96129eb9-f0de-4e05-8af2-73146473f766</relationship-value>
+                                            </relationship-data>
+                                        </relationship>
+                                    </relationship-list>
+                                </model-element>
+                            </model-elements>
+                            <relationship-list>
+                                <relationship>
+                                    <related-to>model-ver</related-to>
+                                    <relationship-data>
+                                        <relationship-key>model-ver.model-version-id</relationship-key>
+                                        <relationship-value>8ecb2c5d-7176-4317-a255-26274edfdd53</relationship-value>
+                                    </relationship-data>
+                                    <relationship-data>
+                                        <relationship-key>model.model-invariant-id</relationship-key>
+                                        <relationship-value>ff69d4e0-a8e8-4108-bdb0-dd63217e63c7</relationship-value>
+                                    </relationship-data>
+                                </relationship>
+                            </relationship-list>
+                        </model-element>
+                    </model-elements>
+                    <relationship-list>
+                        <relationship>
+                            <related-to>model-ver</related-to>
+                            <relationship-data>
+                                <relationship-key>model-ver.model-version-id</relationship-key>
+                                <relationship-value>c00563ae-812b-4e62-8330-7c4d0f47088a</relationship-value>
+                            </relationship-data>
+                            <relationship-data>
+                                <relationship-key>model.model-invariant-id</relationship-key>
+                                <relationship-value>ef86f9c5-2165-44f3-8fc3-96018b609ea5</relationship-value>
+                            </relationship-data>
+                        </relationship>
+                    </relationship-list>
+                </model-element>
+            </model-elements>
+        </model-ver>
+    </model-vers>
+</model>
diff --git a/src/test/resources/generatedXml/AAI-Tunnel_XConnTest-resource-2.0.xml b/src/test/resources/generatedXml/AAI-Tunnel_XConnTest-resource-2.0.xml
new file mode 100644 (file)
index 0000000..ccecc80
--- /dev/null
@@ -0,0 +1,69 @@
+<model>
+    <model-invariant-id>1b111111-1111-1111-1111-111111111111</model-invariant-id>
+    <model-type>resource</model-type>
+    <model-vers>
+        <model-ver>
+            <model-version-id>2b111111-1111-1111-1111-111111111111</model-version-id>
+            <model-name>Tunnel_XConnTest</model-name>
+            <model-version>2.0</model-version>
+            <model-description>Tunnel_XConnTest</model-description>
+            <model-elements>
+                <model-element>
+                    <new-data-del-flag>T</new-data-del-flag>
+                    <cardinality>unbounded</cardinality>
+                    <model-elements>
+                        <model-element>
+                            <new-data-del-flag>F</new-data-del-flag>
+                            <cardinality>unbounded</cardinality>
+                            <model-elements/>
+                            <relationship-list>
+                                <relationship>
+                                    <related-to>model-ver</related-to>
+                                    <relationship-data>
+                                        <relationship-key>model-ver.model-version-id</relationship-key>
+                                        <relationship-value>7b111111-1111-1111-1111-111111111111</relationship-value>
+                                    </relationship-data>
+                                    <relationship-data>
+                                        <relationship-key>model.model-invariant-id</relationship-key>
+                                        <relationship-value>6b111111-1111-1111-1111-111111111111</relationship-value>
+                                    </relationship-data>
+                                </relationship>
+                            </relationship-list>
+                        </model-element>
+                        <model-element>
+                            <new-data-del-flag>T</new-data-del-flag>
+                            <cardinality>unbounded</cardinality>
+                            <model-elements/>
+                            <relationship-list>
+                                <relationship>
+                                    <related-to>model-ver</related-to>
+                                    <relationship-data>
+                                        <relationship-key>model-ver.model-version-id</relationship-key>
+                                        <relationship-value>e7cb4ca8-e1a5-4487-a716-4ae0bcd8aef5</relationship-value>
+                                    </relationship-data>
+                                    <relationship-data>
+                                        <relationship-key>model.model-invariant-id</relationship-key>
+                                        <relationship-value>50b9e2fa-005c-4bbe-b651-3251dece4cd8</relationship-value>
+                                    </relationship-data>
+                                </relationship>
+                            </relationship-list>
+                        </model-element>
+                    </model-elements>
+                    <relationship-list>
+                        <relationship>
+                            <related-to>model-ver</related-to>
+                            <relationship-data>
+                                <relationship-key>model-ver.model-version-id</relationship-key>
+                                <relationship-value>7ad0915f-25c0-4a70-b9bc-185a75f87564</relationship-value>
+                            </relationship-data>
+                            <relationship-data>
+                                <relationship-key>model.model-invariant-id</relationship-key>
+                                <relationship-value>f6d6a23d-a1a9-48ff-8419-b6530da2d381</relationship-value>
+                            </relationship-data>
+                        </relationship>
+                    </relationship-list>
+                </model-element>
+            </model-elements>
+        </model-ver>
+    </model-vers>
+</model>
diff --git a/src/test/resources/jsonFiles/invalid_csar_request.json b/src/test/resources/jsonFiles/invalid_csar_request.json
new file mode 100644 (file)
index 0000000..3742f36
--- /dev/null
@@ -0,0 +1,3 @@
+{"csar": "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SVBfTXV4X0RlbXV4LXVwZGF0ZWQtcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEoPxTTMggIAAN4PAAA7AAAAAAAAAAAAAAAAADY3AABBcnRpZmFjdHMvQUFJLVR1bm5lbF9YQ29ubi1mb3ItREhWLVRlc3RpbmctcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEott6ixQgIAAEULAAA5AAAAAAAAAAAAAAAAACE6AABBcnRpZmFjdHMvQUFJLVNlcnZpY2VfQWRtaW4tZm9yLURIVi1UZXN0LXJlc291cmNlLTEuMC54bWxQSwECFAAUAAgICAD9roRKhVs/IKwDAABhJQAAQAAAAAAAAAAAAAAAAADKPAAAQXJ0aWZhY3RzL0FBSS1WaG5mRm9yRTJlVGVzdC4uYmFzZV9URVNULi5tb2R1bGUtMC1yZXNvdXJjZS0yLnhtbFBLAQIUABQACAgIAP2uhEpIeXXPNgIAADELAAAwAAAAAAAAAAAAAAAAAORAAABBcnRpZmFjdHMvQUFJLXZITkYtZm9yLURIVi1UZXN0LXJlc291cmNlLTIuMC54bWxQSwUGAAAAAAwADACcBAAAeEMAAAAA",
+ "artifactVersion":"1.0",
+ "artifactName":"hello"}
\ No newline at end of file
diff --git a/src/test/resources/jsonFiles/invalid_json_request.json b/src/test/resources/jsonFiles/invalid_json_request.json
new file mode 100644 (file)
index 0000000..4600202
--- /dev/null
@@ -0,0 +1,3 @@
+{"csar": "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QUktSVBfTXV4X0RlbXV4LXVwZGF0ZWQtcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEoPxTTMggIAAN4PAAA7AAAAAAAAAAAAAAAAADY3AABBcnRpZmFjdHMvQUFJLVR1bm5lbF9YQ29ubi1mb3ItREhWLVRlc3RpbmctcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEott6ixQgIAAEULAAA5AAAAAAAAAAAAAAAAACE6AABBcnRpZmFjdHMvQUFJLVNlcnZpY2VfQWRtaW4tZm9yLURIVi1UZXN0LXJlc291cmNlLTEuMC54bWxQSwECFAAUAAgICAD9roRKhVs/IKwDAABhJQAAQAAAAAAAAAAAAAAAAADKPAAAQXJ0aWZhY3RzL0FBSS1WaG5mRm9yRTJlVGVzdC4uYmFzZV9URVNULi5tb2R1bGUtMC1yZXNvdXJjZS0yLnhtbFBLAQIUABQACAgIAP2uhEpIeXXPNgIAADELAAAwAAAAAAAAAAAAAAAAAORAAABBcnRpZmFjdHMvQUFJLXZITkYtZm9yLURIVi1UZXN0LXJlc291cmNlLTIuMC54bWxQSwUGAAAAAAwADACcBAAAeEMAAAAA",
+ "artifactVersion":"1.0",
+ "artifactName":"hello"
\ No newline at end of file
diff --git a/src/test/resources/jsonFiles/missing_artifact_name_request.json b/src/test/resources/jsonFiles/missing_artifact_name_request.json
new file mode 100644 (file)
index 0000000..a5f4948
--- /dev/null
@@ -0,0 +1,3 @@
+{"csar": "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QUktSVBfTXV4X0RlbXV4LXVwZGF0ZWQtcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEoPxTTMggIAAN4PAAA7AAAAAAAAAAAAAAAAADY3AABBcnRpZmFjdHMvQUFJLVR1bm5lbF9YQ29ubi1mb3ItREhWLVRlc3RpbmctcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEott6ixQgIAAEULAAA5AAAAAAAAAAAAAAAAACE6AABBcnRpZmFjdHMvQUFJLVNlcnZpY2VfQWRtaW4tZm9yLURIVi1UZXN0LXJlc291cmNlLTEuMC54bWxQSwECFAAUAAgICAD9roRKhVs/IKwDAABhJQAAQAAAAAAAAAAAAAAAAADKPAAAQXJ0aWZhY3RzL0FBSS1WaG5mRm9yRTJlVGVzdC4uYmFzZV9URVNULi5tb2R1bGUtMC1yZXNvdXJjZS0yLnhtbFBLAQIUABQACAgIAP2uhEpIeXXPNgIAADELAAAwAAAAAAAAAAAAAAAAAORAAABBcnRpZmFjdHMvQUFJLXZITkYtZm9yLURIVi1UZXN0LXJlc291cmNlLTIuMC54bWxQSwUGAAAAAAwADACcBAAAeEMAAAAA",
+ "artifactVersion":"1.0"
+ }
\ No newline at end of file
diff --git a/src/test/resources/jsonFiles/missing_artifact_version_request.json b/src/test/resources/jsonFiles/missing_artifact_version_request.json
new file mode 100644 (file)
index 0000000..cfde298
--- /dev/null
@@ -0,0 +1,2 @@
+{"csar": "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QUktSVBfTXV4X0RlbXV4LXVwZGF0ZWQtcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEoPxTTMggIAAN4PAAA7AAAAAAAAAAAAAAAAADY3AABBcnRpZmFjdHMvQUFJLVR1bm5lbF9YQ29ubi1mb3ItREhWLVRlc3RpbmctcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEott6ixQgIAAEULAAA5AAAAAAAAAAAAAAAAACE6AABBcnRpZmFjdHMvQUFJLVNlcnZpY2VfQWRtaW4tZm9yLURIVi1UZXN0LXJlc291cmNlLTEuMC54bWxQSwECFAAUAAgICAD9roRKhVs/IKwDAABhJQAAQAAAAAAAAAAAAAAAAADKPAAAQXJ0aWZhY3RzL0FBSS1WaG5mRm9yRTJlVGVzdC4uYmFzZV9URVNULi5tb2R1bGUtMC1yZXNvdXJjZS0yLnhtbFBLAQIUABQACAgIAP2uhEpIeXXPNgIAADELAAAwAAAAAAAAAAAAAAAAAORAAABBcnRpZmFjdHMvQUFJLXZITkYtZm9yLURIVi1UZXN0LXJlc291cmNlLTIuMC54bWxQSwUGAAAAAAwADACcBAAAeEMAAAAA",
+ "artifactName":"hello"}
\ No newline at end of file
diff --git a/src/test/resources/jsonFiles/missing_csar_request.json b/src/test/resources/jsonFiles/missing_csar_request.json
new file mode 100644 (file)
index 0000000..e65eb4c
--- /dev/null
@@ -0,0 +1,2 @@
+{"artifactVersion":"1.0",
+ "artifactName":"hello"}
\ No newline at end of file
diff --git a/src/test/resources/jsonFiles/success_request.json b/src/test/resources/jsonFiles/success_request.json
new file mode 100644 (file)
index 0000000..92fa93d
--- /dev/null
@@ -0,0 +1,3 @@
+{"csar": "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QUktSVBfTXV4X0RlbXV4LXVwZGF0ZWQtcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEoPxTTMggIAAN4PAAA7AAAAAAAAAAAAAAAAADY3AABBcnRpZmFjdHMvQUFJLVR1bm5lbF9YQ29ubi1mb3ItREhWLVRlc3RpbmctcmVzb3VyY2UtMS4wLnhtbFBLAQIUABQACAgIAP2uhEott6ixQgIAAEULAAA5AAAAAAAAAAAAAAAAACE6AABBcnRpZmFjdHMvQUFJLVNlcnZpY2VfQWRtaW4tZm9yLURIVi1UZXN0LXJlc291cmNlLTEuMC54bWxQSwECFAAUAAgICAD9roRKhVs/IKwDAABhJQAAQAAAAAAAAAAAAAAAAADKPAAAQXJ0aWZhY3RzL0FBSS1WaG5mRm9yRTJlVGVzdC4uYmFzZV9URVNULi5tb2R1bGUtMC1yZXNvdXJjZS0yLnhtbFBLAQIUABQACAgIAP2uhEpIeXXPNgIAADELAAAwAAAAAAAAAAAAAAAAAORAAABBcnRpZmFjdHMvQUFJLXZITkYtZm9yLURIVi1UZXN0LXJlc291cmNlLTIuMC54bWxQSwUGAAAAAAwADACcBAAAeEMAAAAA",
+ "artifactVersion":"1.0",
+ "artifactName":"hello"}
\ No newline at end of file
diff --git a/src/test/resources/response/response.json b/src/test/resources/response/response.json
new file mode 100644 (file)
index 0000000..8b98d17
--- /dev/null
@@ -0,0 +1 @@
+[{"name":"AAI-SD-WAN Service for Testing-service-1.0.xml","type":"MODEL_INVENTORY_PROFILE","payload":[80,71,49,118,90,71,86,115,73,72,104,116,98,71,53,122,80,83,74,111,100,72,82,119,79,105,56,118,98,51,74,110,76,109,57,119,90,87,53,108,89,50,57,116,99,67,53,104,89,87,107,117,97,87,53,50,90,87,53,48,98,51,74,53,76,51,89,120,77,67,73,43,67,105,65,103,73,67,65,56,98,87,57,107,90,87,119,116,97,87,53,50,89,88,74,112,89,87,53,48,76,87,108,107,80,106,77,120,90,68,86,105,78,109,69,119,76,84,81,48,78,84,81,116,78,71,85,122,77,121,48,53,89,84,99,53,76,87,82,105,89,84,65,52,77,122,103,52,78,109,77,53,90,68,119,118,98,87,57,107,90,87,119,116,97,87,53,50,89,88,74,112,89,87,53,48,76,87,108,107,80,103,111,103,73,67,65,103,80,71,49,118,90,71,86,115,76,88,82,53,99,71,85,43,99,50,86,121,100,109,108,106,90,84,119,118,98,87,57,107,90,87,119,116,100,72,108,119,90,84,52,75,73,67,65,103,73,68,120,116,98,50,82,108,98,67,49,50,90,88,74,122,80,103,111,103,73,67,65,103,73,67,65,103,73,68,120,116,98,50,82,108,98,67,49,50,90,88,73,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,68,120,116,98,50,82,108,98,67,49,50,90,88,74,122,97,87,57,117,76,87,108,107,80,106,81,50,78,68,65,120,90,87,86,106,76,84,77,49,89,109,81,116,78,71,85,53,78,105,49,104,90,68,66,107,76,84,65,122,78,84,90,109,90,106,90,105,79,71,77,52,90,68,119,118,98,87,57,107,90,87,119,116,100,109,86,121,99,50,108,118,98,105,49,112,90,68,52,75,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,80,71,49,118,90,71,86,115,76,87,53,104,98,87,85,43,85,48,81,116,86,48,70,79,73,70,78,108,99,110,90,112,89,50,85,103,90,109,57,121,73,70,82,108,99,51,82,112,98,109,99,56,76,50,49,118,90,71,86,115,76,87,53,104,98,87,85,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,68,120,116,98,50,82,108,98,67,49,50,90,88,74,122,97,87,57,117,80,106,69,117,77,68,119,118,98,87,57,107,90,87,119,116,100,109,86,121,99,50,108,118,98,106,52,75,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,80,71,49,118,90,71,86,115,76,87,82,108,99,50,78,121,97,88,66,48,97,87,57,117,80,108,78,69,76,86,100,66,84,105,66,84,90,88,74,50,97,87,78,108,73,71,90,118,99,105,66,69,83,70,89,103,86,71,86,122,100,71,108,117,90,121,66,112,98,105,66,70,77,107,85,56,76,50,49,118,90,71,86,115,76,87,82,108,99,50,78,121,97,88,66,48,97,87,57,117,80,103,111,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,98,87,57,107,90,87,119,116,90,87,120,108,98,87,86,117,100,72,77,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,98,87,57,107,90,87,119,116,90,87,120,108,98,87,86,117,100,68,52,75,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,98,109,86,51,76,87,82,104,100,71,69,116,90,71,86,115,76,87,90,115,89,87,99,43,86,68,119,118,98,109,86,51,76,87,82,104,100,71,69,116,90,71,86,115,76,87,90,115,89,87,99,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,80,71,78,104,99,109,82,112,98,109,70,115,97,88,82,53,80,110,86,117,89,109,57,49,98,109,82,108,90,68,119,118,89,50,70,121,90,71,108,117,89,87,120,112,100,72,107,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,80,71,49,118,90,71,86,115,76,87,86,115,90,87,49,108,98,110,82,122,76,122,52,75,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,99,109,86,115,89,88,82,112,98,50,53,122,97,71,108,119,76,87,120,112,99,51,81,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,68,120,121,90,87,120,104,100,71,108,118,98,110,78,111,97,88,65,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,99,109,86,115,89,88,82,108,90,67,49,48,98,122,53,116,98,50,82,108,98,67,49,50,90,88,73,56,76,51,74,108,98,71,70,48,90,87,81,116,100,71,56,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,99,109,86,115,89,88,82,112,98,50,53,122,97,71,108,119,76,87,82,104,100,71,69,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,80,72,74,108,98,71,70,48,97,87,57,117,99,50,104,112,99,67,49,114,90,88,107,43,98,87,57,107,90,87,119,116,100,109,86,121,76,109,49,118,90,71,86,115,76,88,90,108,99,110,78,112,98,50,52,116,97,87,81,56,76,51,74,108,98,71,70,48,97,87,57,117,99,50,104,112,99,67,49,114,90,88,107,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,80,72,74,108,98,71,70,48,97,87,57,117,99,50,104,112,99,67,49,50,89,87,120,49,90,84,52,48,78,109,73,53,77,106,69,48,78,67,48,53,77,106,78,104,76,84,82,107,77,106,65,116,89,106,103,49,89,83,48,122,89,50,74,107,79,68,81,51,78,106,89,52,89,84,107,56,76,51,74,108,98,71,70,48,97,87,57,117,99,50,104,112,99,67,49,50,89,87,120,49,90,84,52,75,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,68,119,118,99,109,86,115,89,88,82,112,98,50,53,122,97,71,108,119,76,87,82,104,100,71,69,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,99,109,86,115,89,88,82,112,98,50,53,122,97,71,108,119,76,87,82,104,100,71,69,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,80,72,74,108,98,71,70,48,97,87,57,117,99,50,104,112,99,67,49,114,90,88,107,43,98,87,57,107,90,87,119,117,98,87,57,107,90,87,119,116,97,87,53,50,89,88,74,112,89,87,53,48,76,87,108,107,80,67,57,121,90,87,120,104,100,71,108,118,98,110,78,111,97,88,65,116,97,50,86,53,80,103,111,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,68,120,121,90,87,120,104,100,71,108,118,98,110,78,111,97,88,65,116,100,109,70,115,100,87,85,43,79,68,73,120,79,84,82,104,90,106,69,116,77,50,77,121,89,121,48,48,79,68,86,104,76,84,104,109,78,68,81,116,78,68,73,119,90,84,73,121,89,84,108,108,89,87,69,48,80,67,57,121,90,87,120,104,100,71,108,118,98,110,78,111,97,88,65,116,100,109,70,115,100,87,85,43,67,105,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,76,51,74,108,98,71,70,48,97,87,57,117,99,50,104,112,99,67,49,107,89,88,82,104,80,103,111,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,76,51,74,108,98,71,70,48,97,87,57,117,99,50,104,112,99,68,52,75,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,76,51,74,108,98,71,70,48,97,87,57,117,99,50,104,112,99,67,49,115,97,88,78,48,80,103,111,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,103,80,67,57,116,98,50,82,108,98,67,49,108,98,71,86,116,90,87,53,48,80,103,111,103,73,67,65,103,73,67,65,103,73,67,65,103,73,67,65,56,76,50,49,118,90,71,86,115,76,87,86,115,90,87,49,108,98,110,82,122,80,103,111,103,73,67,65,103,73,67,65,103,73,68,119,118,98,87,57,107,90,87,119,116,100,109,86,121,80,103,111,103,73,67,65,103,80,67,57,116,98,50,82,108,98,67,49,50,90,88,74,122,80,103,111,56,76,50,49,118,90,71,86,115,80,103,61,61]}]
\ No newline at end of file
diff --git a/src/test/resources/ymlFiles/resource-SdWanTestVsp-template.yml b/src/test/resources/ymlFiles/resource-SdWanTestVsp-template.yml
new file mode 100644 (file)
index 0000000..21e64fe
--- /dev/null
@@ -0,0 +1,314 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+metadata:
+  invariantUUID: 1a111111-1111-1111-1111-111111111111
+  UUID: 2a111111-1111-1111-1111-111111111111
+  name: SD-WAN-Test-VSP
+  description: SD-WAN-Test-VSP
+  type: VF
+  category: Network L2-3
+  subcategory: WAN Connectors
+  resourceVendor: SCP-Test-VLM
+  resourceVendorRelease: '1.0'
+imports:
+- nodes:
+    file: nodes.yml
+- datatypes:
+    file: data.yml
+- capabilities:
+    file: capabilities.yml
+- relationships:
+    file: relationships.yml
+- groups:
+    file: groups.yml
+- policies:
+    file: policies.yml
+- resource-SD-WAN-Test-VSP-interface:
+    file: resource-SdWanTestVsp-template-interface.yml
+- resource-SdWanTestVsp.nodes.DUMMY_server:
+    file: resource-SdwantestvspNodesDummyServer-template.yml
+topology_template:
+  inputs:
+    nf_naming:
+      type: org.openecomp.datatypes.Naming
+    nf_function:
+      type: string
+    nf_naming_code:
+      type: string
+    availability_zone_max_count:
+      type: integer
+      default: 1
+    max_instances:
+      type: integer
+    nf_type:
+      type: string
+    DUMMY_flavor_name:
+      type: string
+      description: flavor name of PCRF PD instance
+    DUMMY_image_name:
+      type: string
+      description: PCRF PD image name
+    DUMMY_Role_net_name:
+      type: string
+      description: DUMMY network name
+    DUMMY_server_name:
+      type: string
+      description: PCRF PD server name
+    nf_role:
+      type: string
+    min_instances:
+      type: integer
+    DUMMY_vnf_id:
+      type: string
+      description: PCRF VNF Id
+  node_templates:
+    abstract_DUMMY_server:
+      type: org.openecomp.resource.vfc.SdWanTestVsp.abstract.nodes.DUMMY_server
+      metadata:
+        invariantUUID: 3a111111-1111-1111-1111-111111111111
+        UUID: 4a111111-1111-1111-1111-111111111111
+        customizationUUID: 5a111111-1111-1111-1111-111111111111
+        version: '1.0'
+        name: SdWanTestVsp.nodes.DUMMY_server
+        description: Not reusable inner VFC
+        type: VFC
+        category: Generic
+        subcategory: Abstract
+        resourceVendor: SCP-Test-VLM
+        resourceVendorRelease: '1.0'
+      properties:
+        port_DUMMY_port_network:
+        - get_input: DUMMY_Role_net_name
+        index_value: 0
+        port_DUMMY_port_ip_requirements:
+        - - ip_version: 4
+            ip_count_required:
+              is_required: false
+            floating_ip_count_required:
+              is_required: false
+        vm_flavor_name:
+          get_input: DUMMY_flavor_name
+        service_template_filter:
+          substitute_service_template: Nested_DUMMY_serverServiceTemplate.yaml
+          count: '1'
+        port_DUMMY_port_network_role_tag:
+        - '"DUMMY_Role"'
+        vm_image_name:
+          get_input: DUMMY_image_name
+        vm_type_tag: DUMMY_server
+        min_instances: 0
+        compute_DUMMY_server_metadata:
+        - vnf_id:
+            get_input: DUMMY_vnf_id
+        port_DUMMY_port_mac_requirements:
+        - mac_count_required:
+            is_required: false
+        compute_DUMMY_server_name:
+        - get_input: DUMMY_server_name
+        nfc_naming_code: DUMMY_server
+  groups:
+    SdWanTestVsp..DUMMY..module-0:
+      type: org.openecomp.groups.VfModule
+      members:
+      - abstract_DUMMY_server
+      metadata:
+        vfModuleModelName: SdWanTestVsp..DUMMY..module-0
+        vfModuleModelInvariantUUID: 6a111111-1111-1111-1111-111111111111
+        vfModuleModelUUID: 7a111111-1111-1111-1111-111111111111
+        vfModuleModelVersion: '2'
+      properties:
+        min_vf_module_instances: 0
+        vf_module_label: DUMMY
+        max_vf_module_instances:
+        vfc_list:
+        vf_module_type: Expansion
+        vf_module_description:
+        initial_count: 0
+        volume_group: false
+        availability_zone_count:
+    DUMMY_group:
+      type: org.openecomp.groups.heat.HeatStack
+      members:
+      - abstract_DUMMY_server
+      metadata:
+        invariantUUID: 8a111111-1111-1111-1111-111111111111
+        UUID: 9a111111-1111-1111-1111-111111111111
+        version: '1'
+        name: DUMMY_group
+  substitution_mappings:
+    node_type: org.openecomp.resource.vf.SdWanTestVsp
+    capabilities:
+      abstract_dummy_server.instance_DUMMY_server:
+      - abstract_DUMMY_server
+      - instance_DUMMY_server
+      abstract_dummy_server.disk.device.write.bytes_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.write.bytes_DUMMY_server
+      abstract_dummy_server.disk.device.capacity_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.capacity_DUMMY_server
+      abstract_dummy_server.network.outgoing.bytes_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - network.outgoing.bytes_DUMMY_server_DUMMY_port
+      abstract_dummy_server.os_DUMMY_server:
+      - abstract_DUMMY_server
+      - os_DUMMY_server
+      abstract_dummy_server.host_DUMMY_server:
+      - abstract_DUMMY_server
+      - host_DUMMY_server
+      abstract_dummy_server.memory_DUMMY_server:
+      - abstract_DUMMY_server
+      - memory_DUMMY_server
+      abstract_dummy_server.disk.read.requests_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.read.requests_DUMMY_server
+      abstract_dummy_server.feature_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - feature_DUMMY_server_DUMMY_port
+      abstract_dummy_server.disk.device.write.requests.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.write.requests.rate_DUMMY_server
+      abstract_dummy_server.disk.ephemeral.size_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.ephemeral.size_DUMMY_server
+      abstract_dummy_server.disk.allocation_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.allocation_DUMMY_server
+      abstract_dummy_server.feature:
+      - abstract_DUMMY_server
+      - feature
+      abstract_dummy_server.scalable_DUMMY_server:
+      - abstract_DUMMY_server
+      - scalable_DUMMY_server
+      abstract_dummy_server.network.incoming.packets.rate_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - network.incoming.packets.rate_DUMMY_server_DUMMY_port
+      abstract_dummy_server.binding_DUMMY_server:
+      - abstract_DUMMY_server
+      - binding_DUMMY_server
+      abstract_dummy_server.disk.iops_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.iops_DUMMY_server
+      abstract_dummy_server.network.incoming.bytes_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - network.incoming.bytes_DUMMY_server_DUMMY_port
+      abstract_dummy_server.disk.read.bytes_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.read.bytes_DUMMY_server
+      abstract_dummy_server.disk.write.bytes_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.write.bytes_DUMMY_server
+      abstract_dummy_server.cpu.delta_DUMMY_server:
+      - abstract_DUMMY_server
+      - cpu.delta_DUMMY_server
+      abstract_dummy_server.disk.capacity_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.capacity_DUMMY_server
+      abstract_dummy_server.network.incoming.packets_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - network.incoming.packets_DUMMY_server_DUMMY_port
+      abstract_dummy_server.cpu_DUMMY_server:
+      - abstract_DUMMY_server
+      - cpu_DUMMY_server
+      abstract_dummy_server.memory.resident_DUMMY_server:
+      - abstract_DUMMY_server
+      - memory.resident_DUMMY_server
+      abstract_dummy_server.disk.device.read.bytes_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.read.bytes_DUMMY_server
+      abstract_dummy_server.disk.device.write.bytes.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.write.bytes.rate_DUMMY_server
+      abstract_dummy_server.disk.usage_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.usage_DUMMY_server
+      abstract_dummy_server.disk.write.requests_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.write.requests_DUMMY_server
+      abstract_dummy_server.endpoint_DUMMY_server:
+      - abstract_DUMMY_server
+      - endpoint_DUMMY_server
+      abstract_dummy_server.memory.usage_DUMMY_server:
+      - abstract_DUMMY_server
+      - memory.usage_DUMMY_server
+      abstract_dummy_server.disk.latency_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.latency_DUMMY_server
+      abstract_dummy_server.disk.write.requests.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.write.requests.rate_DUMMY_server
+      abstract_dummy_server.disk.device.allocation_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.allocation_DUMMY_server
+      abstract_dummy_server.disk.device.read.requests.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.read.requests.rate_DUMMY_server
+      abstract_dummy_server.disk.device.read.bytes.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.read.bytes.rate_DUMMY_server
+      abstract_dummy_server.disk.device.usage_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.usage_DUMMY_server
+      abstract_dummy_server.disk.device.write.requests_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.write.requests_DUMMY_server
+      abstract_dummy_server.vcpus_DUMMY_server:
+      - abstract_DUMMY_server
+      - vcpus_DUMMY_server
+      abstract_dummy_server.disk.write.bytes.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.write.bytes.rate_DUMMY_server
+      abstract_dummy_server.network.outgoing.bytes.rate_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - network.outgoing.bytes.rate_DUMMY_server_DUMMY_port
+      abstract_dummy_server.network.outpoing.packets_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - network.outpoing.packets_DUMMY_server_DUMMY_port
+      abstract_dummy_server.network.outgoing.packets.rate_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - network.outgoing.packets.rate_DUMMY_server_DUMMY_port
+      abstract_dummy_server.binding_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - binding_DUMMY_server_DUMMY_port
+      abstract_dummy_server.cpu_util_DUMMY_server:
+      - abstract_DUMMY_server
+      - cpu_util_DUMMY_server
+      abstract_dummy_server.attachment_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - attachment_DUMMY_server_DUMMY_port
+      abstract_dummy_server.disk.device.latency_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.latency_DUMMY_server
+      abstract_dummy_server.disk.root.size_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.root.size_DUMMY_server
+      abstract_dummy_server.disk.device.iops_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.iops_DUMMY_server
+      abstract_dummy_server.disk.read.bytes.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.read.bytes.rate_DUMMY_server
+      abstract_dummy_server.feature_DUMMY_server:
+      - abstract_DUMMY_server
+      - feature_DUMMY_server
+      abstract_dummy_server.disk.device.read.requests_DUMMY_server:
+      - abstract_DUMMY_server
+      - disk.device.read.requests_DUMMY_server
+      abstract_dummy_server.network.incoming.bytes.rate_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - network.incoming.bytes.rate_DUMMY_server_DUMMY_port
+    requirements:
+      abstract_dummy_server.local_storage_DUMMY_server:
+      - abstract_DUMMY_server
+      - local_storage_DUMMY_server
+      abstract_dummy_server.dependency_DUMMY_server:
+      - abstract_DUMMY_server
+      - dependency_DUMMY_server
+      abstract_dummy_server.link_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - link_DUMMY_server_DUMMY_port
+      abstract_dummy_server.dependency_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - dependency_DUMMY_server_DUMMY_port
+      abstract_dummy_server.dependency:
+      - abstract_DUMMY_server
+      - dependency
diff --git a/src/test/resources/ymlFiles/resource-TunnelXconntest-template.yml b/src/test/resources/ymlFiles/resource-TunnelXconntest-template.yml
new file mode 100644 (file)
index 0000000..6179976
--- /dev/null
@@ -0,0 +1,81 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+metadata:
+  invariantUUID: 1b111111-1111-1111-1111-111111111111
+  UUID: 2b111111-1111-1111-1111-111111111111
+  name: Tunnel_XConnTest
+  description: Tunnel_XConnTest
+  type: VF
+  category: Allotted Resource
+  subcategory: Tunnel XConnect
+  resourceVendor: '12345'
+  resourceVendorRelease: '1'
+imports:
+- nodes:
+    file: nodes.yml
+- datatypes:
+    file: data.yml
+- capabilities:
+    file: capabilities.yml
+- relationships:
+    file: relationships.yml
+- groups:
+    file: groups.yml
+- policies:
+    file: policies.yml
+- resource-Tunnel_XConnTest-interface:
+    file: resource-TunnelXconntest-template-interface.yml
+- resource-Allotedresource:
+    file: resource-Allotedresource-template.yml
+topology_template:
+  inputs:
+    nf_naming:
+      type: org.openecomp.datatypes.Naming
+    nf_naming_code:
+      type: string
+    nf_function:
+      type: string
+    availability_zone_max_count:
+      type: integer
+      default: 1
+    nf_role:
+      type: string
+    max_instances:
+      type: integer
+    min_instances:
+      type: integer
+    nf_type:
+      type: string
+  node_templates:
+    Allotedresource 0:
+      type: org.openecomp.resource.vfc.AllottedResource1235
+      metadata:
+        invariantUUID: 3b111111-1111-1111-1111-111111111111
+        UUID: 4b111111-1111-1111-1111-111111111111
+        customizationUUID: 5b111111-1111-1111-1111-111111111111
+        version: '1.0'
+        name: Allotedresource
+        description: Allotedresource
+        type: VFC
+        category: Allotted Resource
+        subcategory: Allotted Resource
+        resourceVendor: '123'
+        resourceVendorRelease: '123'
+      properties:
+        providing_service_invariant_uuid: 6b111111-1111-1111-1111-111111111111
+        providing_service_uuid: 7b111111-1111-1111-1111-111111111111
+        providing_service_name: vVIGaaS-Test
+        max_instances: 1
+        min_instances: 1
+  substitution_mappings:
+    node_type: org.openecomp.resource.vf.TunnelXconntest
+    capabilities:
+      allotedresource0.feature:
+      - Allotedresource 0
+      - feature
+    requirements:
+      allotedresource0.service_dependency:
+      - Allotedresource 0
+      - service_dependency
+      allotedresource0.dependency:
+      - Allotedresource 0
+      - dependency
diff --git a/src/test/resources/ymlFiles/service-SdWanServiceTest-template.yml b/src/test/resources/ymlFiles/service-SdWanServiceTest-template.yml
new file mode 100644 (file)
index 0000000..0d3494a
--- /dev/null
@@ -0,0 +1,270 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+metadata:
+  invariantUUID: 1c111111-1111-1111-1111-111111111111
+  UUID: 2c111111-1111-1111-1111-111111111111
+  name: SD-WAN-Service-Test
+  description: SD-WAN-Service-Test
+  type: Service
+  category: Network L1-3
+  serviceEcompNaming: true
+  ecompGeneratedNaming: true
+  namingPolicy: ''
+imports:
+- nodes:
+    file: nodes.yml
+- datatypes:
+    file: data.yml
+- capabilities:
+    file: capabilities.yml
+- relationships:
+    file: relationships.yml
+- groups:
+    file: groups.yml
+- policies:
+    file: policies.yml
+- service-SD-WAN-Service-Test-interface:
+    file: service-SdWanServiceTest-template-interface.yml
+- resource-SD-WAN-Test-VSP:
+    file: resource-SdWanTestVsp-template.yml
+- resource-SD-WAN-Test-VSP-interface:
+    file: resource-SdWanTestVsp-template-interface.yml
+- resource-Tunnel_XConnTest:
+    file: resource-TunnelXconntest-template.yml
+- resource-Tunnel_XConnTest-interface:
+    file: resource-TunnelXconntest-template-interface.yml
+topology_template:
+  node_templates:
+    SD-WAN-Test-VSP 0:
+      type: org.openecomp.resource.vf.SdWanTestVsp
+      metadata:
+        invariantUUID: 1a111111-1111-1111-1111-111111111111
+        UUID: 2a111111-1111-1111-1111-111111111111
+        customizationUUID: 3c111111-1111-1111-1111-111111111111
+        version: '1.0'
+        name: SD-WAN-Test-VSP
+        description: SD-WAN-Test-VSP
+        type: VF
+        category: Network L2-3
+        subcategory: WAN Connectors
+        resourceVendor: SCP-Test-VLM
+        resourceVendorRelease: '1.0'
+    Tunnel_XConnTest 0:
+      type: org.openecomp.resource.vf.TunnelXconntest
+      metadata:
+        invariantUUID: 1b111111-1111-1111-1111-111111111111
+        UUID: 2b111111-1111-1111-1111-111111111111
+        customizationUUID: 4c111111-1111-1111-1111-111111111111
+        version: '2.0'
+        name: Tunnel_XConnTest
+        description: Tunnel_XConnTest
+        type: VF
+        category: Allotted Resource
+        subcategory: Tunnel XConnect
+        resourceVendor: '12345'
+        resourceVendorRelease: '1'
+  groups:
+    sdwantestvsp0..SdWanTestVsp..DUMMY..module-0:
+      type: org.openecomp.groups.VfModule
+      metadata:
+        vfModuleModelName: SdWanTestVsp..DUMMY..module-0
+        vfModuleModelInvariantUUID: 6a111111-1111-1111-1111-111111111111
+        vfModuleModelUUID: 5c111111-1111-1111-1111-111111111111
+        vfModuleModelVersion: '2'
+        vfModuleModelCustomizationUUID: 6c111111-1111-1111-1111-111111111111
+      properties:
+        min_vf_module_instances: 0
+        vf_module_label: DUMMY
+        max_vf_module_instances:
+        vfc_list:
+        vf_module_type: Expansion
+        vf_module_description:
+        initial_count: 0
+        volume_group: false
+        availability_zone_count:
+  substitution_mappings:
+    node_type: org.openecomp.service.SdWanServiceTest
+    capabilities:
+      sdwantestvsp0.abstract_dummy_server.attachment_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.attachment_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.memory.resident_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.memory.resident_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.instance_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.instance_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.root.size_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.root.size_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.feature_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.feature_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.device.write.requests.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.write.requests.rate_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.network.outpoing.packets_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.network.outpoing.packets_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.network.outgoing.packets.rate_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.network.outgoing.packets.rate_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.disk.device.allocation_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.allocation_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.read.bytes_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.read.bytes_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.read.bytes.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.read.bytes.rate_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.device.usage_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.usage_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.network.outgoing.bytes_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.network.outgoing.bytes_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.disk.device.write.bytes_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.write.bytes_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.host_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.host_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.write.requests.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.write.requests.rate_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.binding_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.binding_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.device.latency_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.latency_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.write.bytes_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.write.bytes_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.os_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.os_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.network.incoming.bytes_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.network.incoming.bytes_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.disk.device.read.bytes.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.read.bytes.rate_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.write.requests_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.write.requests_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.vcpus_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.vcpus_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.ephemeral.size_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.ephemeral.size_DUMMY_server
+      tunnel_xconntest0.allotedresource0.feature:
+      - Allotedresource 0
+      - allotedresource0.feature
+      sdwantestvsp0.abstract_dummy_server.disk.device.read.requests_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.read.requests_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.binding_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.binding_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.disk.device.read.requests.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.read.requests.rate_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.memory.usage_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.memory.usage_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.feature:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.feature
+      sdwantestvsp0.abstract_dummy_server.disk.device.write.bytes.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.write.bytes.rate_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.latency_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.latency_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.memory_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.memory_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.usage_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.usage_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.device.write.requests_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.write.requests_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.scalable_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.scalable_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.cpu_util_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.cpu_util_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.capacity_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.capacity_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.network.incoming.packets_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.network.incoming.packets_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.cpu.delta_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.cpu.delta_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.iops_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.iops_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.allocation_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.allocation_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.device.read.bytes_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.read.bytes_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.cpu_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.cpu_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.network.outgoing.bytes.rate_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.network.outgoing.bytes.rate_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.disk.read.requests_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.read.requests_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.network.incoming.packets.rate_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.network.incoming.packets.rate_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.network.incoming.bytes.rate_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.network.incoming.bytes.rate_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.feature_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.feature_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.disk.device.iops_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.iops_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.device.capacity_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.device.capacity_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.disk.write.bytes.rate_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.disk.write.bytes.rate_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.endpoint_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.endpoint_DUMMY_server
+    requirements:
+      sdwantestvsp0.abstract_dummy_server.dependency_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.dependency_DUMMY_server
+      tunnel_xconntest0.allotedresource0.service_dependency:
+      - Allotedresource 0
+      - allotedresource0.service_dependency
+      tunnel_xconntest0.allotedresource0.dependency:
+      - Allotedresource 0
+      - allotedresource0.dependency
+      sdwantestvsp0.abstract_dummy_server.dependency_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.dependency_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.link_DUMMY_server_DUMMY_port:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.link_DUMMY_server_DUMMY_port
+      sdwantestvsp0.abstract_dummy_server.local_storage_DUMMY_server:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.local_storage_DUMMY_server
+      sdwantestvsp0.abstract_dummy_server.dependency:
+      - abstract_DUMMY_server
+      - abstract_dummy_server.dependency