Initial OpenECOMP sdc-distribution-client commit 87/387/1
authorMichael Lando <ml636r@att.com>
Wed, 15 Feb 2017 14:02:49 +0000 (16:02 +0200)
committerMichael Lando <ml636r@att.com>
Wed, 15 Feb 2017 14:03:20 +0000 (16:03 +0200)
Change-Id: I6dd20cdaf36d22836db1e9b6956c90652b6a38d7
Signed-off-by: Michael Lando <ml636r@att.com>
58 files changed:
.gitignore [new file with mode: 0644]
.gitreview [new file with mode: 0644]
LICENSE.TXT [new file with mode: 0644]
README.md [new file with mode: 0644]
pom.xml [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/IDistributionClient.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/IDistributionStatusMessageJsonBuilder.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/asdc/RegistrationRequest.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/asdc/ServerListResponse.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/consumer/IConfiguration.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/consumer/IDistributionStatusMessage.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/consumer/INotificationCallback.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/notification/IArtifactInfo.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/notification/INotificationData.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/notification/IResourceInstance.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/notification/IVfModuleMetadata.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/results/IDistributionClientDownloadResult.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/api/results/IDistributionClientResult.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/http/AsdcConnectorClient.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/http/AsdcUrls.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/http/HttpAsdcClient.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/http/HttpAsdcResponse.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/http/IHttpAsdcClient.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/http/TopicRegistrationResponse.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/ArtifactInfoImpl.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/Configuration.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/DistributionClientDownloadResultImpl.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/DistributionClientFactory.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/DistributionClientImpl.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/DistributionClientResultImpl.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/DistributionStatusMessageImpl.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/DistributionStatusMessageJsonBuilderFactory.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/JsonContainerResourceInstance.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/NotificationConsumer.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/NotificationDataImpl.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/VfModuleMetadata.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/mock/DistributionClientDownloadResultStubImpl.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/mock/DistributionClientResultStubImpl.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/impl/mock/DistributionClientStubImpl.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/ArtifactTypeEnum.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/DistributionActionResultEnum.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/DistributionClientConstants.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/DistributionStatusEnum.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/GeneralUtils.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/Pair.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/Wrapper.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/YamlToObjectConverter.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/heat/HeatConfiguration.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/heat/HeatParameter.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/heat/HeatParameterConstraint.java [new file with mode: 0644]
src/main/java/org/openecomp/sdc/utils/heat/HeatParser.java [new file with mode: 0644]
src/test/java/org/openecomp/sdc/impl/DistributionClientTest.java [new file with mode: 0644]
src/test/java/org/openecomp/sdc/impl/HeatParserTest.java [new file with mode: 0644]
src/test/java/org/openecomp/sdc/impl/NotificationConsumerTest.java [new file with mode: 0644]
src/test/java/org/openecomp/sdc/utils/ArtifactsUtils.java [new file with mode: 0644]
src/test/java/org/openecomp/sdc/utils/TestConfiguration.java [new file with mode: 0644]
src/test/java/org/openecomp/sdc/utils/TestNotificationCallback.java [new file with mode: 0644]
src/test/resources/heatExample.yaml [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..1b6d5d3
--- /dev/null
@@ -0,0 +1,17 @@
+# Eclipse
+.classpath
+.project
+.settings/
+
+# Maven
+log/
+target/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# Other
+*.class
+*.orig
\ No newline at end of file
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..c8c7a5e
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.openecomp.org
+port=29418
+project=sdc/sdc-distribution-client.git
\ No newline at end of file
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644 (file)
index 0000000..3d6f0e2
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+* ============LICENSE_START==========================================
+* ===================================================================
+* Copyright © 2017 AT&T Intellectual Property.
+* All rights reserved.
+* ===================================================================
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*        http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ============LICENSE_END============================================
+*
+* ECOMP and OpenECOMP are trademarks
+* and service marks of AT&T Intellectual Property.
+*
+*/
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..1a5699d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,144 @@
+# OpenECOMP SDC Distribution client
+
+---
+---
+
+# Introduction
+
+OpenECOMP SDC Distribution client is delivered as helper JAR that can be used by clients that work with SDC.
+It register to SDC for getting notifications, listen for notification from SDC, download artifacts from SDC, and send respone back to SDC.
+
+
+# Compiling OpenECOMP SDC Distribution client
+
+OpenECOMP SDC Distribution client can be compiled easily using maven command: `mvn clean install`
+The result is JAR file under "target" folder
+
+
+### How to use OpenECOMP SDC Distribution client
+Every client that wants to use the JAR, need to implement IConfiguration interface.
+
+Configuration parameters:
+--------------------------
+AsdcAddress                    : ASDC Distribution Engine address. Value can be either hostname (with or without port), IP:port or FQDN (Fully Qualified Domain Name).
+User                                   : User Name for ASDC distribution consumer authentication.
+Password                               : User Password for ASDC distribution consumer authentication.
+PollingInterval                        : Distribution Client Polling Interval towards UEB in seconds. Can Be reconfigured in runtime.
+PollingTimeout                 : Distribution Client Timeout in seconds waiting to UEB server response in each fetch interval. Can Be reconfigured in runtime.
+RelevantArtifactTypes  : List of artifact types. If the service contains any of the artifacts in the list, the callback will be activated. Can Be reconfigured in runtime.
+ConsumerGroup                  : Returns the consumer group defined for this ECOMP component, if no consumer group is defined return null. 
+EnvironmentName                        : Returns the environment name (testing, production etc... Can Be reconfigured in runtime.
+ConsumerID                             : Unique ID of ECOMP component instance (e.x INSTAR name).
+KeyStorePath                   : Return full path to Client's Key Store that contains either CA certificate or the ASDC's public key (e.g /etc/keystore/asdc-client.jks). file will be deployed with asdc-distribution jar
+KeyStorePassword               : Return client's Key Store password.
+activateServerTLSAuth  : Sets whether ASDC server TLS authentication is activated. If set to false, Key Store path and password are not needed to be set.
+
+Example of configuration file implementing IConfiguration interface:
+--------------------------------------------------------------------
+package org.openecomp.conf;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openecomp.asdc.api.consumer.IConfiguration;
+import org.openecomp.asdc.utils.ArtifactTypeEnum;
+
+public class SimpleConfiguration implements IConfiguration{
+       int randomSeed;
+       String asdcAddress;
+       
+       public SimpleConfiguration(){
+               randomSeed = ((int)(Math.random()*1000));
+               asdcAddress = "127.0.0.1:8443";
+       }
+       public String getUser() {
+               return "ci";
+       }
+       
+       public List<String> getRelevantArtifactTypes() {
+               List<String> res = new ArrayList<>();
+               for(ArtifactTypeEnum artifactTypeEnum : ArtifactTypeEnum.values()){
+                       res.add(artifactTypeEnum.name());
+               }
+               return res;
+       }
+       
+       public int getPollingTimeout() {
+               return 20;
+       }
+       
+       public int getPollingInterval() {
+               return 20;
+       }
+       
+       public String getPassword() {
+               return "123456";
+       }
+       
+       public String getEnvironmentName() {
+               return "PROD";
+       }
+       
+       public String getConsumerID() {
+               return "unique-Consumer-ID"+randomSeed;
+       }
+       
+       public String getConsumerGroup() {
+               return "unique-Consumer-Group"+randomSeed;
+       }
+       
+       public String getAsdcAddress() {
+               return asdcAddress;
+       }
+       
+       public void setAsdcAddress(String asdcAddress) {
+               this.asdcAddress = asdcAddress;
+       }
+       @Override
+       public String getKeyStorePath() {
+               return null;
+       }
+       @Override
+       public String getKeyStorePassword() {
+               return null;
+       }
+       @Override
+       public boolean activateServerTLSAuth() {
+               return false;
+       }
+
+}
+
+
+# Logging
+Loggin can be done using log4j
+Example of log.properties file:
+-------------------------------
+log4j.rootCategory=DEBUG, CONSOLE, LOGFILE
+log4j.logger.org.openecomp=TRACE, CONSOLE, LOGFILE
+
+# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%p %d{yyyy-MM-dd HH:mm:ss.SSS Z} %c{1} - %m%n
+# LOGFILE is set to be a File appender using a PatternLayout.
+log4j.appender.LOGFILE=org.apache.log4j.RollingFileAppender
+log4j.appender.LOGFILE.File=logs/wordnik.log
+log4j.appender.LOGFILE.Append=true
+log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.LOGFILE.layout.ConversionPattern=%p %d{yyyy-MM-dd HH:mm:ss.SSS Z} %c{1} - %m%n
+log4j.appender.LOGFILE.MaxFileSize=10MB
+log4j.appender.LOGFILE.MaxBackupIndex=10
+
+
+# Getting Help
+
+*** to be completed on release ***
+
+SDC@lists.openecomp.org
+
+SDC Javadoc and Maven site
+*** to be completed on rrelease ***
+
diff --git a/pom.xml b/pom.xml
new file mode 100644 (file)
index 0000000..fc0eec0
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,277 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <groupId>org.openecomp.sdc</groupId>
+       <artifactId>sdc-distribution-client</artifactId>
+       <version>1.0.0-SNAPSHOT</version>
+       <name>SDC Distribution Client</name>
+       <description>An SDC Client to be used by its consumers</description>
+       <properties> 
+               <httpclient.version>4.5</httpclient.version>
+               <httpcore.version>4.4.1</httpcore.version>
+               <snakeyaml.version>1.14</snakeyaml.version>
+               <sonar.login>sonaruser</sonar.login>
+               <sonar.password>us7USi0Htu93nFY91DPuQLFo6ebKcKXv</sonar.password>
+               <sonar.host.url>http://104.239.145.8:9000</sonar.host.url>
+               <sonar.skipDesign>true</sonar.skipDesign>
+               <sonar.projectBaseDir>${project.basedir}</sonar.projectBaseDir>
+               <sonar.jacoco.reportPath>${project.basedir}/target/jacoco.exec</sonar.jacoco.reportPath>
+       </properties>
+
+       <reporting>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-javadoc-plugin</artifactId>
+                               <version>2.10.4</version>
+                               <configuration>
+                                       <failOnError>false</failOnError>
+                                       <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
+                                       <docletArtifact>
+                                               <groupId>org.umlgraph</groupId>
+                                               <artifactId>umlgraph</artifactId>
+                                               <version>5.6</version>
+                                       </docletArtifact>
+                                       <additionalparam>-views</additionalparam>
+                                       <useStandardDocletOptions>true</useStandardDocletOptions>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </reporting>
+
+
+       <dependencies>
+               <dependency>
+                       <groupId>com.att.nsa</groupId>
+                       <artifactId>saClientLibrary</artifactId>
+                       <version>0.0.1</version>
+                       <scope>compile</scope>
+                       <exclusions>
+                               <exclusion>  <!-- declare the exclusion here -->
+                                       <groupId>org.slf4j</groupId>
+                                       <artifactId>slf4j-log4j12</artifactId>
+                               </exclusion>
+                       </exclusions> 
+               </dependency>
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>slf4j-api</artifactId>
+                       <version>1.7.10</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.att.nsa</groupId>
+                       <artifactId>cambriaClient</artifactId>
+                       <version>0.0.1</version>
+                       <scope>compile</scope>
+               </dependency>
+               
+               <dependency>
+                       <groupId>com.google.code.gson</groupId>
+                       <artifactId>gson</artifactId>
+                       <version>2.3.1</version>
+                       <scope>compile</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.functionaljava</groupId>
+                       <artifactId>functionaljava</artifactId>
+                       <version>4.2</version>
+                       <scope>compile</scope>
+               </dependency>
+               <dependency>
+                       <groupId>commons-io</groupId>
+                       <artifactId>commons-io</artifactId>
+                       <version>2.5</version>
+               </dependency>
+               <dependency>
+                       <groupId>commons-codec</groupId>
+                       <artifactId>commons-codec</artifactId>  
+                       <version>1.9</version>
+                       <scope>compile</scope>
+               </dependency>
+               <!-- http client -->
+               <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpclient</artifactId>
+                       <version>${httpclient.version}</version>
+                       <scope>compile</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpmime</artifactId>
+                       <version>${httpclient.version}</version>
+                       <scope>compile</scope>
+               </dependency>
+
+               <!-- YAML parser -->
+               <dependency>
+                       <groupId>org.yaml</groupId>
+                       <artifactId>snakeyaml</artifactId>
+                       <version>${snakeyaml.version}</version>
+                       <scope>compile</scope>
+               </dependency>
+
+               <!-- http core -->
+               <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpcore</artifactId>
+                       <version>${httpcore.version}</version>
+                       <scope>compile</scope>
+               </dependency>
+               
+               <!-- TEST -->
+               <dependency>
+                       <groupId>org.eclipse.jetty</groupId>
+                       <artifactId>jetty-servlet</artifactId>
+                       <scope>test</scope>
+                       <version>9.2.10.v20150310</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.eclipse.jetty</groupId>
+                       <artifactId>jetty-webapp</artifactId>
+                       <version>9.2.10.v20150310</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>4.12</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-all</artifactId>
+                       <version>1.10.19</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.google.guava</groupId>
+                       <artifactId>guava</artifactId>
+                       <version>15.0</version>
+                       <scope>test</scope>
+               </dependency>
+       </dependencies>
+
+       <!-- ================================================== -->
+       <!-- Set the JDK compiler version. -->
+       <!-- ================================================== -->
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-site-plugin</artifactId>
+                               <version>3.4</version>
+                               <dependencies>
+                                       <dependency>
+                                               <groupId>org.apache.maven.wagon</groupId>
+                                               <artifactId>wagon-webdav-jackrabbit</artifactId>
+                                               <version>2.10</version>
+                                       </dependency>
+                               </dependencies>
+                       </plugin>
+
+                       <plugin>
+                               <groupId>org.jacoco</groupId>
+                               <artifactId>jacoco-maven-plugin</artifactId>
+                               <version>0.7.8</version>
+                               <executions>
+                                       <!-- Unit-Tests -->
+                                       <execution>
+                                               <id>prepare-agent</id>
+                                               <goals>
+                                                       <goal>prepare-agent</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <destFile>${sonar.jacoco.reportPath}</destFile>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <version>2.5.1</version>
+                               <inherited>true</inherited>
+                               <configuration>
+                                       <source>1.7</source>
+                                       <target>1.7</target>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-javadoc-plugin</artifactId>
+                               <version>2.10.3</version>
+                               <configuration/>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.codehaus.mojo</groupId>
+                               <artifactId>license-maven-plugin</artifactId>
+                               <version>1.10</version>
+                               <configuration>
+                                       <addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage>
+                                       <processStartTag>============LICENSE_START=======================================================</processStartTag>
+                                       <processEndTag>============LICENSE_END=========================================================</processEndTag>
+                                       <sectionDelimiter>================================================================================</sectionDelimiter>
+                                       <licenseName>apache_v2</licenseName>
+                                       <inceptionYear>2017</inceptionYear>
+                                       <organizationName>AT&amp;T Intellectual Property. All rights reserved.</organizationName>
+                                       <projectName>sdc-distribution-client</projectName>
+                                       <canUpdateCopyright>true</canUpdateCopyright>
+                                       <canUpdateDescription>true</canUpdateDescription>
+                                       <canUpdateLicense>true</canUpdateLicense>
+                                       <emptyLineAfterHeader>true</emptyLineAfterHeader>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <id>first</id>
+                                               <goals>
+                                                       <goal>update-file-header</goal>
+                                               </goals>
+                                               <!--phase>process-sources</phase-->
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
+       <profiles>
+
+
+               <profile>
+                       <id>rackspace</id>
+                       <activation>
+                               <activeByDefault>false</activeByDefault>
+                       </activation>
+                       <repositories>
+                               <repository>
+                                       <id>rackspace-public</id>
+                                       <name>Rackspace</name>
+                                       <url>https://10.208.197.75:8443/repository/maven-public/</url>
+                                       <layout>default</layout>
+                               </repository>
+                       </repositories>
+
+                       <distributionManagement>
+                               <snapshotRepository>
+                                       <id>rackspace-snapshots</id>
+                                       <name>Rackspace-Snapshots</name>
+                                       <url>https://10.208.197.75:8443/repository/maven-snapshots/</url>
+                               </snapshotRepository>
+
+                               <repository>
+                                       <id>rackspace-public</id>
+                                       <name>Rackspace</name>
+                                       <url>https://10.208.197.75:8443/repository/maven-releases/</url>
+                               </repository>
+
+                               <site>
+                                       <id>rackspace-public</id>
+                                       <url>dav:https://ecomp-nexus:8443/repository/sdc-javadoc-repo/${project.version}</url>
+                               </site>
+
+                               
+                       </distributionManagement>
+
+               </profile>
+       </profiles>
+</project>
diff --git a/src/main/java/org/openecomp/sdc/api/IDistributionClient.java b/src/main/java/org/openecomp/sdc/api/IDistributionClient.java
new file mode 100644 (file)
index 0000000..a620e49
--- /dev/null
@@ -0,0 +1,137 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api;
+
+import java.util.List;
+
+import org.openecomp.sdc.api.consumer.IConfiguration;
+import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
+import org.openecomp.sdc.api.consumer.INotificationCallback;
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.notification.IVfModuleMetadata;
+import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+
+public interface IDistributionClient {
+       
+       /**
+        * Update the configuration of the distribution client <br>
+        * Updatable configuration parameters are: pollingInterval, pollingTimeout, consumerGroup and relevantArtifactTypes
+        * 
+        * @param newConf - contains updated configuration
+        * 
+        * @return IDistributionClientResult
+        */
+       IDistributionClientResult updateConfiguration(IConfiguration newConf);
+       
+       /**
+        * Retrieve the configuration of the distribution client <br>
+        * 
+        * @return IConfiguration
+        */
+       IConfiguration getConfiguration();
+       
+       /**
+        * Start distribution client <br>
+        * - start polling notification topic <br>
+        * 
+        * @return IDistributionClientResult
+        */
+       IDistributionClientResult start();
+       
+       /**
+        * Stop distribution client <br>
+        * - stop polling notification topic <br>
+        * - unregister topics (via ASDC) <br>
+        * - delete keys from UEB 
+        * 
+        * @return IDistributionClientResult
+        */
+       IDistributionClientResult stop();
+       
+       /**
+        * Downloads an artifact from ASDC Catalog <br>
+        * 
+        * @param artifactInfo
+        * @return IDistributionClientDownloadResult
+        */
+       IDistributionClientDownloadResult download(IArtifactInfo artifactInfo);
+       
+       /**
+        *  Initialize the distribution client <br>
+        *  - fetch the UEB server list from ASDC <br>
+        *  - create keys in UEB <br>
+        *  - register for topics (via ASDC) <br>
+        *  - set the notification callback <br>
+        *  
+        *  Note: all configuration fields are mandatory. <br> 
+        *  Password must be in clear text and not encrypted  <br>
+        *  ECOMP-Component MUST store password as SHA-2 (256) hashed with dynamically generated salt value <br>  
+        * 
+        * @param conf
+        * @param callback
+        * @return IDistributionClientResult
+        */
+       IDistributionClientResult init(IConfiguration conf, INotificationCallback callback);
+       
+       
+       /**
+        * Build and publish Distribution Download Status event to Distribution Status Topic
+        * 
+        * @param statusMessage
+        * @return IDistributionClientResult
+        */
+       IDistributionClientResult sendDownloadStatus(IDistributionStatusMessage statusMessage);
+       
+       /**
+        * Build and publish Distribution Download Status event to Distribution Status Topic With Error Reason.
+        * 
+        * @param statusMessage
+        * @param errorReason
+        * @return IDistributionClientResult
+        */
+       IDistributionClientResult sendDownloadStatus(IDistributionStatusMessage statusMessage, String errorReason);
+       
+       
+       /**
+        * Build and publish Distribution Deployment Status event to Distribution Status Topic 
+        * 
+        * @param statusMessage
+        * @return IDistributionClientResult
+        */
+       IDistributionClientResult sendDeploymentStatus(IDistributionStatusMessage statusMessage);
+       
+       /**
+        * Build and publish Distribution Deployment Status event to Distribution Status Topic With Error Reason.
+        * 
+        * @param statusMessage
+        * @param errorReason
+        * @return IDistributionClientResult
+        */
+       IDistributionClientResult sendDeploymentStatus(IDistributionStatusMessage statusMessage, String errorReason);
+       
+       /**This method parses artifact of type VF_MODULES_METADATA payload data . 
+        * @param artifactPayload
+        * @return IVfModuleMetadata list
+        */
+       List<IVfModuleMetadata> decodeVfModuleArtifact(byte[] artifactPayload);
+
+}
diff --git a/src/main/java/org/openecomp/sdc/api/IDistributionStatusMessageJsonBuilder.java b/src/main/java/org/openecomp/sdc/api/IDistributionStatusMessageJsonBuilder.java
new file mode 100644 (file)
index 0000000..7c28271
--- /dev/null
@@ -0,0 +1,25 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api;
+
+public interface IDistributionStatusMessageJsonBuilder {
+       String build();
+}
diff --git a/src/main/java/org/openecomp/sdc/api/asdc/RegistrationRequest.java b/src/main/java/org/openecomp/sdc/api/asdc/RegistrationRequest.java
new file mode 100644 (file)
index 0000000..f6ce949
--- /dev/null
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.asdc;
+
+public class RegistrationRequest {
+
+       String apiPublicKey;
+       String distrEnvName;
+       
+       public RegistrationRequest(String apiPublicKey, String distrEnvName) {
+               this.apiPublicKey = apiPublicKey;
+               this.distrEnvName = distrEnvName;
+       }
+       
+}
diff --git a/src/main/java/org/openecomp/sdc/api/asdc/ServerListResponse.java b/src/main/java/org/openecomp/sdc/api/asdc/ServerListResponse.java
new file mode 100644 (file)
index 0000000..c131a95
--- /dev/null
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.asdc;
+
+import java.util.List;
+
+public class ServerListResponse {
+
+       private List<String> uebServerList;
+
+       public List<String> getUebServerList() {
+               return uebServerList;
+       }
+
+       public void setUebServerList(List<String> uebServerList) {
+               this.uebServerList = uebServerList;
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/api/consumer/IConfiguration.java b/src/main/java/org/openecomp/sdc/api/consumer/IConfiguration.java
new file mode 100644 (file)
index 0000000..67eebce
--- /dev/null
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.consumer;
+
+import java.util.List;
+
+public interface IConfiguration {
+       /**ASDC Distribution Engine address. 
+        * Value can be either hostname (with or without port), IP:port or FQDN (Fully Qualified Domain Name). */
+       String getAsdcAddress(); 
+       /** User Name for ASDC distribution consumer authentication. */
+       String getUser(); 
+       /** User Password for ASDC distribution consumer authentication. */
+       String getPassword(); 
+       /** Distribution Client Polling Interval towards UEB in seconds. 
+        * Can Be reconfigured in runtime */
+       int getPollingInterval(); 
+       /** Distribution Client Timeout in seconds waiting to UEB server response in each fetch interval. 
+        * Can Be reconfigured in runtime */
+       int getPollingTimeout(); 
+       /** List of artifact types.<br>
+        * If the service contains any of the artifacts in the list, the callback will be activated. 
+        * Can Be reconfigured in runtime */
+       List<String> getRelevantArtifactTypes();
+       /** Returns the consumer group defined for this ECOMP component, if no consumer group is defined return null. */
+       String getConsumerGroup();
+       /** Returns the environment name (testing, production etc...)
+        * Can Be reconfigured in runtime */
+       String getEnvironmentName();
+       /**Unique ID of ECOMP component instance (e.x INSTAR name)*/
+       String getConsumerID();
+       /**Return full path to Client's Key Store that contains either CA certificate or the ASDC's public key (e.g /etc/keystore/asdc-client.jks)
+        * file will be deployed with asdc-distribution jar */
+       String getKeyStorePath();
+       
+       /**return client's Key Store password */
+       String getKeyStorePassword();
+       
+       /**
+        * Sets whether ASDC server TLS authentication is activated.
+        * If set to false, Key Store path and password are not needed to be set. 
+        * @return
+        */
+       boolean activateServerTLSAuth();
+}
+
+
diff --git a/src/main/java/org/openecomp/sdc/api/consumer/IDistributionStatusMessage.java b/src/main/java/org/openecomp/sdc/api/consumer/IDistributionStatusMessage.java
new file mode 100644 (file)
index 0000000..86251d1
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.consumer;
+
+import org.openecomp.sdc.utils.DistributionStatusEnum;
+
+public interface IDistributionStatusMessage {
+       /**
+        * Distribution ID published in the distribution notification.<br>
+        * Should be used to link the distribution status reports to the appropriate
+        * distribution activation.<br>
+        * Global Distribution Identifier: UUID generated by ASDC per each
+        * distribution activation.<br>
+        * Generated UUID is compliant with RFC 4122. It is a 128-bit value
+        * formatted into blocks of hexadecimal digits separated by a hyphen ("-").
+        * Ex.: AA97B177-9383-4934-8543-0F91A7A02836
+        */
+       String getDistributionID();
+       
+       /**Unique ID of ECOMP component instance (e.x INSTAR name)*/
+       String getConsumerID();
+       
+       /**
+        * Timestamp of the distribution status report creation.<br>
+        * The number of seconds that have elapsed since January 1, 1970.
+        */
+       long getTimestamp();
+       
+       /**Resource URL of the downloaded/deployed artifact - URL specified in the distribution notification message*/
+       String getArtifactURL();
+       
+       /**Download/Deployment status*/
+       DistributionStatusEnum getStatus();
+}
diff --git a/src/main/java/org/openecomp/sdc/api/consumer/INotificationCallback.java b/src/main/java/org/openecomp/sdc/api/consumer/INotificationCallback.java
new file mode 100644 (file)
index 0000000..60666ed
--- /dev/null
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.consumer;
+
+import org.openecomp.sdc.api.notification.INotificationData;
+/**When a relevant notification will be found activateCallback method will be activated with the notification data.<br>
+ * Please implement it according to your desired callback logic.*/
+public interface INotificationCallback {
+       void activateCallback(INotificationData data);
+}
+
diff --git a/src/main/java/org/openecomp/sdc/api/notification/IArtifactInfo.java b/src/main/java/org/openecomp/sdc/api/notification/IArtifactInfo.java
new file mode 100644 (file)
index 0000000..135fd45
--- /dev/null
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.notification;
+
+import java.util.List;
+
+
+public interface IArtifactInfo {
+       
+       /**Artifact File name */
+       String getArtifactName();
+       
+       /**Artifact Type.<br>
+       Following are  valid  values :   HEAT , DG_XML. <br>
+       List of values will be extended in post-1510 releases.*/
+       String getArtifactType();
+       
+       /**Relative artifact's URL. Should be used in REST GET API to download the artifact's payload.<br> 
+       The full  artifact URL  will be  in the following format :<br>
+       https://{serverBaseURL}/{resourcePath}<br>
+       serverBaseURL  - Hostname ( ASDC LB FQDN)  + optional port <br>
+       resourcePath -  "artifactURL"  <br>
+       Ex : https://asdc.att.com/v1/catalog/services/srv1/2.0/resources/aaa/1.0/artifacts/aaa.yml */
+       String getArtifactURL();
+       
+       /**Base-64 encoded MD5 checksum of the artifact's payload.<br>
+       Should be used for data integrity validation when an artifact's payload is downloaded.<br>*/
+       String getArtifactChecksum();
+       
+       /**
+        * Installation timeout in minutes.<br>
+        * Used by the Orchestrator to determine how much time to wait for a heat (or other deployment artifact)<br>
+        * This field is only relevant for artifacts of ArtifactTypeEnum HEAT, for other artifacts it will be null.<br>
+        * deployment process to finish.<br>
+        * 
+        */
+       Integer getArtifactTimeout();
+       
+       /**
+        * Artifact description
+        */
+       String getArtifactDescription();
+       
+       /**
+        * Artifact Version
+        */
+       String getArtifactVersion();
+       
+       /**
+        * Artifact Unique ID
+        */
+       String getArtifactUUID();
+
+       
+       /**
+        * Returns the artifact it is generated from (relevant for heat_env), or null if there is no such artifact.
+        */
+       IArtifactInfo getGeneratedArtifact(); 
+       
+       /**
+        * Returns the list of related artifacts (relevant for HEAT_NESTED or HEAT_ARTIFACT), or null if there is no such artifacts.
+        */
+       List<IArtifactInfo> getRelatedArtifacts(); 
+       
+       
+}
diff --git a/src/main/java/org/openecomp/sdc/api/notification/INotificationData.java b/src/main/java/org/openecomp/sdc/api/notification/INotificationData.java
new file mode 100644 (file)
index 0000000..df314ea
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.notification;
+
+import java.util.List;
+
+
+
+
+
+public interface INotificationData {
+       /** Global Distribution Identifier: UUID generated by ASDC per each distribution activation.<br>
+        *  Generated UUID is compliant with RFC 4122.<br>
+        *  It is a 128-bit value formatted into blocks of hexadecimal digits separated by a hyphen ("-").<br>
+               Ex.: AA97B177-9383-4934-8543-0F91A7A02836 */
+       String getDistributionID();
+       
+       /**Logical Service Name.*/
+       String getServiceName();
+       
+       /** Service Version.<br>
+        *  Two dot (".") separated  digit blocks.<br> 
+               Ex. : "2.0"*/
+       String getServiceVersion();
+       
+       /**Global UUID generated by ASDC per each service version. Generated UUID is compliant with RFC 4122.<br>
+       It is a 128-bit value formatted into blocks of hexadecimal digits separated by a hyphen ("-").<br>
+       Ex. : AA97B177-9383-4934-8543-0F91A7A02836*/
+       String getServiceUUID();
+       
+       /**
+        * Service description
+        */
+       String getServiceDescription();
+       
+       /** List of the resource instances */
+       List<IResourceInstance> getResources();
+       
+       /** List of Artifacts On Service Level */
+       List<IArtifactInfo> getServiceArtifacts();
+       
+       /**This method allows getting details of the artifact by its uuid.*/
+       IArtifactInfo getArtifactMetadataByUUID(String artifactUUID);
+       
+       /**
+        * Invariant UUID
+        */
+       String getServiceInvariantUUID();
+}
diff --git a/src/main/java/org/openecomp/sdc/api/notification/IResourceInstance.java b/src/main/java/org/openecomp/sdc/api/notification/IResourceInstance.java
new file mode 100644 (file)
index 0000000..5a29d4b
--- /dev/null
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.notification;
+
+import java.util.List;
+
+public interface IResourceInstance {
+       /**Logical Resource Instance Name. <br>
+        * Unique Identifier of  the instance of the  specific resource in the service context.**/
+       String getResourceInstanceName();
+       
+       /**resource name */
+       String getResourceName();
+       
+       /**resource version */
+       String getResourceVersion();
+
+       /**Resource Type (For Example: VF (Virtual Function) - A subsystem in a service, it can include one or more VFCs. This is what NFV spec refers as VNF.)**/
+       String getResourceType();
+       
+       /**Global UUID of the resource that specific artifact belongs to.<br>
+       It is generated by ASDC per each resource version.<br>
+       Generated UUID is compliant with RFC 4122. It is a 128-bit value formatted into blocks of hexadecimal digits separated by a hyphen ("-"). <br>
+       Ex.: AA97B177-9383-4934-8543-0F91A7A02836*/
+       String getResourceUUID();
+
+       /**List of resource instance deployment artifacts. **/
+       List<IArtifactInfo> getArtifacts();
+       
+       String getResourceInvariantUUID();
+
+}
diff --git a/src/main/java/org/openecomp/sdc/api/notification/IVfModuleMetadata.java b/src/main/java/org/openecomp/sdc/api/notification/IVfModuleMetadata.java
new file mode 100644 (file)
index 0000000..a769d71
--- /dev/null
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.notification;
+
+import java.util.List;
+/**VF Module in the resource (VF) context*/
+public interface IVfModuleMetadata {
+       /**Logical VF  Module Name. Unique Identifier of  VF Module in the resource (VF) context.<br>
+          Ex. : "PCRF-module-0"
+       */
+       String getVfModuleModelName();
+       
+       /**Invariant VF Module UUID generated  on VF Module creation according to RFC 4122 <br>
+          It is generated  on service creation and stays  invariant even if service name /version are updated.
+        */
+       String getVfModuleModelInvariantUUID();
+       
+       /**
+       Resource Version . Ex. : "1"
+       */
+       String getVfModuleModelVersion();
+       
+       /**Global UUID of the VF Module.<br>
+               It is generated by ASDC per each new VF module version. Generated UUID is compliant with RFC 4122. It is a 128-bit value formatted into blocks of hexadecimal digits separated by a hyphen ("-").<br>
+               Ex.: AA97B177-9383-4934-8543-0F91A7A02836
+        */
+       String getVfModuleModelUUID();
+       
+       
+       /**
+        * VF  Module textual description. Can be empty. 
+        */
+       String getVfModuleModelDescription();
+       
+       
+       /**
+        * Is this VF module is the base module of the VF. 
+        * */
+       boolean isBase();
+       
+       /**
+        * Array of VF Module deployment artifacts UUID. 
+        * */
+       List<String> getArtifacts();
+}
diff --git a/src/main/java/org/openecomp/sdc/api/results/IDistributionClientDownloadResult.java b/src/main/java/org/openecomp/sdc/api/results/IDistributionClientDownloadResult.java
new file mode 100644 (file)
index 0000000..e101636
--- /dev/null
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.results;
+
+/**Distribution Client Result For Download API*/
+public interface IDistributionClientDownloadResult extends IDistributionClientResult{
+       byte[] getArtifactPayload();
+       String getArtifactName();
+}
diff --git a/src/main/java/org/openecomp/sdc/api/results/IDistributionClientResult.java b/src/main/java/org/openecomp/sdc/api/results/IDistributionClientResult.java
new file mode 100644 (file)
index 0000000..b4086ac
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.api.results;
+
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+/**General Distribution Client Result*/
+public interface IDistributionClientResult {
+       DistributionActionResultEnum getDistributionActionResult();
+       String getDistributionMessageResult();
+}
diff --git a/src/main/java/org/openecomp/sdc/http/AsdcConnectorClient.java b/src/main/java/org/openecomp/sdc/http/AsdcConnectorClient.java
new file mode 100644 (file)
index 0000000..59a879c
--- /dev/null
@@ -0,0 +1,410 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.openecomp.sdc.api.asdc.RegistrationRequest;
+import org.openecomp.sdc.api.asdc.ServerListResponse;
+import org.openecomp.sdc.api.consumer.IConfiguration;
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.impl.DistributionClientDownloadResultImpl;
+import org.openecomp.sdc.impl.DistributionClientResultImpl;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+import org.openecomp.sdc.utils.DistributionClientConstants;
+import org.openecomp.sdc.utils.GeneralUtils;
+import org.openecomp.sdc.utils.Pair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.att.nsa.apiClient.credentials.ApiCredential;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+
+import fj.data.Either;
+
+public class AsdcConnectorClient {
+       String contentDispositionHeader = "Content-Disposition";
+       private static Logger log = LoggerFactory.getLogger(AsdcConnectorClient.class.getName());
+       private IConfiguration configuration;
+       private HttpAsdcClient httpClient = null;
+
+       public void init(IConfiguration configuraion) {
+               this.configuration = configuraion;
+               httpClient = new HttpAsdcClient(configuration);
+       }
+
+       public void close() {
+               if (httpClient != null) {
+                       httpClient.closeHttpClient();
+               }
+       }
+
+       public IConfiguration getConfiguration() {
+               return configuration;
+       }
+
+       public void setConfiguration(IConfiguration configuration) {
+               this.configuration = configuration;
+       }
+
+       public HttpAsdcClient getHttpClient() {
+               return httpClient;
+       }
+
+       public void setHttpClient(HttpAsdcClient httpClient) {
+               this.httpClient = httpClient;
+       }
+
+       public Either<List<String>, IDistributionClientResult> getServerList() {
+               Pair<HttpAsdcResponse, CloseableHttpResponse> getServersResponsePair = performAsdcServerRequest(AsdcUrls.GET_CLUSTER_SERVER_LIST);
+               HttpAsdcResponse getServersResponse = getServersResponsePair.getFirst();
+
+               Either<List<String>, IDistributionClientResult> response;
+               if (getServersResponse.getStatus() == HttpStatus.SC_OK) {
+                       response = parseGetServersResponse(getServersResponse);
+               } else {
+                       IDistributionClientResult asdcError = handleAsdcError(getServersResponse);
+                       response = Either.right(asdcError);
+
+               }
+               handeAsdcConnectionClose(getServersResponsePair);
+               return response;
+
+       }
+
+       public Either<List<String>, IDistributionClientResult> getValidArtifactTypesList() {
+               Pair<HttpAsdcResponse, CloseableHttpResponse> getServersResponsePair = performAsdcServerRequest(AsdcUrls.GET_VALID_ARTIFACT_TYPES);
+               HttpAsdcResponse getArtifactTypeResponse = getServersResponsePair.getFirst();
+
+               Either<List<String>, IDistributionClientResult> response;
+               if (getArtifactTypeResponse.getStatus() == HttpStatus.SC_OK) {
+                       response = parseGetValidArtifactTypesResponse(getArtifactTypeResponse);
+               } else {
+                       IDistributionClientResult asdcError = handleAsdcError(getArtifactTypeResponse);
+                       response = Either.right(asdcError);
+
+               }
+               handeAsdcConnectionClose(getServersResponsePair);
+               return response;
+
+       }
+
+       private void handeAsdcConnectionClose(Pair<HttpAsdcResponse, CloseableHttpResponse> getServersResponsePair) {
+               if (getServersResponsePair.getSecond() != null) {
+                       try {
+                               getServersResponsePair.getSecond().close();
+
+                       } catch (IOException e) {
+                               log.error("failed to close http response");
+                       }
+
+               }
+       }
+
+       private Pair<HttpAsdcResponse, CloseableHttpResponse> performAsdcServerRequest(final String url) {
+               String requestId = UUID.randomUUID().toString();
+               Map<String, String> requestHeaders = addHeadersToHttpRequest(requestId);
+               log.debug("about to perform getServerList. requestId= {} url= {}", requestId, url);
+               Pair<HttpAsdcResponse, CloseableHttpResponse> getServersResponsePair = httpClient.getRequest(url, requestHeaders, false);
+               return getServersResponsePair;
+       }
+
+       public Either<TopicRegistrationResponse, DistributionClientResultImpl> registerAsdcTopics(ApiCredential credential) {
+
+               Either<TopicRegistrationResponse, DistributionClientResultImpl> response = null;
+
+               String requestId = UUID.randomUUID().toString();
+               Map<String, String> requestHeaders = addHeadersToHttpRequest(requestId);
+
+               RegistrationRequest registrationRequest = new RegistrationRequest(credential.getApiKey(), configuration.getEnvironmentName());
+               Gson gson = new GsonBuilder().setPrettyPrinting().create();
+               String jsonRequest = gson.toJson(registrationRequest);
+               StringEntity body = new StringEntity(jsonRequest, ContentType.APPLICATION_JSON);
+
+               log.debug("about to perform registerAsdcTopics. requestId= " + requestId + " url= " + AsdcUrls.POST_FOR_TOPIC_REGISTRATION);
+               Pair<HttpAsdcResponse, CloseableHttpResponse> registerResponsePair = httpClient.postRequest(AsdcUrls.POST_FOR_TOPIC_REGISTRATION, body, requestHeaders, false);
+               HttpAsdcResponse registerResponse = registerResponsePair.getFirst();
+               int status = registerResponse.getStatus();
+
+               if (status == HttpStatus.SC_OK) {
+                       response = parseRegistrationResponse(registerResponse);
+
+               } else {
+                       DistributionClientResultImpl asdcError = handleAsdcError(registerResponse);
+                       return Either.right(asdcError);
+               }
+               handeAsdcConnectionClose(registerResponsePair);
+
+               log.debug("registerAsdcTopics response= " + status + ". requestId= " + requestId + " url= " + AsdcUrls.POST_FOR_TOPIC_REGISTRATION);
+               return response;
+
+       }
+
+       public IDistributionClientResult unregisterTopics(ApiCredential credential) {
+
+               DistributionClientResultImpl response = null;
+
+               String requestId = UUID.randomUUID().toString();
+               HttpAsdcClient httpClient = new HttpAsdcClient(configuration);
+               Map<String, String> requestHeaders = addHeadersToHttpRequest(requestId);
+
+               RegistrationRequest registrationRequest = new RegistrationRequest(credential.getApiKey(), configuration.getEnvironmentName());
+               Gson gson = new GsonBuilder().setPrettyPrinting().create();
+               String jsonRequest = gson.toJson(registrationRequest);
+               StringEntity body = new StringEntity(jsonRequest, ContentType.APPLICATION_JSON);
+
+               log.debug("about to perform unregisterTopics. requestId= " + requestId + " url= " + AsdcUrls.POST_FOR_UNREGISTER);
+               Pair<HttpAsdcResponse, CloseableHttpResponse> unRegisterResponsePair = httpClient.postRequest(AsdcUrls.POST_FOR_UNREGISTER, body, requestHeaders, false);
+               HttpAsdcResponse unRegisterResponse = unRegisterResponsePair.getFirst();
+               int status = unRegisterResponse.getStatus();
+               if (status == HttpStatus.SC_NO_CONTENT || status == HttpStatus.SC_OK) {
+                       response = new DistributionClientResultImpl(DistributionActionResultEnum.SUCCESS, "unregistration successful");
+
+               } else {
+                       response = handleAsdcError(unRegisterResponse);
+               }
+
+               handeAsdcConnectionClose(unRegisterResponsePair);
+
+               log.debug("unregisterTopics response = " + status + ". requestId= " + requestId + " url= " + AsdcUrls.POST_FOR_UNREGISTER);
+
+               return response;
+
+       }
+
+       public DistributionClientDownloadResultImpl dowloadArtifact(IArtifactInfo artifactInfo) {
+               DistributionClientDownloadResultImpl response = new DistributionClientDownloadResultImpl(DistributionActionResultEnum.GENERAL_ERROR, "failed to download artifact from ASDC");
+
+               String requestId = UUID.randomUUID().toString();
+               Map<String, String> requestHeaders = new HashMap<String, String>();
+               requestHeaders.put(DistributionClientConstants.HEADER_REQUEST_ID, requestId);
+               requestHeaders.put(DistributionClientConstants.HEADER_INSTANCE_ID, configuration.getConsumerID());
+               requestHeaders.put(HttpHeaders.ACCEPT, ContentType.APPLICATION_OCTET_STREAM.toString());
+               String requestUrl = artifactInfo.getArtifactURL();
+               Pair<HttpAsdcResponse, CloseableHttpResponse> downloadPair = httpClient.getRequest(requestUrl, requestHeaders, false);
+               HttpAsdcResponse downloadResponse = downloadPair.getFirst();
+
+               int status = downloadResponse.getStatus();
+               if (status == 200) {
+
+                       response = parseDownloadArtifactResponse(artifactInfo, downloadResponse);
+               } else {
+                       response = handleAsdcDownloadArtifactError(downloadResponse);
+
+               }
+               handeAsdcConnectionClose(downloadPair);
+               return response;
+       }
+
+       /* **************************** private methods ********************************************/
+
+       private Either<List<String>, IDistributionClientResult> parseGetServersResponse(HttpAsdcResponse getServersResponse) {
+               Either<List<String>, IDistributionClientResult> result;
+               try {
+                       String jsonMessage = IOUtils.toString(getServersResponse.getMessage().getContent());
+
+                       Gson gson = new GsonBuilder().create();
+                       ServerListResponse serverListResponse = gson.fromJson(jsonMessage, ServerListResponse.class);
+                       List<String> serverList = serverListResponse.getUebServerList();
+                       result = Either.left(serverList);
+
+               } catch (UnsupportedOperationException | IOException e) {
+                       result = handleParsingError(e);
+               }
+
+               return result;
+       }
+
+       private Either<List<String>, IDistributionClientResult> parseGetValidArtifactTypesResponse(HttpAsdcResponse getArtifactTypesResponse) {
+               Either<List<String>, IDistributionClientResult> result;
+               try {
+                       String jsonMessage = IOUtils.toString(getArtifactTypesResponse.getMessage().getContent());
+                       Type listType = new TypeToken<ArrayList<String>>() {
+                       }.getType();
+                       Gson gson = new GsonBuilder().create();
+                       List<String> artifactTypesList = gson.fromJson(jsonMessage, listType);
+                       result = Either.left(artifactTypesList);
+
+               } catch (UnsupportedOperationException | IOException e) {
+                       result = handleParsingError(e);
+               }
+
+               return result;
+       }
+
+       private Either<List<String>, IDistributionClientResult> handleParsingError(Exception e) {
+               Either<List<String>, IDistributionClientResult> result;
+               log.error("failed to parse response from ASDC. error: " + e.getMessage());
+               IDistributionClientResult response = new DistributionClientResultImpl(DistributionActionResultEnum.GENERAL_ERROR, "failed to parse response from ASDC");
+               result = Either.right(response);
+               return result;
+       }
+
+       private Either<TopicRegistrationResponse, DistributionClientResultImpl> parseRegistrationResponse(HttpAsdcResponse registerResponse) {
+
+               String jsonMessage;
+               try {
+                       jsonMessage = IOUtils.toString(registerResponse.getMessage().getContent());
+
+                       Gson gson = new GsonBuilder().create();
+                       TopicRegistrationResponse registrationResponse = gson.fromJson(jsonMessage, TopicRegistrationResponse.class);
+
+                       if (registrationResponse.getDistrNotificationTopicName() == null) {
+                               DistributionClientResultImpl response = new DistributionClientResultImpl(DistributionActionResultEnum.FAIL, "failed to receive notification topic from ASDC");
+                               return Either.right(response);
+                       }
+
+                       if (registrationResponse.getDistrStatusTopicName() == null) {
+                               DistributionClientResultImpl response = new DistributionClientResultImpl(DistributionActionResultEnum.FAIL, "failed to receive status topic from ASDC");
+                               return Either.right(response);
+                       }
+                       return Either.left(registrationResponse);
+
+               } catch (UnsupportedOperationException | IOException e) {
+                       log.error("failed to pars response from ASDC. error: " + e.getMessage());
+                       DistributionClientResultImpl response = new DistributionClientResultImpl(DistributionActionResultEnum.GENERAL_ERROR, "failed to parse response from ASDC");
+                       return Either.right(response);
+               }
+       }
+
+       private Map<String, String> addHeadersToHttpRequest(String requestId) {
+               Map<String, String> requestHeaders = new HashMap<String, String>();
+               requestHeaders.put(DistributionClientConstants.HEADER_REQUEST_ID, requestId);
+               requestHeaders.put(DistributionClientConstants.HEADER_INSTANCE_ID, configuration.getConsumerID());
+               requestHeaders.put(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
+
+               return requestHeaders;
+       }
+
+       private DistributionClientResultImpl handleAsdcError(HttpAsdcResponse registerResponse) {
+               int status = registerResponse.getStatus();
+               DistributionClientResultImpl errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.GENERAL_ERROR, "failed to send request to ASDC");
+               if (status == HttpStatus.SC_UNAUTHORIZED) {
+                       errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.ASDC_AUTHENTICATION_FAILED, "authentication to ASDC failed for user " + configuration.getUser());
+               } else if (status == HttpStatus.SC_FORBIDDEN) {
+                       errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.ASDC_AUTHORIZATION_FAILED, "authorization failure for user " + configuration.getUser());
+               } else if (status == HttpStatus.SC_BAD_REQUEST) {
+                       errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.BAD_REQUEST, "ASDC call failed due to missing information");
+               } else if (status == HttpStatus.SC_NOT_FOUND) {
+                       errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.ASDC_NOT_FOUND, "ASDC not found");
+               } else if (status == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
+                       errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.ASDC_SERVER_PROBLEM, "ASDC server problem");
+               } else if (status == HttpStatus.SC_BAD_GATEWAY) {
+                       errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.ASDC_CONNECTION_FAILED, "ASDC server problem");
+               } else if (status == HttpStatus.SC_GATEWAY_TIMEOUT) {
+                       errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.ASDC_SERVER_TIMEOUT, "ASDC server problem");
+               }
+               log.error("status from ASDC is " + registerResponse);
+               log.error(errorResponse.toString());
+               try {
+                       String errorString = IOUtils.toString(registerResponse.getMessage().getContent());
+                       log.debug("error from ASDC is: " + errorString);
+               } catch (UnsupportedOperationException | IOException e) {
+               }
+               return errorResponse;
+
+       }
+
+       private DistributionClientDownloadResultImpl handleAsdcDownloadArtifactError(HttpAsdcResponse registerResponse) {
+               int status = registerResponse.getStatus();
+               DistributionClientDownloadResultImpl errorResponse = new DistributionClientDownloadResultImpl(DistributionActionResultEnum.GENERAL_ERROR, "failed to send request to ASDC");
+               if (status == HttpStatus.SC_UNAUTHORIZED) {
+                       errorResponse = new DistributionClientDownloadResultImpl(DistributionActionResultEnum.ASDC_AUTHENTICATION_FAILED, "authentication to ASDC failed for user " + configuration.getUser());
+               } else if (status == HttpStatus.SC_FORBIDDEN) {
+                       errorResponse = new DistributionClientDownloadResultImpl(DistributionActionResultEnum.ASDC_AUTHORIZATION_FAILED, "authorization failure for user " + configuration.getUser());
+               } else if (status == HttpStatus.SC_BAD_REQUEST || status == HttpStatus.SC_NOT_FOUND) {
+                       errorResponse = new DistributionClientDownloadResultImpl(DistributionActionResultEnum.ARTIFACT_NOT_FOUND, "Specified artifact is  not found");
+                       // } else if (status == 404){
+                       // errorResponse = new DistributionClientDownloadResultImpl(
+                       // DistributionActionResultEnum.ASDC_NOT_FOUND,
+                       // "ASDC not found");
+               } else if (status == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
+                       errorResponse = new DistributionClientDownloadResultImpl(DistributionActionResultEnum.ASDC_SERVER_PROBLEM, "ASDC server problem");
+               }
+               log.error("status from ASDC is " + registerResponse);
+               log.error(errorResponse.toString());
+               try {
+                       String errorString = IOUtils.toString(registerResponse.getMessage().getContent());
+                       log.debug("error from ASDC is: " + errorString);
+               } catch (UnsupportedOperationException | IOException e) {
+               }
+               return errorResponse;
+
+       }
+
+       private DistributionClientDownloadResultImpl parseDownloadArtifactResponse(IArtifactInfo artifactInfo, HttpAsdcResponse getServersResponse) {
+               HttpEntity entity = getServersResponse.getMessage();
+               InputStream is;
+               try {
+                       is = entity.getContent();
+                       String artifactName = "";
+                       if (getServersResponse.getHeadersMap().containsKey(contentDispositionHeader))
+                               artifactName = getServersResponse.getHeadersMap().get(contentDispositionHeader);
+
+                       byte[] payload = IOUtils.toByteArray(is);
+                       if (artifactInfo.getArtifactChecksum() == null || artifactInfo.getArtifactChecksum().isEmpty()) {
+                               return new DistributionClientDownloadResultImpl(DistributionActionResultEnum.DATA_INTEGRITY_PROBLEM, "failed to get artifact from ASDC. Empty checksum");
+                       }
+
+                       if (validateChecksum(artifactInfo, payload)) {
+                               DistributionClientDownloadResultImpl resResponse = new DistributionClientDownloadResultImpl(DistributionActionResultEnum.SUCCESS, "success", artifactName, payload);
+                               return resResponse;
+
+                       } else {
+
+                               return new DistributionClientDownloadResultImpl(DistributionActionResultEnum.GENERAL_ERROR, "Invalid checksum. ArtifactInfo checksum ");
+                       }
+
+               } catch (UnsupportedOperationException | IOException e) {
+                       log.error("failed to get artifact from response ");
+                       return new DistributionClientDownloadResultImpl(DistributionActionResultEnum.GENERAL_ERROR, "UnsupportedOperationException ");
+               }
+
+       }
+
+       private boolean validateChecksum(IArtifactInfo artifactInfo, byte[] payload) {
+               boolean bRes = false;
+               String calculatedMD5 = GeneralUtils.calculateMD5(payload);
+               if (artifactInfo.getArtifactChecksum().equals(calculatedMD5)) {
+                       bRes = true;
+               }
+
+               return bRes;
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/http/AsdcUrls.java b/src/main/java/org/openecomp/sdc/http/AsdcUrls.java
new file mode 100644 (file)
index 0000000..2112f39
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.http;
+
+public class AsdcUrls {
+
+       public static final String GET_CLUSTER_SERVER_LIST = "/asdc/v1/distributionUebCluster";
+       public static final String GET_VALID_ARTIFACT_TYPES = "/asdc/v1/artifactTypes";
+       public static final String POST_FOR_TOPIC_REGISTRATION = "/asdc/v1/registerForDistribution";
+       public static final String POST_FOR_UNREGISTER = "/asdc/v1/unRegisterForDistribution";
+       
+}
diff --git a/src/main/java/org/openecomp/sdc/http/HttpAsdcClient.java b/src/main/java/org/openecomp/sdc/http/HttpAsdcClient.java
new file mode 100644 (file)
index 0000000..a08416c
--- /dev/null
@@ -0,0 +1,352 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.http;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.ConnectException;
+import java.net.UnknownHostException;
+import java.security.KeyStore;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpStatus;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.ssl.TrustStrategy;
+import org.openecomp.sdc.api.consumer.IConfiguration;
+import org.openecomp.sdc.impl.DistributionClientImpl;
+import org.openecomp.sdc.utils.Pair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HttpAsdcClient implements IHttpAsdcClient {
+
+       private static final String TLS = "TLS";
+       private static final String AUTHORIZATION_HEADER = "Authorization";
+       private static final String HTTPS = "https://";
+       private static Logger log = LoggerFactory.getLogger(DistributionClientImpl.class.getName());
+       private CloseableHttpClient httpClient = null;
+       private String serverFqdn = null;
+       private String authHeaderValue = "";
+
+       public HttpAsdcClient(IConfiguration configuraion/* String serverFqdn, String username, String password */) {
+               this.serverFqdn = configuraion.getAsdcAddress();
+               String username = configuraion.getUser();
+               String password = configuraion.getPassword();
+
+               initSSL(serverFqdn, username, password, configuraion.getKeyStorePath(), configuraion.getKeyStorePassword(), configuraion.activateServerTLSAuth());
+
+               String userNameAndPassword = username + ":" + password;
+               this.authHeaderValue = "Basic " + Base64.encodeBase64String(userNameAndPassword.getBytes());
+       }
+
+       // @SuppressWarnings("deprecation")
+       private void initSSL(String serverFqdn, String username, String password, String keyStorePath, String keyStoePass, boolean isSupportSSLVerification) {
+
+               try {
+                       HostnameVerifier hostnameVerifier = new HostnameVerifier() {
+
+                               @Override
+                               public boolean verify(String hostname, SSLSession session) {
+                                       return true;
+                               }
+                       };
+
+                       // SSLContextBuilder is not thread safe
+                       // @SuppressWarnings("deprecation")
+                       CredentialsProvider credsProvider = new BasicCredentialsProvider();
+                       credsProvider.setCredentials(new AuthScope("localhost", 443), new UsernamePasswordCredentials(username, password));
+                       SSLContext sslContext;
+                       sslContext = SSLContext.getInstance(TLS);
+                       TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+                       KeyStore trustStore = null;
+                       tmf.init(trustStore);
+                       TrustManager[] tms = tmf.getTrustManagers();
+                       if (isSupportSSLVerification) {
+
+                               if (keyStorePath != null && !keyStorePath.isEmpty()) {
+                                       // trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+                                       // trustStore.load(new FileInputStream(keyStorePath), keyStoePass.toCharArray());
+
+                                       // Using null here initialises the TMF with the default trust store.
+
+                                       // Get hold of the default trust manager
+                                       X509TrustManager defaultTm = null;
+                                       for (TrustManager tm : tmf.getTrustManagers()) {
+                                               if (tm instanceof X509TrustManager) {
+                                                       defaultTm = (X509TrustManager) tm;
+                                                       break;
+                                               }
+                                       }
+
+                                       // Do the same with your trust store this time
+                                       // Adapt how you load the keystore to your needs
+                                       trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+                                       trustStore.load(new FileInputStream(keyStorePath), keyStoePass.toCharArray());
+
+                                       tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+                                       tmf.init(trustStore);
+
+                                       // Get hold of the default trust manager
+                                       X509TrustManager myTm = null;
+                                       for (TrustManager tm : tmf.getTrustManagers()) {
+                                               if (tm instanceof X509TrustManager) {
+                                                       myTm = (X509TrustManager) tm;
+                                                       break;
+                                               }
+                                       }
+
+                                       // Wrap it in your own class.
+                                       final X509TrustManager finalDefaultTm = defaultTm;
+                                       final X509TrustManager finalMyTm = myTm;
+                                       X509TrustManager customTm = new X509TrustManager() {
+                                               @Override
+                                               public X509Certificate[] getAcceptedIssuers() {
+                                                       // If you're planning to use client-cert auth,
+                                                       // merge results from "defaultTm" and "myTm".
+                                                       return finalDefaultTm.getAcceptedIssuers();
+                                               }
+
+                                               @Override
+                                               public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                                                       try {
+                                                               finalMyTm.checkServerTrusted(chain, authType);
+                                                       } catch (CertificateException e) {
+                                                               // This will throw another CertificateException if this fails too.
+                                                               finalDefaultTm.checkServerTrusted(chain, authType);
+                                                       }
+                                               }
+
+                                               @Override
+                                               public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                                                       // If you're planning to use client-cert auth,
+                                                       // do the same as checking the server.
+                                                       finalDefaultTm.checkClientTrusted(chain, authType);
+                                               }
+                                       };
+
+                                       tms = new TrustManager[] { customTm };
+
+                               }
+
+                               sslContext.init(null, tms, null);
+                               SSLContext.setDefault(sslContext);
+
+                               SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1", "TLSv1.1" }, null, hostnameVerifier);
+                               httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(credsProvider).setSSLSocketFactory(sslsf).build();
+
+                       } else {
+
+                               SSLContextBuilder builder = new SSLContextBuilder();
+
+                               builder.loadTrustMaterial(null, new TrustStrategy() {
+                                       public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                                               return true;
+                                       }
+                               });
+
+                               sslContext = builder.build();
+
+                               httpClient = HttpClientBuilder.create().setSSLHostnameVerifier(hostnameVerifier).setSslcontext(sslContext).setDefaultCredentialsProvider(credsProvider).build();
+                       }
+
+               } catch (Exception e) {
+                       log.error("Failed to create https client", e);
+
+               }
+
+               return;
+       }
+
+       public HttpAsdcResponse postRequest(String requestUrl, HttpEntity entity, Map<String, String> headersMap) {
+               return postRequest(requestUrl, entity, headersMap, true).getFirst();
+       }
+
+       public Pair<HttpAsdcResponse, CloseableHttpResponse> postRequest(String requestUrl, HttpEntity entity, Map<String, String> headersMap, boolean closeTheRequest) {
+               Pair<HttpAsdcResponse, CloseableHttpResponse> ret;
+               CloseableHttpResponse httpResponse = null;
+               HttpAsdcResponse response = null;
+               HttpPost httpPost = new HttpPost(HTTPS + serverFqdn + requestUrl);
+               List<Header> headers = addHeadersToHttpRequest(headersMap);
+               for (Header header : headers) {
+                       httpPost.addHeader(header);
+               }
+
+               httpPost.setHeader(AUTHORIZATION_HEADER, this.authHeaderValue);
+
+               httpPost.setEntity(entity);
+               try {
+                       httpResponse = httpClient.execute(httpPost);
+                       response = new HttpAsdcResponse(httpResponse.getStatusLine().getStatusCode(), httpResponse.getEntity());
+
+               } catch (IOException e) {
+                       log.error("failed to send request to url: " + requestUrl);
+                       StringEntity errorEntity = null;
+                       try {
+                               errorEntity = new StringEntity("failed to send request");
+                       } catch (UnsupportedEncodingException e1) {
+                       }
+
+                       response = new HttpAsdcResponse(500, errorEntity);
+
+               } finally {
+                       if (closeTheRequest) {
+                               if (httpResponse != null) {
+                                       try {
+                                               httpResponse.close();
+
+                                       } catch (IOException e) {
+                                               log.error("failed to close http response");
+                                       }
+                               }
+                               ret = new Pair<HttpAsdcResponse, CloseableHttpResponse>(response, null);
+                       } else {
+                               ret = new Pair<HttpAsdcResponse, CloseableHttpResponse>(response, httpResponse);
+                       }
+               }
+
+               return ret;
+       }
+
+       public HttpAsdcResponse getRequest(String requestUrl, Map<String, String> headersMap) {
+
+               return getRequest(requestUrl, headersMap, true).getFirst();
+
+       }
+
+       public Pair<HttpAsdcResponse, CloseableHttpResponse> getRequest(String requestUrl, Map<String, String> headersMap, boolean closeTheRequest) {
+               Pair<HttpAsdcResponse, CloseableHttpResponse> ret;
+               CloseableHttpResponse httpResponse = null;
+               String url = HTTPS + serverFqdn + requestUrl;
+               log.debug("url to send  " + url);
+               HttpGet httpGet = new HttpGet(url);
+               List<Header> headers = addHeadersToHttpRequest(headersMap);
+               for (Header header : headers) {
+                       httpGet.addHeader(header);
+               }
+
+               httpGet.setHeader(AUTHORIZATION_HEADER, this.authHeaderValue);
+
+               HttpAsdcResponse response = null;
+               try {
+                       httpResponse = httpClient.execute(httpGet);
+
+                       log.debug("GET Response Status " + httpResponse.getStatusLine().getStatusCode());
+                       Header[] headersRes = httpResponse.getAllHeaders();
+                       Map<String, String> headersResMap = new HashMap<String, String>();
+                       for (Header header : headersRes) {
+                               headersResMap.put(header.getName(), header.getValue());
+                       }
+                       response = new HttpAsdcResponse(httpResponse.getStatusLine().getStatusCode(), httpResponse.getEntity(), headersResMap);
+
+               } catch (UnknownHostException | ConnectException e) {
+                       log.error("failed to connect to url: " + requestUrl, e);
+                       StringEntity errorEntity = null;
+                       try {
+                               errorEntity = new StringEntity("failed to connect");
+                       } catch (UnsupportedEncodingException e1) {
+                       }
+
+                       response = new HttpAsdcResponse(HttpStatus.SC_BAD_GATEWAY, errorEntity);
+
+               } catch (IOException e) {
+                       log.error("failed to send request to url: " + requestUrl + " error " + e.getMessage());
+                       StringEntity errorEntity = null;
+                       try {
+                               errorEntity = new StringEntity("failed to send request " + e.getMessage());
+                       } catch (UnsupportedEncodingException e1) {
+                       }
+
+                       response = new HttpAsdcResponse(HttpStatus.SC_BAD_GATEWAY, errorEntity);
+
+               } finally {
+
+                       if (closeTheRequest) {
+                               if (httpResponse != null) {
+                                       try {
+                                               httpResponse.close();
+
+                                       } catch (IOException e) {
+                                               log.error("failed to close http response");
+                                       }
+                               }
+                               ret = new Pair<HttpAsdcResponse, CloseableHttpResponse>(response, null);
+                       } else {
+                               ret = new Pair<HttpAsdcResponse, CloseableHttpResponse>(response, httpResponse);
+                       }
+               }
+
+               return ret;
+
+       }
+
+       public void closeHttpClient() {
+               try {
+                       httpClient.close();
+               } catch (IOException e) {
+                       // TODO Auto-generated catch block
+                       log.error("failed to close http client");
+               }
+
+       }
+
+       private List<Header> addHeadersToHttpRequest(Map<String, String> headersMap) {
+
+               List<Header> requestHeaders = new ArrayList<Header>();
+
+               Set<String> headersKyes = headersMap.keySet();
+               for (String key : headersKyes) {
+                       Header requestHeader = new BasicHeader(key, headersMap.get(key));
+                       requestHeaders.add(requestHeader);
+               }
+
+               return requestHeaders;
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/http/HttpAsdcResponse.java b/src/main/java/org/openecomp/sdc/http/HttpAsdcResponse.java
new file mode 100644 (file)
index 0000000..9e48d5e
--- /dev/null
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.http;
+
+import java.util.Map;
+
+import org.apache.http.HttpEntity;
+
+public class HttpAsdcResponse {
+
+       int status;
+       HttpEntity message;
+       Map<String, String> headersMap;
+       
+       public HttpAsdcResponse(int status, HttpEntity message) {
+               super();
+               this.status = status;
+               this.message = message;
+       }
+       
+       public HttpAsdcResponse(int status, HttpEntity message, Map<String, String> headersMap) {
+               super();
+               this.status = status;
+               this.message = message;
+               this.headersMap = headersMap;
+       }
+
+       public Map<String, String> getHeadersMap() {
+               return headersMap;
+       }
+
+       public void setHeadersMap(Map<String, String> headersMap) {
+               this.headersMap = headersMap;
+       }
+
+       public int getStatus() {
+               return status;
+       }
+
+       public void setStatus(int status) {
+               this.status = status;
+       }
+
+       public HttpEntity getMessage() {
+               return message;
+       }
+
+       public void setMessage(HttpEntity message) {
+               this.message = message;
+       }
+       
+       
+}
diff --git a/src/main/java/org/openecomp/sdc/http/IHttpAsdcClient.java b/src/main/java/org/openecomp/sdc/http/IHttpAsdcClient.java
new file mode 100644 (file)
index 0000000..aa62bac
--- /dev/null
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.http;
+
+import java.util.Map;
+
+import org.apache.http.HttpEntity;
+
+public interface IHttpAsdcClient {
+               
+       HttpAsdcResponse postRequest(String requestUrl, HttpEntity entity, Map<String, String> headersMap);
+       HttpAsdcResponse getRequest(String requestUrl, Map<String, String> headersMap);
+       void closeHttpClient();
+       
+}
diff --git a/src/main/java/org/openecomp/sdc/http/TopicRegistrationResponse.java b/src/main/java/org/openecomp/sdc/http/TopicRegistrationResponse.java
new file mode 100644 (file)
index 0000000..280d7da
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.http;
+
+public class TopicRegistrationResponse {
+       String distrNotificationTopicName;
+       String distrStatusTopicName;
+       
+       
+       public void setDistrNotificationTopicName(String distrNotificationTopicName) {
+               this.distrNotificationTopicName = distrNotificationTopicName;
+       }
+       public void setDistrStatusTopicName(String distrStatusTopicName) {
+               this.distrStatusTopicName = distrStatusTopicName;
+       }
+       
+       public String getDistrNotificationTopicName() {
+               return distrNotificationTopicName;
+       }
+       public String getDistrStatusTopicName() {
+               return distrStatusTopicName;
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/ArtifactInfoImpl.java b/src/main/java/org/openecomp/sdc/impl/ArtifactInfoImpl.java
new file mode 100644 (file)
index 0000000..64ff9a8
--- /dev/null
@@ -0,0 +1,192 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+
+class ArtifactInfoImpl implements IArtifactInfo {
+
+       private String artifactName;
+       private String artifactType;
+       private String artifactURL;
+       private String artifactChecksum;
+       private String artifactDescription;
+       private Integer artifactTimeout;
+       private String artifactVersion;
+       private String artifactUUID;
+       private String generatedFromUUID;
+       private IArtifactInfo generatedArtifact;
+       private List<String> relatedArtifacts;
+       private List<IArtifactInfo> relatedArtifactsInfo;
+       ArtifactInfoImpl(){}
+       
+       private ArtifactInfoImpl(IArtifactInfo iArtifactInfo){
+               artifactName = iArtifactInfo.getArtifactName();
+               artifactType = iArtifactInfo.getArtifactType(); 
+               artifactURL = iArtifactInfo.getArtifactURL();
+               artifactChecksum = iArtifactInfo.getArtifactChecksum();
+               artifactDescription = iArtifactInfo.getArtifactDescription();
+               artifactTimeout = iArtifactInfo.getArtifactTimeout();
+               artifactVersion = iArtifactInfo.getArtifactVersion();
+               artifactUUID = iArtifactInfo.getArtifactUUID();
+               generatedArtifact = iArtifactInfo.getGeneratedArtifact();
+               relatedArtifactsInfo = iArtifactInfo.getRelatedArtifacts();
+               relatedArtifacts = fillRelatedArtifactsUUID(relatedArtifactsInfo);
+               
+       }
+       
+       
+       private List<String> fillRelatedArtifactsUUID(List<IArtifactInfo> relatedArtifactsInfo) {
+               List<String> relatedArtifactsUUID = null;
+               if( relatedArtifactsInfo != null && !relatedArtifactsInfo.isEmpty()){
+                       relatedArtifactsUUID = new ArrayList<>();
+                       for(IArtifactInfo curr: relatedArtifactsInfo){
+                               relatedArtifactsUUID.add(curr.getArtifactUUID());
+                       }
+               }
+               return relatedArtifactsUUID;
+       }
+
+       public static List<ArtifactInfoImpl> convertToArtifactInfoImpl(List<IArtifactInfo> list){
+               List<ArtifactInfoImpl> ret = new ArrayList<ArtifactInfoImpl>();
+               if( list != null ){
+                       for(IArtifactInfo artifactInfo : list  ){
+                               ret.add(new ArtifactInfoImpl(artifactInfo));
+                       }
+               }
+               return ret;
+       }
+       
+       public String getArtifactName() {
+               return artifactName;
+       }
+
+       public void setArtifactName(String artifactName) {
+               this.artifactName = artifactName;
+       }
+
+       public String getArtifactType() {
+               return artifactType;
+       }
+
+       public void setArtifactType(String artifactType) {
+               this.artifactType = artifactType;
+       }
+
+       public String getArtifactURL() {
+               return artifactURL;
+       }
+
+       public void setArtifactURL(String artifactURL) {
+               this.artifactURL = artifactURL;
+       }
+
+       public String getArtifactChecksum() {
+               return artifactChecksum;
+       }
+
+       public void setArtifactChecksum(String artifactChecksum) {
+               this.artifactChecksum = artifactChecksum;
+       }
+
+       public String getArtifactDescription() {
+               return artifactDescription;
+       }
+
+       public void setArtifactDescription(String artifactDescription) {
+               this.artifactDescription = artifactDescription;
+       }
+
+       public Integer getArtifactTimeout() {
+               return artifactTimeout;
+       }
+
+       public void setArtifactTimeout(Integer artifactTimeout) {
+               this.artifactTimeout = artifactTimeout;
+       }
+
+       @Override
+       public String toString() {
+               return "BaseArtifactInfoImpl [artifactName=" + artifactName
+                               + ", artifactType=" + artifactType + ", artifactURL="
+                               + artifactURL + ", artifactChecksum=" + artifactChecksum
+                               + ", artifactDescription=" + artifactDescription
+                               + ", artifactVersion=" + artifactVersion
+                               + ", artifactUUID=" + artifactUUID
+                               + ", artifactTimeout=" + artifactTimeout + "]";
+       }
+
+       public String getArtifactVersion() {
+               return artifactVersion;
+       }
+
+       public void setArtifactVersion(String artifactVersion) {
+               this.artifactVersion = artifactVersion;
+       }
+
+       public String getArtifactUUID() {
+               return artifactUUID;
+       }
+
+       public void setArtifactUUID(String artifactUUID) {
+               this.artifactUUID = artifactUUID;
+       }
+
+       public String getGeneratedFromUUID() {
+               return generatedFromUUID;
+       }
+
+       public void setGeneratedFromUUID(String generatedFromUUID) {
+               this.generatedFromUUID = generatedFromUUID;
+       }
+       
+       public IArtifactInfo getGeneratedArtifact() {
+               return generatedArtifact;
+       }
+
+       public void setGeneratedArtifact(IArtifactInfo generatedArtifact) {
+               this.generatedArtifact = generatedArtifact;
+       }
+       
+       public List<IArtifactInfo> getRelatedArtifacts(){
+               List<IArtifactInfo> temp = new ArrayList<IArtifactInfo>();
+               if( relatedArtifactsInfo != null ){
+                       temp.addAll(relatedArtifactsInfo);
+               }
+               return temp;
+       }
+       
+       public void setRelatedArtifacts(List<String> relatedArtifacts) {
+               this.relatedArtifacts = relatedArtifacts;
+       }
+
+       public void setRelatedArtifactsInfo(List<IArtifactInfo> relatedArtifactsInfo) {
+               this.relatedArtifactsInfo = relatedArtifactsInfo;
+       }
+       
+       public List<String> getRelatedArtifactsUUID(){
+               return relatedArtifacts;
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/Configuration.java b/src/main/java/org/openecomp/sdc/impl/Configuration.java
new file mode 100644 (file)
index 0000000..3b8f3bd
--- /dev/null
@@ -0,0 +1,183 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import java.util.List;
+
+import org.openecomp.sdc.api.consumer.IConfiguration;
+import org.openecomp.sdc.utils.DistributionClientConstants;
+
+public class Configuration implements IConfiguration{
+
+       
+       private String asdcAddress;
+       private String user;
+       private String password;
+       private int pollingInterval = DistributionClientConstants.MIN_POLLING_INTERVAL_SEC;
+       private int pollingTimeout = DistributionClientConstants.POLLING_TIMEOUT_SEC;
+       private List<String> relevantArtifactTypes;
+       private String consumerGroup;
+       private String environmentName;
+       private String comsumerID;
+       private String keyStorePath;
+       private String keyStorePassword;
+       private boolean  activateServerTLSAuth;
+
+       public Configuration(IConfiguration other) {
+               this.asdcAddress = other.getAsdcAddress();
+               this.comsumerID = other.getConsumerID();
+               this.consumerGroup = other.getConsumerGroup();
+               this.environmentName = other.getEnvironmentName();
+               this.password = other.getPassword();
+               this.pollingInterval = other.getPollingInterval();
+               this.pollingTimeout = other.getPollingTimeout();
+               this.relevantArtifactTypes = other.getRelevantArtifactTypes();
+               this.user = other.getUser();
+               this.keyStorePath = other.getKeyStorePath();
+               this.keyStorePassword = other.getKeyStorePassword();
+               this.activateServerTLSAuth = other.activateServerTLSAuth();
+       }
+
+       @Override
+       public String getAsdcAddress() {
+               return asdcAddress;
+       }
+
+       @Override
+       public String getUser() {
+               return user;
+       }
+
+       @Override
+       public String getPassword() {
+               return password;
+       }
+
+       @Override
+       public int getPollingInterval() {
+               return pollingInterval;
+       }
+
+       @Override
+       public int getPollingTimeout() {
+               return pollingTimeout;
+       }
+
+       @Override
+       public List<String> getRelevantArtifactTypes() {
+               return relevantArtifactTypes;
+       }
+
+       @Override
+       public String getConsumerGroup() {
+               return consumerGroup;
+       }
+
+       @Override
+       public String getEnvironmentName() {
+               return environmentName;
+       }
+
+       @Override
+       public String getConsumerID() {
+               return comsumerID;
+       }
+       
+       @Override
+       public String getKeyStorePath() {
+               return keyStorePath;
+       }       
+
+       @Override
+       public String getKeyStorePassword() {
+               return keyStorePassword;
+       }
+
+       public String getComsumerID() {
+               return comsumerID;
+       }
+
+       public void setComsumerID(String comsumerID) {
+               this.comsumerID = comsumerID;
+       }
+
+       public void setAsdcAddress(String asdcAddress) {
+               this.asdcAddress = asdcAddress;
+       }
+
+       public void setUser(String user) {
+               this.user = user;
+       }
+
+       public void setPassword(String password) {
+               this.password = password;
+       }
+
+       public void setPollingInterval(int pollingInterval) {
+               this.pollingInterval = pollingInterval;
+       }
+
+       public void setPollingTimeout(int pollingTimeout) {
+               this.pollingTimeout = pollingTimeout;
+       }
+
+       public void setRelevantArtifactTypes(List<String> relevantArtifactTypes) {
+               this.relevantArtifactTypes = relevantArtifactTypes;
+       }
+
+       public void setConsumerGroup(String consumerGroup) {
+               this.consumerGroup = consumerGroup;
+       }
+
+       public void setEnvironmentName(String environmentName) {
+               this.environmentName = environmentName;
+       }
+       
+       public void setKeyStorePath(String keyStorePath) {
+               this.keyStorePath = keyStorePath;
+       }
+
+       public void setKeyStorePassword(String keyStorePassword) {
+               this.keyStorePassword = keyStorePassword;
+       }
+
+       @Override
+       public String toString() {
+               return "Configuration [asdcAddress=" + asdcAddress + ", user=" + user
+                               + ", password=" + password + ", pollingInterval="
+                               + pollingInterval + ", pollingTimeout=" + pollingTimeout
+                               + ", relevantArtifactTypes=" + relevantArtifactTypes
+                               + ", consumerGroup=" + consumerGroup + ", environmentName="
+                               + environmentName + ", comsumerID=" + comsumerID + "]";
+       }
+
+       
+       public void setactivateServerTLSAuth(boolean activateServerTLSAuth) {
+               this.activateServerTLSAuth = activateServerTLSAuth;
+       }
+
+       @Override
+       public boolean activateServerTLSAuth() {
+               
+               return this.activateServerTLSAuth;
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/DistributionClientDownloadResultImpl.java b/src/main/java/org/openecomp/sdc/impl/DistributionClientDownloadResultImpl.java
new file mode 100644 (file)
index 0000000..b69cb24
--- /dev/null
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+
+public class DistributionClientDownloadResultImpl  extends DistributionClientResultImpl implements IDistributionClientDownloadResult{
+       byte[] artifactPayload;
+       String artifactName;
+
+       
+       public DistributionClientDownloadResultImpl(
+                       DistributionActionResultEnum responseStatus, String responseMessage) {
+               super(responseStatus, responseMessage);
+               
+       }
+
+       public DistributionClientDownloadResultImpl(
+                       DistributionActionResultEnum responseStatus,
+                       String responseMessage, String artifactName, byte[] artifactPayload) {
+               super(responseStatus, responseMessage);
+               this.artifactPayload = artifactPayload;
+               this.artifactName = artifactName;
+       }
+
+
+       public void setArtifactPayload(byte[] payload) {
+               this.artifactPayload = payload;
+       }
+
+
+       public byte[] getArtifactPayload() {
+               
+               return artifactPayload;
+       } 
+       
+       public String getArtifactName(){
+               return artifactName;
+       }
+       
+       public void setArtifactName(String artifactName){
+               this.artifactName = artifactName;
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/DistributionClientFactory.java b/src/main/java/org/openecomp/sdc/impl/DistributionClientFactory.java
new file mode 100644 (file)
index 0000000..467f9cb
--- /dev/null
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.impl.mock.DistributionClientStubImpl;
+
+public class DistributionClientFactory {
+       public static IDistributionClient createDistributionClient(){
+               return new DistributionClientImpl();
+       }
+       
+       public static IDistributionClient createMockDistributionClient(){
+               return new DistributionClientStubImpl();
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/DistributionClientImpl.java b/src/main/java/org/openecomp/sdc/impl/DistributionClientImpl.java
new file mode 100644 (file)
index 0000000..ce74b26
--- /dev/null
@@ -0,0 +1,634 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.net.MalformedURLException;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.api.IDistributionStatusMessageJsonBuilder;
+import org.openecomp.sdc.api.consumer.IConfiguration;
+import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
+import org.openecomp.sdc.api.consumer.INotificationCallback;
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.notification.IVfModuleMetadata;
+import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.http.AsdcConnectorClient;
+import org.openecomp.sdc.http.TopicRegistrationResponse;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+import org.openecomp.sdc.utils.DistributionClientConstants;
+import org.openecomp.sdc.utils.Wrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.att.nsa.apiClient.credentials.ApiCredential;
+import com.att.nsa.apiClient.http.HttpException;
+import com.att.nsa.cambria.client.CambriaBatchingPublisher;
+import com.att.nsa.cambria.client.CambriaClient.CambriaApiException;
+import com.att.nsa.cambria.client.CambriaClientBuilders.PublisherBuilder;
+import com.att.nsa.cambria.client.CambriaClientBuilders.ConsumerBuilder;
+import com.att.nsa.cambria.client.CambriaClientBuilders.IdentityManagerBuilder;
+import com.att.nsa.cambria.client.CambriaConsumer;
+import com.att.nsa.cambria.client.CambriaIdentityManager;
+import com.att.nsa.cambria.client.CambriaPublisher.message;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+
+import fj.data.Either;
+
+public class DistributionClientImpl implements IDistributionClient {
+
+       private static Logger log = LoggerFactory.getLogger(DistributionClientImpl.class.getName());
+
+       protected AsdcConnectorClient asdcConnector = new AsdcConnectorClient();
+       private ScheduledExecutorService executorPool = null;
+       protected CambriaIdentityManager cambriaIdentityManager = null;
+       private List<String> brokerServers;
+       protected ApiCredential credential;
+       protected Configuration configuration;
+       private INotificationCallback callback;
+       private String notificationTopic;
+       private String statusTopic;
+       private boolean isConsumerGroupGenerated = false;
+
+       private boolean isInitialized, isStarted, isTerminated;
+
+       @Override
+       public IConfiguration getConfiguration() {
+               return configuration;
+       }
+
+       @Override
+       /* see javadoc */
+       public synchronized IDistributionClientResult updateConfiguration(IConfiguration conf) {
+
+               log.info("update DistributionClient configuration");
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateRunReady(errorWrapper);
+
+               if (!errorWrapper.isEmpty()) {
+                       return errorWrapper.getInnerElement();
+               }
+
+               IDistributionClientResult updateResult = new DistributionClientResultImpl(DistributionActionResultEnum.SUCCESS, "configuration updated successfuly");
+
+               boolean needToUpdateCambriaConsumer = false;
+
+               if (conf.getRelevantArtifactTypes() != null && !conf.getRelevantArtifactTypes().isEmpty()) {
+                       configuration.setRelevantArtifactTypes(conf.getRelevantArtifactTypes());
+                       needToUpdateCambriaConsumer = true;
+               }
+               if (isPollingIntervalValid(conf.getPollingInterval())) {
+                       configuration.setPollingInterval(conf.getPollingInterval());
+                       needToUpdateCambriaConsumer = true;
+               }
+               if (isPollingTimeoutValid(conf.getPollingTimeout())) {
+                       configuration.setPollingTimeout(conf.getPollingTimeout());
+                       needToUpdateCambriaConsumer = true;
+               }
+               if (conf.getConsumerGroup() != null) {
+                       configuration.setConsumerGroup(conf.getConsumerGroup());
+                       isConsumerGroupGenerated = false;
+                       needToUpdateCambriaConsumer = true;
+               } else if (!isConsumerGroupGenerated) {
+                       generateConsumerGroup();
+               }
+
+               if (needToUpdateCambriaConsumer) {
+                       updateResult = restartConsumer();
+               }
+
+               return updateResult;
+       }
+
+       @Override
+       /**
+        * Start polling the Notification topic
+        */
+       public synchronized IDistributionClientResult start() {
+
+               log.info("start DistributionClient");
+               CambriaConsumer cambriaConsumer = null;
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateRunReady(errorWrapper);
+               if (errorWrapper.isEmpty()) {
+                       validateNotStarted(errorWrapper);
+               }
+               if (errorWrapper.isEmpty()) {
+                       try {
+                               cambriaConsumer = new ConsumerBuilder().authenticatedBy(credential.getApiKey(), credential.getApiSecret()).knownAs(configuration.getConsumerGroup(), configuration.getConsumerID()).onTopic(notificationTopic).usingHosts(brokerServers)
+                                               .withSocketTimeout(configuration.getPollingTimeout() * 1000).build();
+                       } catch (MalformedURLException | GeneralSecurityException e) {
+                               handleCambriaInitFailure(errorWrapper, e);
+                       }
+               }
+
+               if (!errorWrapper.isEmpty()) {
+                       return errorWrapper.getInnerElement();
+               }
+
+               List<String> relevantArtifactTypes = configuration.getRelevantArtifactTypes();
+               // Remove nulls from list - workaround for how configuration is built
+               while (relevantArtifactTypes.remove(null));
+
+               NotificationConsumer consumer = new NotificationConsumer(cambriaConsumer, callback, relevantArtifactTypes, this);
+               executorPool = Executors.newScheduledThreadPool(DistributionClientConstants.POOL_SIZE);
+               executorPool.scheduleAtFixedRate(consumer, 0, configuration.getPollingInterval(), TimeUnit.SECONDS);
+
+               DistributionClientResultImpl startResult = new DistributionClientResultImpl(DistributionActionResultEnum.SUCCESS, "distribution client started successfuly");
+               isStarted = true;
+               return startResult;
+       }
+
+       @Override
+       /* see javadoc */
+       public synchronized IDistributionClientResult stop() {
+
+               log.info("stop DistributionClient");
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateRunReady(errorWrapper);
+               if (!errorWrapper.isEmpty()) {
+                       return errorWrapper.getInnerElement();
+               }
+               // 1. stop polling notification topic
+               shutdownExecutor();
+
+               // 2. send to ASDC unregister to topic
+               IDistributionClientResult unregisterResult = asdcConnector.unregisterTopics(credential);
+               if (unregisterResult.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+                       log.info("client failed to unregister from topics");
+               } else {
+                       log.info("client unregistered from topics successfully");
+               }
+               asdcConnector.close();
+
+               try {
+                       cambriaIdentityManager.deleteCurrentApiKey();
+               } catch (HttpException | IOException e) {
+                       log.debug("failed to delete cambria keys", e);
+               }
+               cambriaIdentityManager.close();
+
+               isInitialized = false;
+               isTerminated = true;
+
+               DistributionClientResultImpl stopResult = new DistributionClientResultImpl(DistributionActionResultEnum.SUCCESS, "distribution client stopped successfuly");
+               return stopResult;
+       }
+
+       @Override
+       public IDistributionClientDownloadResult download(IArtifactInfo artifactInfo) {
+               log.info("DistributionClient - download");
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateRunReady(errorWrapper);
+               if (!errorWrapper.isEmpty()) {
+                       IDistributionClientResult result = errorWrapper.getInnerElement();
+                       IDistributionClientDownloadResult downloadResult = new DistributionClientDownloadResultImpl(result.getDistributionActionResult(), result.getDistributionMessageResult());
+                       return downloadResult;
+               }
+               return asdcConnector.dowloadArtifact(artifactInfo);
+       }
+
+       @Override
+       /*
+        * see javadoc
+        */
+       public synchronized IDistributionClientResult init(IConfiguration conf, INotificationCallback callback) {
+
+               log.info("DistributionClient - init");
+
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateNotInitilized(errorWrapper);
+               if (errorWrapper.isEmpty()) {
+                       validateNotTerminated(errorWrapper);
+               }
+               if (errorWrapper.isEmpty()) {
+                       validateAndInitConfiguration(errorWrapper, conf);
+               }
+               // 1. get servers list from ASDC
+               if (errorWrapper.isEmpty()) {
+                       initUebServerList(errorWrapper);
+               }
+               // 2.validate artifact types against asdc server
+               if (errorWrapper.isEmpty()) {
+                       validateArtifactTypesWithAsdcServer(conf, errorWrapper);
+               }
+               // 3. create keys
+               if (errorWrapper.isEmpty()) {
+                       this.callback = callback;
+                       createUebKeys(errorWrapper);
+               }
+               // 4. register for topics
+               if (errorWrapper.isEmpty()) {
+                       registerForTopics(errorWrapper);
+               }
+
+               IDistributionClientResult result;
+               if (errorWrapper.isEmpty()) {
+                       isInitialized = true;
+                       result = new DistributionClientResultImpl(DistributionActionResultEnum.SUCCESS, "distribution client initialized successfuly");
+               } else {
+                       result = errorWrapper.getInnerElement();
+               }
+
+               return result;
+       }
+
+       private void registerForTopics(Wrapper<IDistributionClientResult> errorWrapper) {
+               Either<TopicRegistrationResponse, DistributionClientResultImpl> registerAsdcTopics = asdcConnector.registerAsdcTopics(credential);
+               if (registerAsdcTopics.isRight()) {
+
+                       try {
+                               cambriaIdentityManager.deleteCurrentApiKey();
+                       } catch (HttpException | IOException e) {
+                               log.debug("failed to delete cambria keys", e);
+                       }
+                       errorWrapper.setInnerElement(registerAsdcTopics.right().value());
+               } else {
+                       TopicRegistrationResponse topics = registerAsdcTopics.left().value();
+                       notificationTopic = topics.getDistrNotificationTopicName();
+                       statusTopic = topics.getDistrStatusTopicName();
+               }
+
+       }
+
+       private void createUebKeys(Wrapper<IDistributionClientResult> errorWrapper) {
+               initCambriaClient(errorWrapper);
+               if (errorWrapper.isEmpty()) {
+                       log.debug("create keys");
+                       DistributionClientResultImpl createKeysResponse = createUebKeys();
+                       if (createKeysResponse.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+                               errorWrapper.setInnerElement(createKeysResponse);
+                       }
+               }
+       }
+
+       private void validateArtifactTypesWithAsdcServer(IConfiguration conf, Wrapper<IDistributionClientResult> errorWrapper) {
+               Either<List<String>, IDistributionClientResult> eitherValidArtifactTypesList = asdcConnector.getValidArtifactTypesList();
+               if (eitherValidArtifactTypesList.isRight()) {
+                       DistributionActionResultEnum errorType = eitherValidArtifactTypesList.right().value().getDistributionActionResult();
+                       // Support the case of a new client and older ASDC Server which does not have the API
+                       if (errorType != DistributionActionResultEnum.ASDC_NOT_FOUND) {
+                               errorWrapper.setInnerElement(eitherValidArtifactTypesList.right().value());
+                       }
+               } else {
+                       final List<String> artifactTypesFromAsdc = eitherValidArtifactTypesList.left().value();
+                       boolean isArtifactTypesValid = artifactTypesFromAsdc.containsAll(conf.getRelevantArtifactTypes());
+                       if (!isArtifactTypesValid) {
+                               List<String> invalidArtifactTypes = new ArrayList<>();
+                               invalidArtifactTypes.addAll(conf.getRelevantArtifactTypes());
+                               invalidArtifactTypes.removeAll(artifactTypesFromAsdc);
+                               DistributionClientResultImpl errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.CONF_CONTAINS_INVALID_ARTIFACT_TYPES,
+                                               "configuration contains invalid artifact types:" + invalidArtifactTypes + " valid types are:" + artifactTypesFromAsdc);
+                               errorWrapper.setInnerElement(errorResponse);
+                       } else {
+                               log.debug("Artifact types: {} were validated with ASDC server", conf.getRelevantArtifactTypes());
+                       }
+               }
+       }
+
+       private void initUebServerList(Wrapper<IDistributionClientResult> errorWrapper) {
+               log.debug("get cluster server list from ASDC");
+               asdcConnector.init(configuration);
+
+               Either<List<String>, IDistributionClientResult> serverListResponse = asdcConnector.getServerList();
+               if (serverListResponse.isRight()) {
+                       errorWrapper.setInnerElement(serverListResponse.right().value());
+               } else {
+                       brokerServers = serverListResponse.left().value();
+               }
+       }
+
+       private void validateNotInitilized(Wrapper<IDistributionClientResult> errorWrapper) {
+               if (isInitialized) {
+                       log.warn("distribution client already initialized");
+                       DistributionClientResultImpl alreadyInitResponse = new DistributionClientResultImpl(DistributionActionResultEnum.DISTRIBUTION_CLIENT_ALREADY_INITIALIZED, "distribution client already initialized");
+                       errorWrapper.setInnerElement(alreadyInitResponse);
+               }
+       }
+
+       @Override
+       public IDistributionClientResult sendDownloadStatus(IDistributionStatusMessage statusMessage) {
+               log.info("DistributionClient - sendDownloadStatus");
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateRunReady(errorWrapper);
+               if (!errorWrapper.isEmpty()) {
+                       return errorWrapper.getInnerElement();
+               }
+
+               return sendStatus(DistributionStatusMessageJsonBuilderFactory.getSimpleBuilder(statusMessage));
+       }
+
+       private IDistributionClientResult sendStatus(IDistributionStatusMessageJsonBuilder builder) {
+               DistributionClientResultImpl statusResult = new DistributionClientResultImpl(DistributionActionResultEnum.GENERAL_ERROR, "Failed to send status");
+               log.info("DistributionClient - sendStatus");
+               Either<CambriaBatchingPublisher, IDistributionClientResult> eitherPublisher = getCambriaPublisher();
+               if (eitherPublisher.isRight()) {
+                       return eitherPublisher.right().value();
+               }
+               CambriaBatchingPublisher pub = eitherPublisher.left().value();
+
+               log.debug("after create publisher server list " + brokerServers.toString());
+               String jsonRequest = builder.build();
+
+               log.debug("try to send status " + jsonRequest);
+
+               try {
+                       pub.send("MyPartitionKey", jsonRequest);
+                       Thread.sleep(1000L);
+               } catch (IOException e) {
+                       log.debug("DistributionClient - sendDownloadStatus. Failed to send download status");
+               } catch (InterruptedException e) {
+                       log.debug("DistributionClient - sendDownloadStatus. thread was interrupted");
+               }
+
+               finally {
+
+                       try {
+                               List<message> stuck = pub.close(10L, TimeUnit.SECONDS);
+
+                               if (!stuck.isEmpty()) {
+                                       log.debug("DistributionClient - sendDownloadStatus. " + stuck.size() + " messages unsent");
+                               } else {
+                                       statusResult = new DistributionClientResultImpl(DistributionActionResultEnum.SUCCESS, "messages successfully sent");
+                               }
+                       } catch (IOException | InterruptedException e) {
+                               log.debug("DistributionClient - sendDownloadStatus. failed to send messages and close publisher ");
+                       }
+
+               }
+               return statusResult;
+       }
+
+       private Either<CambriaBatchingPublisher, IDistributionClientResult> getCambriaPublisher() {
+               CambriaBatchingPublisher cambriaPublisher = null;
+                       try {
+                               cambriaPublisher = new PublisherBuilder().onTopic(statusTopic).usingHosts(brokerServers).build();
+                               cambriaPublisher.setApiCredentials(credential.getApiKey(), credential.getApiSecret());
+                       } catch (MalformedURLException | GeneralSecurityException e) {
+                               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+                               handleCambriaInitFailure(errorWrapper, e);
+                               return Either.right(errorWrapper.getInnerElement());
+                       }
+               return Either.left(cambriaPublisher);
+       }
+
+       @Override
+       public IDistributionClientResult sendDeploymentStatus(IDistributionStatusMessage statusMessage) {
+               log.info("DistributionClient - sendDeploymentStatus");
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateRunReady(errorWrapper);
+               if (!errorWrapper.isEmpty()) {
+                       return errorWrapper.getInnerElement();
+               }
+               return sendStatus(DistributionStatusMessageJsonBuilderFactory.getSimpleBuilder(statusMessage));
+       }
+
+       IDistributionClientResult sendNotificationStatus(long currentTimeMillis, String distributionId, ArtifactInfoImpl artifactInfo, boolean isNotified) {
+               log.info("DistributionClient - sendNotificationStatus");
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateRunReady(errorWrapper);
+               if (!errorWrapper.isEmpty()) {
+                       return errorWrapper.getInnerElement();
+               }
+               return sendStatus(DistributionStatusMessageJsonBuilderFactory.prepareBuilderForNotificationStatus(getConfiguration().getConsumerID(), currentTimeMillis, distributionId, artifactInfo, isNotified));
+       }
+
+       /* *************************** Private Methods *************************************************** */
+
+       protected DistributionClientResultImpl createUebKeys() {
+               DistributionClientResultImpl response = new DistributionClientResultImpl(DistributionActionResultEnum.SUCCESS, "keys created successfuly");
+               try {
+                       String description = String.format(DistributionClientConstants.CLIENT_DESCRIPTION, configuration.getConsumerID());
+                       credential = cambriaIdentityManager.createApiKey(DistributionClientConstants.EMAIL, description);
+                       cambriaIdentityManager.setApiCredentials(credential.getApiKey(), credential.getApiSecret());
+
+               } catch (HttpException | CambriaApiException | IOException e) {
+                       response = new DistributionClientResultImpl(DistributionActionResultEnum.UEB_KEYS_CREATION_FAILED, "failed to create keys: " + e.getMessage());
+                       log.error(response.toString());
+               }
+               return response;
+       }
+
+       private IDistributionClientResult restartConsumer() {
+               shutdownExecutor();
+               return start();
+       }
+
+       protected DistributionActionResultEnum validateAndInitConfiguration(Wrapper<IDistributionClientResult> errorWrapper, IConfiguration conf) {
+               DistributionActionResultEnum result = DistributionActionResultEnum.SUCCESS;
+
+               if (conf == null) {
+                       result = DistributionActionResultEnum.CONFIGURATION_IS_MISSING;
+               } else if (conf.getConsumerID() == null || conf.getConsumerID().isEmpty()) {
+                       result = DistributionActionResultEnum.CONF_MISSING_CONSUMER_ID;
+               } else if (conf.getUser() == null || conf.getUser().isEmpty()) {
+                       result = DistributionActionResultEnum.CONF_MISSING_USERNAME;
+               } else if (conf.getPassword() == null || conf.getPassword().isEmpty()) {
+                       result = DistributionActionResultEnum.CONF_MISSING_PASSWORD;
+               } else if (conf.getAsdcAddress() == null || conf.getAsdcAddress().isEmpty()) {
+                       result = DistributionActionResultEnum.CONF_MISSING_ASDC_FQDN;
+               } else if (!isValidFqdn(conf.getAsdcAddress())) {
+                       result = DistributionActionResultEnum.CONF_INVALID_ASDC_FQDN;
+               } else if (conf.getEnvironmentName() == null || conf.getEnvironmentName().isEmpty()) {
+                       result = DistributionActionResultEnum.CONF_MISSING_ENVIRONMENT_NAME;
+               } else if (conf.getRelevantArtifactTypes() == null || conf.getRelevantArtifactTypes().isEmpty()) {
+                       result = DistributionActionResultEnum.CONF_MISSING_ARTIFACT_TYPES;
+               }
+               // DistributionActionResultEnum.SUCCESS
+               else {
+                       this.configuration = new Configuration(conf);
+                       if (!isPollingIntervalValid(conf.getPollingInterval())) {
+                               configuration.setPollingInterval(DistributionClientConstants.MIN_POLLING_INTERVAL_SEC);
+                       }
+                       if (!isPollingTimeoutValid(conf.getPollingTimeout())) {
+                               configuration.setPollingTimeout(DistributionClientConstants.POLLING_TIMEOUT_SEC);
+                       }
+                       if (conf.getConsumerGroup() == null) {
+                               generateConsumerGroup();
+                       }
+               }
+
+               if (result != DistributionActionResultEnum.SUCCESS) {
+
+                       DistributionClientResultImpl initResult = new DistributionClientResultImpl(result, "configuration is invalid: " + result.name());
+
+                       log.error(initResult.toString());
+                       errorWrapper.setInnerElement(initResult);
+               }
+               return result;
+       }
+
+       private void generateConsumerGroup() {
+               String generatedConsumerGroup = UUID.randomUUID().toString();
+               configuration.setConsumerGroup(generatedConsumerGroup);
+               isConsumerGroupGenerated = true;
+       }
+
+       protected boolean isValidFqdn(String fqdn) {
+               try {
+                       Matcher matcher = DistributionClientConstants.FQDN_PATTERN.matcher(fqdn);
+                       return matcher.matches();
+               } catch (Exception e) {
+               }
+               return false;
+       }
+
+       private void shutdownExecutor() {
+               if (executorPool == null)
+                       return;
+
+               executorPool.shutdown(); // Disable new tasks from being submitted
+               try {
+                       // Wait a while for existing tasks to terminate
+                       if (!executorPool.awaitTermination(60, TimeUnit.SECONDS)) {
+                               executorPool.shutdownNow(); // Cancel currently executing tasks
+                               // Wait a while for tasks to respond to being cancelled
+                               if (!executorPool.awaitTermination(60, TimeUnit.SECONDS))
+                                       log.error("Pool did not terminate");
+                       }
+               } catch (InterruptedException ie) {
+                       // (Re-)Cancel if current thread also interrupted
+                       executorPool.shutdownNow();
+                       // Preserve interrupt status
+                       Thread.currentThread().interrupt();
+               } finally {
+                       isStarted = false;
+               }
+       }
+
+       private void validateRunReady(Wrapper<IDistributionClientResult> errorWrapper) {
+               if (errorWrapper.isEmpty()) {
+                       validateInitilized(errorWrapper);
+               }
+               if (errorWrapper.isEmpty()) {
+                       validateNotTerminated(errorWrapper);
+               }
+
+       }
+
+       private void validateInitilized(Wrapper<IDistributionClientResult> errorWrapper) {
+               if (!isInitialized) {
+                       log.debug("client was not initialized");
+                       IDistributionClientResult result = new DistributionClientResultImpl(DistributionActionResultEnum.DISTRIBUTION_CLIENT_NOT_INITIALIZED, "distribution client was not initialized");
+                       errorWrapper.setInnerElement(result);
+               }
+       }
+
+       private void validateNotStarted(Wrapper<IDistributionClientResult> errorWrapper) {
+               if (isStarted) {
+                       log.debug("client already started");
+                       IDistributionClientResult result = new DistributionClientResultImpl(DistributionActionResultEnum.DISTRIBUTION_CLIENT_ALREADY_STARTED, "distribution client already started");
+                       errorWrapper.setInnerElement(result);
+               }
+       }
+
+       private void validateNotTerminated(Wrapper<IDistributionClientResult> errorWrapper) {
+               if (isTerminated) {
+                       log.debug("client was terminated");
+                       IDistributionClientResult result = new DistributionClientResultImpl(DistributionActionResultEnum.DISTRIBUTION_CLIENT_IS_TERMINATED, "distribution client was terminated");
+                       errorWrapper.setInnerElement(result);
+               }
+       }
+
+       private boolean isPollingTimeoutValid(int timeout) {
+               boolean isValid = (timeout >= DistributionClientConstants.POLLING_TIMEOUT_SEC);
+               if (!isValid) {
+                       log.warn("polling interval is out of range. value should be greater than or equals to " + DistributionClientConstants.POLLING_TIMEOUT_SEC);
+                       log.warn("setting polling interval to default: " + DistributionClientConstants.POLLING_TIMEOUT_SEC);
+               }
+               return isValid;
+       }
+
+       private boolean isPollingIntervalValid(int pollingInt) {
+               boolean isValid = (pollingInt >= DistributionClientConstants.MIN_POLLING_INTERVAL_SEC);
+               if (!isValid) {
+                       log.warn("polling interval is out of range. value should be greater than or equals to " + DistributionClientConstants.MIN_POLLING_INTERVAL_SEC);
+                       log.warn("setting polling interval to default: " + DistributionClientConstants.MIN_POLLING_INTERVAL_SEC);
+               }
+               return isValid;
+       }
+
+       private synchronized void initCambriaClient(Wrapper<IDistributionClientResult> errorWrapper) {
+               if (cambriaIdentityManager == null) {
+                       try {
+                               cambriaIdentityManager = new IdentityManagerBuilder().usingHosts(brokerServers).build();
+                       } catch (MalformedURLException | GeneralSecurityException e) {
+                               handleCambriaInitFailure(errorWrapper, e);
+                       }
+               }
+       }
+
+       private void handleCambriaInitFailure(Wrapper<IDistributionClientResult> errorWrapper, Exception e) {
+               final String errorMessage = "Failed initilizing cambria component:" + e.getMessage();
+               IDistributionClientResult errorResponse = new DistributionClientResultImpl(DistributionActionResultEnum.CAMBRIA_INIT_FAILED, errorMessage);
+               errorWrapper.setInnerElement(errorResponse);
+               log.error(errorMessage);
+               log.debug(errorMessage, e);
+       }
+
+       @Override
+       public IDistributionClientResult sendDownloadStatus(IDistributionStatusMessage statusMessage, String errorReason) {
+               log.info("DistributionClient - sendDownloadStatus with errorReason");
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateRunReady(errorWrapper);
+               if (!errorWrapper.isEmpty()) {
+                       return errorWrapper.getInnerElement();
+               }
+
+               return sendStatus(DistributionStatusMessageJsonBuilderFactory.getErrorReasonBuilder(statusMessage, errorReason));
+
+       }
+
+       @Override
+       public IDistributionClientResult sendDeploymentStatus(IDistributionStatusMessage statusMessage, String errorReason) {
+               log.info("DistributionClient - sendDeploymentStatus with errorReason");
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               validateRunReady(errorWrapper);
+               if (!errorWrapper.isEmpty()) {
+                       return errorWrapper.getInnerElement();
+               }
+               return sendStatus(DistributionStatusMessageJsonBuilderFactory.getErrorReasonBuilder(statusMessage, errorReason));
+
+       }
+
+       @Override
+       public List<IVfModuleMetadata> decodeVfModuleArtifact(byte[] artifactPayload) {
+               Gson gson = new GsonBuilder().setPrettyPrinting().create();
+               String vfModuleJsonString = new String(artifactPayload, StandardCharsets.UTF_8);
+               final Type type = new TypeToken<List<VfModuleMetadata>>() {
+               }.getType();
+               List<IVfModuleMetadata> vfModules = gson.fromJson(vfModuleJsonString, type);
+               return vfModules;
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/DistributionClientResultImpl.java b/src/main/java/org/openecomp/sdc/impl/DistributionClientResultImpl.java
new file mode 100644 (file)
index 0000000..a5af31a
--- /dev/null
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+
+public class DistributionClientResultImpl implements IDistributionClientResult {
+
+       DistributionActionResultEnum responseStatus;
+       String responseMessage;
+
+       public DistributionClientResultImpl(DistributionActionResultEnum responseStatus, String responseMessage) {
+               this.responseStatus = responseStatus;
+               this.responseMessage = responseMessage;
+       }
+
+       @Override
+       public DistributionActionResultEnum getDistributionActionResult() {
+               return responseStatus;
+       }
+
+       @Override
+       public String getDistributionMessageResult() {
+               return responseMessage;
+       }
+
+       @Override
+       public String toString() {
+               return "DistributionClientResultImpl [responseStatus=" + responseStatus + ", responseMessage=" + responseMessage + "]";
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/DistributionStatusMessageImpl.java b/src/main/java/org/openecomp/sdc/impl/DistributionStatusMessageImpl.java
new file mode 100644 (file)
index 0000000..d570142
--- /dev/null
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
+import org.openecomp.sdc.utils.DistributionStatusEnum;
+
+class DistributionStatusMessageImpl implements IDistributionStatusMessage {
+       
+       
+       String distributionID;
+       String consumerID;
+       long timestamp;
+       String artifactURL;
+       DistributionStatusEnum status;
+       String errorReason;
+       
+       
+       public DistributionStatusMessageImpl(IDistributionStatusMessage message){
+               super();
+               distributionID = message.getDistributionID();
+               consumerID = message.getConsumerID();
+               timestamp = message.getTimestamp();
+               artifactURL = message.getArtifactURL();
+               status = message.getStatus();
+               
+       }
+
+       @Override
+       public String getDistributionID() {
+               
+               return distributionID;
+       }
+
+       @Override
+       public String getConsumerID() {
+               
+               return consumerID;
+       }
+
+       @Override
+       public long getTimestamp() {
+               
+               return timestamp;
+       }
+
+       @Override
+       public String getArtifactURL() {
+               
+               return artifactURL;
+       }
+
+       @Override
+       public DistributionStatusEnum getStatus() {
+               
+               return status;
+       }
+
+       public void setDistributionID(String distributionID) {
+               this.distributionID = distributionID;
+       }
+
+       public void setConsumerID(String consumerID) {
+               this.consumerID = consumerID;
+       }
+
+       public void setTimestamp(long timestamp) {
+               this.timestamp = timestamp;
+       }
+
+       public void setArtifactURL(String artifactURL) {
+               this.artifactURL = artifactURL;
+       }
+
+       public void setStatus(DistributionStatusEnum status) {
+               this.status = status;
+       }
+
+       public String getErrorReason() {
+               return errorReason;
+       }
+
+       public void setErrorReason(String errorReason) {
+               this.errorReason = errorReason;
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/DistributionStatusMessageJsonBuilderFactory.java b/src/main/java/org/openecomp/sdc/impl/DistributionStatusMessageJsonBuilderFactory.java
new file mode 100644 (file)
index 0000000..9d97805
--- /dev/null
@@ -0,0 +1,117 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import org.openecomp.sdc.api.IDistributionStatusMessageJsonBuilder;
+import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
+import org.openecomp.sdc.utils.DistributionStatusEnum;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class DistributionStatusMessageJsonBuilderFactory {
+       static Gson gson = new GsonBuilder().setPrettyPrinting().create();
+       
+       public static IDistributionStatusMessageJsonBuilder getSimpleBuilder(IDistributionStatusMessage statusMessage){
+               DistributionStatusMessageImpl message = new DistributionStatusMessageImpl(statusMessage);
+               
+               return prepareBuilderFromImpl(message);
+       }
+       
+       public static IDistributionStatusMessageJsonBuilder getErrorReasonBuilder(IDistributionStatusMessage statusMessage, String errorReason){
+               DistributionStatusMessageImpl message = new DistributionStatusMessageImpl(statusMessage);
+               message.setErrorReason(errorReason);
+               
+               return prepareBuilderFromImpl(message);
+       }
+       
+       static IDistributionStatusMessageJsonBuilder prepareBuilderForNotificationStatus(final String consumerId, final long currentTimeMillis, final String distributionId,
+                       final ArtifactInfoImpl artifactInfo, boolean isNotified){
+               
+               final DistributionStatusEnum fakeStatusToReplace = DistributionStatusEnum.DOWNLOAD_OK;
+               final String jsonRequest = buildDistributionStatusJson(consumerId, currentTimeMillis, distributionId, artifactInfo, fakeStatusToReplace);
+               
+               DistributionStatusNotificationEnum notificationStatus = isNotified ? DistributionStatusNotificationEnum.NOTIFIED : DistributionStatusNotificationEnum.NOT_NOTIFIED;
+               final String changedRequest = jsonRequest.replace(fakeStatusToReplace.name(), notificationStatus.name());
+               IDistributionStatusMessageJsonBuilder builder = new IDistributionStatusMessageJsonBuilder() {
+                       @Override
+                       public String build() {
+                               return changedRequest;
+                       }
+               };
+               return builder;
+               
+       }
+
+       private static String buildDistributionStatusJson(final String consumerId,
+                       final long currentTimeMillis, final String distributionId,
+                       final ArtifactInfoImpl artifactInfo,
+                       final DistributionStatusEnum fakeStatusToBeReplaced) {
+               IDistributionStatusMessage statusMessage = new IDistributionStatusMessage() {
+                       @Override
+                       public long getTimestamp() {
+                               return currentTimeMillis;
+                       }
+                       
+                       @Override
+                       public DistributionStatusEnum getStatus() {
+                               
+                               return fakeStatusToBeReplaced;
+                       }
+                       
+                       @Override
+                       public String getDistributionID() {
+                               return distributionId;
+                       }
+                       
+                       @Override
+                       public String getConsumerID() {
+                               return consumerId;
+                       }
+                       
+                       @Override
+                       public String getArtifactURL() {
+                               return artifactInfo.getArtifactURL();
+                       }
+               };
+               
+               DistributionStatusMessageImpl message = new DistributionStatusMessageImpl(statusMessage);
+               final String jsonRequest = gson.toJson(message);
+               return jsonRequest;
+       }
+       
+       private static IDistributionStatusMessageJsonBuilder prepareBuilderFromImpl( DistributionStatusMessageImpl message) {
+               final String jsonRequest = gson.toJson(message);
+               IDistributionStatusMessageJsonBuilder builder = new IDistributionStatusMessageJsonBuilder() {
+                       @Override
+                       public String build() {
+                               return jsonRequest;
+                       }
+               };
+               return builder;
+       }
+       
+       private enum DistributionStatusNotificationEnum {
+               NOTIFIED, NOT_NOTIFIED
+       }
+       
+       
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/JsonContainerResourceInstance.java b/src/main/java/org/openecomp/sdc/impl/JsonContainerResourceInstance.java
new file mode 100644 (file)
index 0000000..68d557c
--- /dev/null
@@ -0,0 +1,124 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.notification.IResourceInstance;
+
+class JsonContainerResourceInstance implements IResourceInstance{
+       JsonContainerResourceInstance (){}
+       private String resourceInstanceName, resourceName, resourceVersion, resoucreType, resourceUUID, resourceInvariantUUID;;
+       private List<ArtifactInfoImpl> artifacts;
+       
+       private JsonContainerResourceInstance(IResourceInstance resourceInstance){
+               resourceInstanceName = resourceInstance.getResourceInstanceName();
+               resourceName = resourceInstance.getResourceName();
+               resourceVersion = resourceInstance.getResourceVersion();
+               resoucreType = resourceInstance.getResourceType();
+               resourceUUID = resourceInstance.getResourceUUID();
+               resourceInvariantUUID = resourceInstance.getResourceInvariantUUID();
+               artifacts = ArtifactInfoImpl.convertToArtifactInfoImpl(resourceInstance.getArtifacts());
+       }
+       
+       public static List<JsonContainerResourceInstance> convertToJsonContainer(List<IResourceInstance> resources){
+                List<JsonContainerResourceInstance> buildResources = new ArrayList<JsonContainerResourceInstance>();
+                if( resources != null ){
+                        for( IResourceInstance resourceInstance : resources ){
+                                buildResources.add(new JsonContainerResourceInstance(resourceInstance));
+                        }
+                }
+                return buildResources;
+       }
+       
+       @Override
+       public String getResourceInstanceName() {
+               return resourceInstanceName;
+       }
+
+       public void setResourceInstanceName(String resourceInstanceName) {
+               this.resourceInstanceName = resourceInstanceName;
+       }
+       
+       @Override
+       public String getResourceName() {
+               return resourceName;
+       }
+
+       public void setResourceName(String resourceName) {
+               this.resourceName = resourceName;
+       }
+
+       @Override
+       public String getResourceVersion() {
+               return resourceVersion;
+       }
+
+       public void setResourceVersion(String resourceVersion) {
+               this.resourceVersion = resourceVersion;
+       }
+
+       @Override
+       public String getResourceType() {
+               return resoucreType;
+       }
+
+       public void setResoucreType(String resoucreType) {
+               this.resoucreType = resoucreType;
+       }
+
+       @Override
+       public String getResourceUUID() {
+               return resourceUUID;
+       }
+
+       public void setResourceUUID(String resourceUUID) {
+               this.resourceUUID = resourceUUID;
+       }
+
+       @Override
+       public List<IArtifactInfo> getArtifacts() {
+               List<IArtifactInfo> temp = new ArrayList<IArtifactInfo>();
+               if( artifacts != null ){
+                       temp.addAll(artifacts);
+               }
+               return temp;
+       }
+
+       public void setArtifacts(List<ArtifactInfoImpl> artifacts) {
+               this.artifacts = artifacts;
+       }
+       
+       public List<ArtifactInfoImpl> getArtifactsImpl(){
+               return artifacts;
+       }
+       
+       @Override
+       public String getResourceInvariantUUID() {
+               return resourceInvariantUUID;
+       }
+       
+       public void setResourceInvariantUUID(String resourceInvariantUUID) {
+               this.resourceInvariantUUID = resourceInvariantUUID;
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/NotificationConsumer.java b/src/main/java/org/openecomp/sdc/impl/NotificationConsumer.java
new file mode 100644 (file)
index 0000000..d337650
--- /dev/null
@@ -0,0 +1,180 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openecomp.sdc.api.consumer.INotificationCallback;
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.notification.INotificationData;
+import org.openecomp.sdc.api.notification.IResourceInstance;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.utils.ArtifactTypeEnum;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.att.nsa.cambria.client.CambriaConsumer;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+class NotificationConsumer implements Runnable {
+
+       private static Logger log = LoggerFactory.getLogger(NotificationConsumer.class.getName());
+
+       private CambriaConsumer cambriaConsumer;
+       private INotificationCallback clientCallback;
+       private List<String> artifactsTypes;
+       private DistributionClientImpl distributionClient;
+
+       public NotificationConsumer(CambriaConsumer cambriaConsumer, INotificationCallback clientCallback, List<String> artifactsTypes, DistributionClientImpl distributionClient) {
+               this.cambriaConsumer = cambriaConsumer;
+               this.clientCallback = clientCallback;
+               this.artifactsTypes = artifactsTypes;
+               this.distributionClient = distributionClient;
+       }
+
+       @Override
+       public void run() {
+
+               try {
+                       Gson gson = new GsonBuilder().setPrettyPrinting().create();
+                       long currentTimeMillis = System.currentTimeMillis();
+                       for (String notificationMsg : cambriaConsumer.fetch()) {
+                               log.debug("received message from topic");
+                               log.debug("recieved notification from broker: {}", notificationMsg);
+
+                               final NotificationDataImpl notificationFromUEB = gson.fromJson(notificationMsg, NotificationDataImpl.class);
+                               NotificationDataImpl notificationForCallback = buildCallbackNotificationLogic(currentTimeMillis, notificationFromUEB);
+                               if (isActivateCallback(notificationForCallback)) {
+                                       log.debug("sending notification to client: {}", notificationForCallback);
+                                       clientCallback.activateCallback(notificationForCallback);
+                               }
+                       }
+
+               } catch (Exception e) {
+                       log.error("Error exception occured when fetching with Cambria Client:{}", e.getMessage());
+                       log.debug("Error exception occured when fetching with Cambria Client:{}", e.getMessage(), e);
+               }
+       }
+
+       private boolean isActivateCallback(NotificationDataImpl notificationForCallback) {
+               boolean hasRelevantArtifactsInResourceInstance = notificationForCallback.getResources() != null && !notificationForCallback.getResources().isEmpty();
+               boolean hasRelevantArtifactsInService = notificationForCallback.getServiceArtifacts() != null && !notificationForCallback.getServiceArtifacts().isEmpty();
+
+               return hasRelevantArtifactsInResourceInstance || hasRelevantArtifactsInService;
+       }
+
+       private NotificationDataImpl buildCallbackNotificationLogic(long currentTimeMillis, final NotificationDataImpl notificationFromUEB) {
+               List<IResourceInstance> relevantResourceInstances = buildResourceInstancesLogic(notificationFromUEB, currentTimeMillis);
+               List<ArtifactInfoImpl> relevantServiceArtifacts = handleRelevantArtifacts(notificationFromUEB, currentTimeMillis, notificationFromUEB.getServiceArtifactsImpl());
+               notificationFromUEB.setResources(relevantResourceInstances);
+               notificationFromUEB.setServiceArtifacts(relevantServiceArtifacts);
+               return notificationFromUEB;
+       }
+
+       private List<IResourceInstance> buildResourceInstancesLogic(NotificationDataImpl notificationFromUEB, long currentTimeMillis) {
+
+               List<IResourceInstance> relevantResourceInstances = new ArrayList<>();
+
+               for (JsonContainerResourceInstance resourceInstance : notificationFromUEB.getResourcesImpl()) {
+                       final List<ArtifactInfoImpl> artifactsImplList = resourceInstance.getArtifactsImpl();
+                       List<ArtifactInfoImpl> foundRelevantArtifacts = handleRelevantArtifacts(notificationFromUEB, currentTimeMillis, artifactsImplList);
+                       if (!foundRelevantArtifacts.isEmpty()) {
+                               resourceInstance.setArtifacts(foundRelevantArtifacts);
+                               relevantResourceInstances.add(resourceInstance);
+                       }
+               }
+               return relevantResourceInstances;
+
+       }
+
+       private List<ArtifactInfoImpl> handleRelevantArtifacts(NotificationDataImpl notificationFromUEB, long currentTimeMillis, final List<ArtifactInfoImpl> artifactsImplList) {
+               List<ArtifactInfoImpl> relevantArtifacts = new ArrayList<>();
+               if (artifactsImplList != null) {
+                       for (ArtifactInfoImpl artifactInfo : artifactsImplList) {
+                               handleRelevantArtifact(notificationFromUEB, currentTimeMillis, artifactsImplList, relevantArtifacts, artifactInfo);
+                       }
+               }
+               return relevantArtifacts;
+       }
+
+       private void handleRelevantArtifact(NotificationDataImpl notificationFromUEB, long currentTimeMillis, final List<ArtifactInfoImpl> artifactsImplList, List<ArtifactInfoImpl> relevantArtifacts, ArtifactInfoImpl artifactInfo) {
+               boolean isArtifactRelevant = artifactsTypes.contains(artifactInfo.getArtifactType());
+               String artifactType = artifactInfo.getArtifactType();
+               if (artifactInfo.getGeneratedFromUUID() != null && !artifactInfo.getGeneratedFromUUID().isEmpty()) {
+                       IArtifactInfo generatedFromArtInfo = findGeneratedFromArtifact(artifactInfo.getGeneratedFromUUID(), artifactsImplList);
+                       if (generatedFromArtInfo != null)
+                               isArtifactRelevant = isArtifactRelevant && artifactsTypes.contains(generatedFromArtInfo.getArtifactType());
+                       else
+                               isArtifactRelevant = false;
+               }
+               if (isArtifactRelevant) {
+                       setRelatedArtifacts(artifactInfo, notificationFromUEB);
+                       if (artifactType.equals(ArtifactTypeEnum.HEAT.name()) || artifactType.equals(ArtifactTypeEnum.HEAT_VOL.name()) || artifactType.equals(ArtifactTypeEnum.HEAT_NET.name())) {
+                               setGeneratedArtifact(artifactsImplList, artifactInfo);
+                       }
+                       relevantArtifacts.add(artifactInfo);
+
+               }
+               IDistributionClientResult notificationStatus = distributionClient.sendNotificationStatus(currentTimeMillis, notificationFromUEB.getDistributionID(), artifactInfo, isArtifactRelevant);
+               if (notificationStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+                       log.error("Error failed to send notification status to UEB failed status:{}, error message:{}", notificationStatus.getDistributionActionResult().name(), notificationStatus.getDistributionMessageResult());
+               }
+       }
+
+       private void setRelatedArtifacts(ArtifactInfoImpl artifact, INotificationData notificationData) {
+               if (artifact.getRelatedArtifactsUUID() != null) {
+                       List<IArtifactInfo> relatedArtifacts = new ArrayList<>();
+                       for (String relatedArtifactUUID : artifact.getRelatedArtifactsUUID()) {
+                               relatedArtifacts.add(notificationData.getArtifactMetadataByUUID(relatedArtifactUUID));
+                       }
+                       artifact.setRelatedArtifactsInfo(relatedArtifacts);
+               }
+
+       }
+
+       private void setGeneratedArtifact(final List<ArtifactInfoImpl> artifactsImplList, ArtifactInfoImpl artifactInfo) {
+               IArtifactInfo found = null;
+               String artifactUUID = artifactInfo.getArtifactUUID();
+               for (ArtifactInfoImpl generatedArtifactInfo : artifactsImplList) {
+                       if (generatedArtifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.name()) && artifactUUID.equals(generatedArtifactInfo.getGeneratedFromUUID())) {
+                               found = generatedArtifactInfo;
+                               break;
+                       }
+               }
+
+               artifactInfo.setGeneratedArtifact(found);
+       }
+
+       private IArtifactInfo findGeneratedFromArtifact(String getGeneratedFromUUID, List<ArtifactInfoImpl> list) {
+               IArtifactInfo found = null;
+               for (ArtifactInfoImpl artifactInfo : list) {
+                       if (getGeneratedFromUUID.equals(artifactInfo.getArtifactUUID())) {
+                               found = artifactInfo;
+                               break;
+                       }
+               }
+               return found;
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/NotificationDataImpl.java b/src/main/java/org/openecomp/sdc/impl/NotificationDataImpl.java
new file mode 100644 (file)
index 0000000..7ad3987
--- /dev/null
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.notification.INotificationData;
+import org.openecomp.sdc.api.notification.IResourceInstance;
+
+
+class NotificationDataImpl implements INotificationData {
+
+       private String distributionID;
+       private String serviceName;
+       private String serviceVersion;
+       private String serviceUUID;
+       private String serviceDescription;
+       private String serviceInvariantUUID;
+       private List<JsonContainerResourceInstance> resources;
+       private List<ArtifactInfoImpl> serviceArtifacts;
+
+       @Override
+       public String getDistributionID() {
+               return distributionID;
+       }
+
+       @Override
+       public String getServiceName() {
+               return serviceName;
+       }
+
+       @Override
+       public String getServiceVersion() {
+               return serviceVersion;
+       }
+
+       @Override
+       public String getServiceUUID() {
+               return serviceUUID;
+       }
+
+       public void setDistributionID(String distributionID) {
+               this.distributionID = distributionID;
+       }
+
+       public void setServiceName(String serviceName) {
+               this.serviceName = serviceName;
+       }
+
+       public void setServiceVersion(String serviceVersion) {
+               this.serviceVersion = serviceVersion;
+       }
+
+       public void setServiceUUID(String serviceUUID) {
+               this.serviceUUID = serviceUUID;
+       }
+
+       
+
+       public String getServiceDescription() {
+               return serviceDescription;
+       }
+
+       public void setServiceDescription(String serviceDescription) {
+               this.serviceDescription = serviceDescription;
+       }
+
+       @Override
+       public String toString() {
+               return "NotificationDataImpl [distributionID=" + distributionID
+                               + ", serviceName=" + serviceName + ", serviceVersion="
+                               + serviceVersion + ", serviceUUID=" + serviceUUID+"]";
+       }
+
+       @Override
+       public List<IResourceInstance> getResources() {
+               List<IResourceInstance> ret = new ArrayList<IResourceInstance>();
+               if( resources != null ){
+                       ret.addAll(resources);
+               }
+               return ret;
+       }
+
+       public void setResources(List<IResourceInstance> resources){
+               this.resources = JsonContainerResourceInstance.convertToJsonContainer(resources);
+       }
+       
+       public List<JsonContainerResourceInstance> getResourcesImpl(){
+               return resources;
+       }
+       
+       List<ArtifactInfoImpl> getServiceArtifactsImpl(){
+               return serviceArtifacts;
+       }
+
+       @Override
+       public List<IArtifactInfo> getServiceArtifacts() {
+               
+               List<IArtifactInfo> temp = new ArrayList<IArtifactInfo>();
+               if( serviceArtifacts != null ){
+                       temp.addAll(serviceArtifacts);
+               }
+               return temp;
+       }
+
+       void setServiceArtifacts(List<ArtifactInfoImpl> relevantServiceArtifacts) {
+               serviceArtifacts = relevantServiceArtifacts;
+               
+       }
+       
+       @Override
+       public String getServiceInvariantUUID() {
+               return serviceInvariantUUID;
+       }
+       
+       
+       public void setServiceInvariantUUID(String serviceInvariantUUID) {
+               this.serviceInvariantUUID = serviceInvariantUUID;
+       }
+       @Override
+       public IArtifactInfo getArtifactMetadataByUUID(String artifactUUID){
+               IArtifactInfo ret = findArtifactInfoByUUID(artifactUUID, serviceArtifacts);
+               if( ret == null && resources != null ){
+                       for( JsonContainerResourceInstance currResourceInstance : resources ){
+                               ret = findArtifactInfoByUUID(artifactUUID, currResourceInstance.getArtifactsImpl());
+                               if( ret != null ){
+                                       break;
+                               }
+                       }
+               }
+               return ret;
+
+       }
+
+       private IArtifactInfo findArtifactInfoByUUID(String artifactUUID, List<ArtifactInfoImpl> listToCheck) {
+               IArtifactInfo ret = null;
+               if( listToCheck != null ){
+                       for(IArtifactInfo curr: listToCheck ){
+                               if(curr.getArtifactUUID().equals(artifactUUID) ){
+                                       ret = curr;
+                                       break;
+                               }
+                       }
+               }
+               return ret;
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/VfModuleMetadata.java b/src/main/java/org/openecomp/sdc/impl/VfModuleMetadata.java
new file mode 100644 (file)
index 0000000..3932253
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import java.util.List;
+
+import org.openecomp.sdc.api.notification.IVfModuleMetadata;
+
+final class VfModuleMetadata implements IVfModuleMetadata {
+       private VfModuleMetadata(){
+               //This Class is only built by parsing Json
+       }
+       
+       private String vfModuleModelName;
+       private String vfModuleModelInvariantUUID;
+       private String vfModuleModelVersion;
+       private String vfModuleModelUUID;
+       private String vfModuleModelDescription;
+       private boolean isBase; 
+       private List<String> artifacts;
+       
+       public String getVfModuleModelName() {
+               return vfModuleModelName;
+       }
+       public String getVfModuleModelInvariantUUID() {
+               return vfModuleModelInvariantUUID;
+       }
+       public String getVfModuleModelVersion() {
+               return vfModuleModelVersion;
+       }
+       public String getVfModuleModelUUID() {
+               return vfModuleModelUUID;
+       }
+       public String getVfModuleModelDescription() {
+               return vfModuleModelDescription;
+       }
+       public boolean isBase() {
+               return isBase;
+       }
+       public List<String> getArtifacts() {
+               return artifacts;
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/mock/DistributionClientDownloadResultStubImpl.java b/src/main/java/org/openecomp/sdc/impl/mock/DistributionClientDownloadResultStubImpl.java
new file mode 100644 (file)
index 0000000..d69451a
--- /dev/null
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl.mock;
+
+import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
+
+/** Mock Implementation */
+public class DistributionClientDownloadResultStubImpl extends DistributionClientResultStubImpl implements IDistributionClientDownloadResult {
+
+       @Override
+       public byte[] getArtifactPayload() {
+               String mockPayload = "heat_template_version: 2013-05-23\r\n" + 
+                               "\r\n" + 
+                               "description: >\r\n" + 
+                               "  HOT template that creates one COR network (direct).\r\n" + 
+                               "\r\n" + 
+                               "parameters:\r\n" + 
+                               "  cor_direct_net_name:\r\n" + 
+                               "    type: string\r\n" + 
+                               "    description: Name of COR direct network\r\n" + 
+                               "  cor_direct_net_cidr:\r\n" + 
+                               "    type: string\r\n" + 
+                               "    description: Direct network address (CIDR notation)\r\n" + 
+                               "  cor_direct_net_gateway:\r\n" + 
+                               "    type: string\r\n" + 
+                               "    description: Direct network gateway address\r\n" + 
+                               "  cor_direct_net_RT:\r\n" + 
+                               "    type: string\r\n" + 
+                               "    description: Direct network route-target (RT)\r\n" + 
+                               "\r\n" + 
+                               "resources:\r\n" + 
+                               "  cor_direct_net:\r\n" + 
+                               "    type: OS::Contrail::VirtualNetwork\r\n" + 
+                               "    properties:\r\n" + 
+                               "      name: { get_param: cor_direct_net_name }\r\n" + 
+                               "      route_targets: [ get_param: cor_direct_net_RT ]\r\n" + 
+                               "\r\n" + 
+                               "  cor_direct_ip_subnet:\r\n" + 
+                               "    type: OS::Neutron::Subnet\r\n" + 
+                               "    properties:\r\n" + 
+                               "      network_id: { get_resource: cor_direct_net }\r\n" + 
+                               "      cidr: {get_param: cor_direct_net_cidr}\r\n" + 
+                               "      gateway_ip: { get_param: cor_direct_net_gateway }\r\n";
+               
+               return mockPayload.getBytes();
+       }
+
+       @Override
+       public String getArtifactName() {
+               // TODO Auto-generated method stub
+               return "MackArtifactName";
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/mock/DistributionClientResultStubImpl.java b/src/main/java/org/openecomp/sdc/impl/mock/DistributionClientResultStubImpl.java
new file mode 100644 (file)
index 0000000..13d64a4
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl.mock;
+
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+/** Mock Implementation */
+public class DistributionClientResultStubImpl implements IDistributionClientResult {
+       @Override
+       public DistributionActionResultEnum getDistributionActionResult() {
+               return DistributionActionResultEnum.SUCCESS;
+       }
+
+       @Override
+       public String getDistributionMessageResult() {
+               return "Stub Result, method not implemented!";
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/impl/mock/DistributionClientStubImpl.java b/src/main/java/org/openecomp/sdc/impl/mock/DistributionClientStubImpl.java
new file mode 100644 (file)
index 0000000..b8044cd
--- /dev/null
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl.mock;
+
+import java.util.List;
+
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.api.consumer.IConfiguration;
+import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
+import org.openecomp.sdc.api.consumer.INotificationCallback;
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.notification.IVfModuleMetadata;
+import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+/** Mock Implementation */
+public class DistributionClientStubImpl implements IDistributionClient{
+       public DistributionClientStubImpl(){
+               
+       }
+       
+       public IDistributionClientResult updateConfiguration(IConfiguration newConf) {
+               return new DistributionClientResultStubImpl();
+       }
+
+       public IDistributionClientResult start() {
+               return new DistributionClientResultStubImpl();
+       }
+
+       public IDistributionClientResult stop() {
+               return new DistributionClientResultStubImpl();
+       }
+
+       public IDistributionClientResult sendDownloadStatus( IDistributionStatusMessage statusMessage) {
+               return new DistributionClientResultStubImpl();
+       }
+
+       public IDistributionClientResult sendDeploymentStatus( IDistributionStatusMessage statusMessage) {
+               return new DistributionClientResultStubImpl();
+       }
+
+       @Override
+       public IDistributionClientDownloadResult download(IArtifactInfo artifactInfo) {
+               return new DistributionClientDownloadResultStubImpl();
+       }
+
+       @Override
+       public IDistributionClientResult init(IConfiguration conf, INotificationCallback callback) {
+               return new DistributionClientResultStubImpl();
+       }
+
+       @Override
+       public IConfiguration getConfiguration() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public IDistributionClientResult sendDownloadStatus(
+                       IDistributionStatusMessage statusMessage, String errorReason) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public IDistributionClientResult sendDeploymentStatus(
+                       IDistributionStatusMessage statusMessage, String errorReason) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public List<IVfModuleMetadata> decodeVfModuleArtifact(byte[] artifactPayload) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+       
+
+
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/ArtifactTypeEnum.java b/src/main/java/org/openecomp/sdc/utils/ArtifactTypeEnum.java
new file mode 100644 (file)
index 0000000..ca5339f
--- /dev/null
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+public enum ArtifactTypeEnum {
+       HEAT,
+       HEAT_VOL,
+       HEAT_NET,
+       MURANO_PKG,
+       HEAT_ENV,
+       YANG_XML,
+       OTHER,
+       VF_LICENSE,
+       VENDOR_LICENSE,
+       MODEL_INVENTORY_PROFILE,
+       MODEL_QUERY_SPEC,
+       APPC_CONFIG,
+       VNF_CATALOG,
+       HEAT_NESTED,
+       HEAT_ARTIFACT,
+       VF_MODULES_METADATA,
+       //DCAE Artifacts
+       DCAE_TOSCA, DCAE_JSON, DCAE_POLICY, DCAE_DOC, 
+       DCAE_EVENT, DCAE_INVENTORY_TOSCA, DCAE_INVENTORY_JSON, 
+       DCAE_INVENTORY_POLICY, DCAE_INVENTORY_DOC, 
+       DCAE_INVENTORY_BLUEPRINT, DCAE_INVENTORY_EVENT;
+
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/DistributionActionResultEnum.java b/src/main/java/org/openecomp/sdc/utils/DistributionActionResultEnum.java
new file mode 100644 (file)
index 0000000..47333d5
--- /dev/null
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+public enum DistributionActionResultEnum {
+       SUCCESS, 
+       FAIL,
+       GENERAL_ERROR,
+       BAD_REQUEST,
+       DISTRIBUTION_CLIENT_NOT_INITIALIZED,
+       DISTRIBUTION_CLIENT_IS_TERMINATED,
+       DISTRIBUTION_CLIENT_ALREADY_INITIALIZED,
+       DISTRIBUTION_CLIENT_ALREADY_STARTED,
+       
+       DATA_INTEGRITY_PROBLEM,
+       ARTIFACT_NOT_FOUND,
+       
+       CONFIGURATION_IS_MISSING,
+       CONF_MISSING_USERNAME,
+       CONF_MISSING_PASSWORD,
+       CONF_MISSING_ASDC_FQDN,
+       CONF_MISSING_ARTIFACT_TYPES,
+       CONF_CONTAINS_INVALID_ARTIFACT_TYPES,
+       CONF_MISSING_CONSUMER_ID,
+       CONF_MISSING_ENVIRONMENT_NAME,
+       CONF_MISSING_CONSUMER_GROUP, 
+       CONF_INVALID_ASDC_FQDN,
+       ASDC_AUTHENTICATION_FAILED, 
+       ASDC_AUTHORIZATION_FAILED,
+       ASDC_NOT_FOUND,
+       ASDC_SERVER_PROBLEM,
+       ASDC_CONNECTION_FAILED,
+       ASDC_SERVER_TIMEOUT,
+       
+       CAMBRIA_INIT_FAILED,
+       UEB_KEYS_CREATION_FAILED
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/DistributionClientConstants.java b/src/main/java/org/openecomp/sdc/utils/DistributionClientConstants.java
new file mode 100644 (file)
index 0000000..37b8ae3
--- /dev/null
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+import java.util.regex.Pattern;
+
+/**
+ * Constants Used By Distribution Client
+ * @author mshitrit
+ *
+ */
+public final class DistributionClientConstants {
+       public static final String CLIENT_DESCRIPTION = "ASDC Distribution Client Key for %s";
+       public static final Pattern FQDN_PATTERN = Pattern.compile("^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])(\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))*(:[0-9]{2,4})*$", Pattern.CASE_INSENSITIVE);
+       public static final String EMAIL = "";
+       public static final int MIN_POLLING_INTERVAL_SEC = 15;
+       public static final int POOL_SIZE = 10;
+       public static final int POLLING_TIMEOUT_SEC = 15;
+       
+       public static final String HEADER_INSTANCE_ID = "X-ECOMP-InstanceID";
+       public static final String HEADER_REQUEST_ID = "X-ECOMP-RequestID";
+       public static final String APPLICATION_JSON = "application/json";
+       public static final String HEADER_CONTENT_TYPE = "Content-Type";
+       
+       private DistributionClientConstants(){ throw new UnsupportedOperationException();}
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/DistributionStatusEnum.java b/src/main/java/org/openecomp/sdc/utils/DistributionStatusEnum.java
new file mode 100644 (file)
index 0000000..1d2d03c
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+public enum DistributionStatusEnum {
+       /**Can be sent  when ECOMP component  successfully  downloaded the specific artifact*/
+       DOWNLOAD_OK, 
+       
+       /**Can be sent when ECOMP component failed to download  the specific artifact (corrupted file)*/
+       DOWNLOAD_ERROR, 
+       
+       /**Can be sent only  if  the  repeated  distribution notification  event is  sent when  the ECOMP component  already  downloaded  the  artifact  , but  still  not  stored it in the  local  repository .*/
+       ALREADY_DOWNLOADED, 
+       
+       /**Can be sent  when ECOMP component  successfully  deployed the specific artifact in the  local repository*/
+       DEPLOY_OK, 
+       
+       /**Can be sent when ECOMP component failed  to  store  the downloaded  artifact  in the local  repository*/
+       DEPLOY_ERROR, 
+       
+       /**Sent  when  the  repeated  distribution notification  event is sent for already  stored  in the  local  repository  service artifact  ( artifact's version and  checksum match the one stored  in the local repository)*/
+       ALREADY_DEPLOYED
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/GeneralUtils.java b/src/main/java/org/openecomp/sdc/utils/GeneralUtils.java
new file mode 100644 (file)
index 0000000..9d786d0
--- /dev/null
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+import java.util.regex.Pattern;
+
+import org.apache.commons.codec.binary.Base64;
+
+public class GeneralUtils {
+       
+       public static String calculateMD5 (String data){
+               String calculatedMd5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(data);
+               // encode base-64 result
+               byte[] encodeBase64 = Base64.encodeBase64(calculatedMd5.getBytes());
+               String encodeBase64Str = new String(encodeBase64);
+               return encodeBase64Str;
+
+       } 
+       
+       public static String calculateMD5(byte[] decodedPayload) {
+               String decodedMd5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(decodedPayload);
+               byte[] encodeMd5 = Base64.encodeBase64(decodedMd5.getBytes());
+               return new String(encodeMd5);
+       }
+       
+       public static boolean isBase64Encoded(String str){
+                boolean isEncoded = false;
+              try
+              {
+                  // If no exception is caught, then it is possibly a base64 encoded string
+                  byte[] data = Base64.decodeBase64(str);
+                  // checks if the string was properly padded to the
+                  isEncoded=  ((str.length() % 4 == 0) && (Pattern.matches("\\A[a-zA-Z0-9/+]+={1,2}\\z", str)));
+                 
+              }
+              catch (Exception e)
+              {
+                  // If exception is caught, then it is not a base64 encoded string
+                  isEncoded=  false;
+              }
+              return isEncoded;
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/Pair.java b/src/main/java/org/openecomp/sdc/utils/Pair.java
new file mode 100644 (file)
index 0000000..eca644a
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+public final class Pair<F, S> {
+       private final F first;
+       private final S second;
+       
+       public Pair(F first, S second){
+               this.first = first;
+               this.second = second;
+       }
+
+       public F getFirst() {
+               return first;
+       }
+
+       public S getSecond() {
+               return second;
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/Wrapper.java b/src/main/java/org/openecomp/sdc/utils/Wrapper.java
new file mode 100644 (file)
index 0000000..047ea86
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+/**
+ * Very Basic Wrapper class.
+ * @author mshitrit
+ *  
+ * @param <T>
+ */
+public class Wrapper<T>{
+       private T innerElement;
+       public Wrapper(T innerElement){
+               this.innerElement = innerElement;
+       }
+       public Wrapper(){
+               this.innerElement = null;
+       }
+       public T getInnerElement() {
+               return innerElement;
+       }
+       public void setInnerElement(T innerElement) {
+               this.innerElement = innerElement;
+       }
+       public boolean isEmpty(){
+               return innerElement == null;
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/YamlToObjectConverter.java b/src/main/java/org/openecomp/sdc/utils/YamlToObjectConverter.java
new file mode 100644 (file)
index 0000000..50feb6c
--- /dev/null
@@ -0,0 +1,155 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+import java.beans.IntrospectionException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+
+import org.openecomp.sdc.utils.heat.HeatConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.TypeDescription;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.introspector.BeanAccess;
+import org.yaml.snakeyaml.introspector.Property;
+import org.yaml.snakeyaml.introspector.PropertyUtils;
+
+public class YamlToObjectConverter {
+
+       private static Logger log = LoggerFactory
+                       .getLogger(YamlToObjectConverter.class.getName());
+
+       private static HashMap<String, Yaml> yamls = new HashMap<String, Yaml>();
+
+       private static Yaml defaultYaml = new Yaml();
+
+       static {
+
+               org.yaml.snakeyaml.constructor.Constructor heatConstructor = new org.yaml.snakeyaml.constructor.Constructor(HeatConfiguration.class);
+               TypeDescription heatDescription = new TypeDescription(HeatConfiguration.class);
+               //heatDescription.putListPropertyType("parameters", HeatParameterConfiguration.class);
+               heatConstructor.addTypeDescription(heatDescription);
+               PropertyUtils propertyUtils = new PropertyUtils() {
+                       @Override
+                       //This is in order to workaround "default" field in HeatParameterEntry, since default is Java keyword
+                       public Property getProperty(Class<? extends Object> type, String name, BeanAccess bAccess)
+                                       throws IntrospectionException {
+                               name = name.substring(0, 1).toLowerCase() + name.substring(1);
+                               return super.getProperty(type, name, bAccess);
+                       }
+
+               };
+               //Skip properties which are not found - we only are interested in "parameters"
+               propertyUtils.setSkipMissingProperties(true);
+               heatConstructor.setPropertyUtils(propertyUtils);
+
+               Yaml yaml = new Yaml(heatConstructor);
+
+               yamls.put(HeatConfiguration.class.getName(), yaml);
+
+       }
+
+       private static <T> Yaml getYamlByClassName(Class<T> className) {
+
+               Yaml yaml = yamls.get(className.getName());
+               if (yaml == null) {
+                       yaml = defaultYaml;
+               }
+
+               return yaml;
+       }
+
+       public <T> T convert(String dirPath, Class<T> className,
+                       String configFileName) {
+
+               T config = null;
+
+               try {
+
+                       String fullFileName = dirPath + File.separator + configFileName;
+
+                       config = convert(fullFileName, className);
+
+               } catch (Exception e) {
+                       log.error("Failed to convert yaml file " + configFileName
+                                       + " to object.", e);
+               } 
+
+               return config;
+       }
+
+       public <T> T convert(String fullFileName, Class<T> className) {
+
+               T config = null;
+
+               Yaml yaml = getYamlByClassName(className);
+
+               InputStream in = null;
+               try {
+
+                       File f = new File(fullFileName);
+                       if (false == f.exists()) {
+                               log.warn("The file " + fullFileName
+                                               + " cannot be found. Ignore reading configuration.");
+                               return null;
+                       }
+                       in = Files.newInputStream(Paths.get(fullFileName));
+
+                       config = yaml.loadAs(in, className);
+
+                       // System.out.println(config.toString());
+               } catch (Exception e) {
+                       log.error("Failed to convert yaml file " + fullFileName
+                                       + " to object.", e);
+               } finally {
+                       if (in != null) {
+                               try {
+                                       in.close();
+                               } catch (IOException e) {
+                                       // TODO Auto-generated catch block
+                                       e.printStackTrace();
+                               }
+                       }
+               }
+
+               return config;
+       }
+
+       public <T> T convertFromString(String yamlContents, Class<T> className) {
+
+               T config = null;
+
+               Yaml yaml = getYamlByClassName(className);
+
+               try {
+                       config = yaml.loadAs(yamlContents, className);
+               } catch (Exception e){
+                       log.error("Failed to convert YAML {} to object." , yamlContents, e);
+               }
+
+               return config;
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/heat/HeatConfiguration.java b/src/main/java/org/openecomp/sdc/utils/heat/HeatConfiguration.java
new file mode 100644 (file)
index 0000000..6cd2de0
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils.heat;
+
+import java.util.Map;
+
+public class HeatConfiguration {
+       
+       //All the rest of heat file is not needed for now...
+       Map<String, HeatParameter> parameters;
+       
+
+       public Map<String, HeatParameter> getParameters() {
+               return parameters;
+       }
+
+
+       public void setParameters(Map<String, HeatParameter> parameters) {
+               this.parameters = parameters;
+       }
+
+       
+
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/heat/HeatParameter.java b/src/main/java/org/openecomp/sdc/utils/heat/HeatParameter.java
new file mode 100644 (file)
index 0000000..954152d
--- /dev/null
@@ -0,0 +1,207 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils.heat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class HeatParameter{
+
+       String type;
+       String label;
+       String description;
+       //This is in order to workaround "default" field in HeatParameterEntry, since default is Java keyword
+       //YAML constructor will lowercase it during parsing     
+       String Default;
+       String hidden = "false";//Default value according to OpenStack spec
+       List<HeatParameterConstraint> constraints;
+
+
+
+       public String getHidden() {
+               return hidden;
+       }
+       public void setHidden(String hidden) {
+               this.hidden = hidden;
+       }
+
+       public List<HeatParameterConstraint> getConstraints() {
+               return constraints;
+       }
+       public void setConstraints(List<HeatParameterConstraint> constraints) {
+               this.constraints = constraints;
+       }
+       public String getType() {
+               return type;
+       }
+       public void setType(String type) {
+               this.type = type;
+       }
+       public String getLabel() {
+               return label;
+       }
+       public void setLabel(String label) {
+               this.label = label;
+       }
+       public String getDescription() {
+               return description;
+       }
+       public void setDescription(String description) {
+               this.description = description;
+       }
+       public String getDefault() {
+               return Default;
+       }
+       public void setDefault(String default1) {
+               Default = default1;
+       }
+       
+       
+
+       // Getting specific constraints
+       /**
+        * Get the first "length" constraint from HEAT parameter.
+        * No additional "length" constraint is searched for.
+        * 
+        * @return first "length" constraint found for this parameter,
+        * or null if no such constraint exists. 
+        */
+       public HeatParameterConstraint getLengthConstraint(){
+               HeatParameterConstraint res = null;
+               if (constraints != null){
+                       for (HeatParameterConstraint entry : constraints){
+                               if (entry.getLength() != null){
+                                       res = entry;
+                                       break;
+                               }
+                       }
+               }
+               return res;
+       }
+
+
+       /**
+        * Get the first "range" constraint from HEAT parameter.
+        * No additional "range" constraint is searched for.
+        * 
+        * @return first "range" constraint found for this parameter,
+        * or null if no such constraint exists. 
+        */
+       public HeatParameterConstraint getRangeConstraint(){
+               HeatParameterConstraint res = null;
+               if (constraints != null){
+                       for (HeatParameterConstraint entry : constraints){
+                               if (entry.getRange() != null){
+                                       res = entry;
+                                       break;
+                               }
+                       }
+               }
+               return res;
+       }
+
+       /**
+        * Get the first "allowed_values" constraint from HEAT parameter.
+        * No additional "allowed_values" constraint is searched for.
+        * 
+        * @return first "allowed_values" constraint found for this parameter,
+        * or null if no such constraint exists. 
+        */
+       public HeatParameterConstraint getAllowedValuesConstraint(){
+               HeatParameterConstraint res = null;
+               if (constraints != null){
+                       for (HeatParameterConstraint entry : constraints){
+                               if (entry.getAllowed_values() != null){
+                                       res = entry;
+                                       break;
+                               }
+                       }
+               }
+               return res;
+       }
+
+       /**
+        * Get the "allowed_pattern" constraint list from HEAT parameter.
+        * 
+        * @return "allowed_pattern" constraint list found for this parameter,
+        * or null if no such constraint exists. 
+        */
+       public List<HeatParameterConstraint> getAllowedPatternConstraint(){
+               List<HeatParameterConstraint> res = null;
+               if (constraints != null){
+                       for (HeatParameterConstraint entry : constraints){
+                               if (entry.getAllowed_pattern() != null){
+                                       if (res == null){
+                                               res = new ArrayList<>();
+                                       }
+                                       res.add(entry);
+                               }
+                       }
+               }
+               return res;
+       }
+
+       /**
+        * Get the "custom_constraint" constraint list from HEAT parameter.
+        * 
+        * @return "custom_constraint" constraint list found for this parameter,
+        * or null if no such constraint exists. 
+        */
+       public List<HeatParameterConstraint> getCustomConstraintConstraint(){
+               List<HeatParameterConstraint> res = null;
+               if (constraints != null){
+                       for (HeatParameterConstraint entry : constraints){
+                               if (entry.getCustom_constraint() != null){
+                                       if (res == null){
+                                               res = new ArrayList<>();
+                                       }
+                                       res.add(entry);
+                               }
+                       }
+               }
+               return res;
+       }
+       
+       @Override
+       public String toString() {
+               StringBuilder sb = new StringBuilder();
+               if (type != null){
+                       sb.append("type:"+type+", ");
+               } 
+               if (label != null){
+                       sb.append("label:"+label+", ");
+               }
+               if (Default != null){
+                       sb.append("default:"+Default+", ");
+               }
+               if (hidden != null){
+                       sb.append("hidden:"+hidden+", ");
+               }
+               if (constraints != null){
+                       sb.append("constraints:"+constraints+", ");
+               }
+               if (description != null){
+                       sb.append("description:"+description);
+               }
+               return sb.toString();
+       }
+
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/heat/HeatParameterConstraint.java b/src/main/java/org/openecomp/sdc/utils/heat/HeatParameterConstraint.java
new file mode 100644 (file)
index 0000000..b89ad48
--- /dev/null
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils.heat;
+
+import java.util.List;
+import java.util.Map;
+
+public class HeatParameterConstraint {
+
+       Map<String, String> length;
+       Map<String, String> range;
+       List<String> allowed_values;
+       String allowed_pattern;
+       String custom_constraint;
+       String description;
+       
+       
+       public String getDescription() {
+               return description;
+       }
+       public void setDescription(String description) {
+               this.description = description;
+       }
+       public Map<String, String> getLength() {
+               return length;
+       }
+       public void setLength(Map<String, String> length) {
+               this.length = length;
+       }
+       public Map<String, String> getRange() {
+               return range;
+       }
+       public void setRange(Map<String, String> range) {
+               this.range = range;
+       }
+       public List<String> getAllowed_values() {
+               return allowed_values;
+       }
+       public void setAllowed_values(List<String> allowed_values) {
+               this.allowed_values = allowed_values;
+       }
+       public String getAllowed_pattern() {
+               return allowed_pattern;
+       }
+       public void setAllowed_pattern(String allowed_pattern) {
+               this.allowed_pattern = allowed_pattern;
+       }
+       public String getCustom_constraint() {
+               return custom_constraint;
+       }
+       public void setCustom_constraint(String custom_constraint) {
+               this.custom_constraint = custom_constraint;
+       }
+       
+       @Override
+       public String toString() {
+               String constraintTypeValue = "<empty>";
+               String descriptionStr = "<empty>";
+               if (length != null){
+                       constraintTypeValue = "length:"+length;
+               } else if (range != null){
+                       constraintTypeValue = "range:"+range;
+               } else if (allowed_values != null){
+                       constraintTypeValue = "allowed_values:"+allowed_values;
+               } else if (allowed_pattern != null){
+                       constraintTypeValue = "allowed_pattern:"+allowed_pattern;
+               } else if (custom_constraint != null){
+                       constraintTypeValue = "custom_constraint:"+custom_constraint;
+               }
+               if (description != null){
+                       descriptionStr = "description:"+description;
+               }
+               return new StringBuilder().append(constraintTypeValue).append(", ").append(descriptionStr).toString();
+       }
+}
diff --git a/src/main/java/org/openecomp/sdc/utils/heat/HeatParser.java b/src/main/java/org/openecomp/sdc/utils/heat/HeatParser.java
new file mode 100644 (file)
index 0000000..5aa4968
--- /dev/null
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils.heat;
+
+import java.util.Map;
+
+import org.openecomp.sdc.utils.YamlToObjectConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HeatParser {
+       
+       private static Logger log = LoggerFactory.getLogger(HeatParser.class.getName());
+
+
+       /**
+        * Parses and returns the contents of the "parameters" section of YAML-formatted HEAT template.
+        *  
+        * @param heatFileContents - the string contents of HEAT template
+        * @return map of parameter name to HeatParameter object.
+        * For the following YAML snippet:
+        * <b>parameters:
+        *              image_name_1:
+        *                      type: string
+        *                      label: Image Name
+        *                      description: SCOIMAGE Specify an image name for instance1
+        *                      default: cirros-0.3.1-x86_64
+        * </b>
+        * the map with one entry will be returned, the key will be "image_name_1".
+        * For a HeatParameter object, getConstraints() returns the list of all constraints,
+        * regardless of constraint type. 
+        * For that reason, for each constraint type a sugaring function were added on the HeatParameter type,
+        * for example getLengthConstraint(). A correct way to fetch the "length" constraint values map would be
+        * parameter.getLengthConstraint().getLength(). Same logic was implemented for all other constraint types.
+        * 
+        * In case of parse error, null will be returned.
+        * 
+        */
+       public Map<String, HeatParameter> getHeatParameters(String heatFileContents){
+               log.debug("Start of extracting HEAT parameters from file, file contents: {}", heatFileContents);
+               Map<String, HeatParameter> heatParameters = null;
+               YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter();
+               HeatConfiguration heatConfiguration = yamlToObjectConverter.convertFromString(heatFileContents, HeatConfiguration.class);
+               if (heatConfiguration != null){
+                       heatParameters = heatConfiguration.getParameters();
+               } else {
+                       log.error("Couldn't parse HEAT template.");
+               }
+               if (heatParameters != null && heatParameters.size() > 0){
+                       System.out.println("Found HEAT parameters: "+heatParameters.toString());
+                       log.debug("Found HEAT parameters: {}", heatParameters.toString());
+               } else {
+                       log.warn("HEAT template parameters section wasn't found or is empty.");
+               }
+               return heatParameters;
+       }
+}
diff --git a/src/test/java/org/openecomp/sdc/impl/DistributionClientTest.java b/src/test/java/org/openecomp/sdc/impl/DistributionClientTest.java
new file mode 100644 (file)
index 0000000..9e6461d
--- /dev/null
@@ -0,0 +1,546 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.api.consumer.IConfiguration;
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.http.AsdcConnectorClient;
+import org.openecomp.sdc.http.TopicRegistrationResponse;
+import org.openecomp.sdc.impl.ArtifactInfoImpl;
+import org.openecomp.sdc.impl.DistributionClientFactory;
+import org.openecomp.sdc.impl.DistributionClientImpl;
+import org.openecomp.sdc.impl.DistributionClientResultImpl;
+import org.openecomp.sdc.utils.ArtifactTypeEnum;
+import org.openecomp.sdc.utils.ArtifactsUtils;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+import org.openecomp.sdc.utils.TestConfiguration;
+import org.openecomp.sdc.utils.TestNotificationCallback;
+import org.openecomp.sdc.utils.Wrapper;
+
+import com.att.nsa.apiClient.credentials.ApiCredential;
+import com.att.nsa.apiClient.http.HttpException;
+import com.att.nsa.cambria.client.CambriaClient.CambriaApiException;
+import com.att.nsa.cambria.client.CambriaClientBuilders;
+import com.att.nsa.cambria.client.CambriaIdentityManager;
+import com.att.nsa.cambria.client.CambriaTopicManager;
+
+import fj.data.Either;
+
+public class DistributionClientTest {
+
+       static CambriaIdentityManager cc;
+       static List<String> serverList;
+       DistributionClientImpl client = new DistributionClientImpl();
+       IConfiguration testConfiguration = new TestConfiguration();
+       AsdcConnectorClient connector = Mockito.mock(AsdcConnectorClient.class);
+
+       @BeforeClass
+       public static void setup() {
+               serverList = new ArrayList<String>();
+               serverList.add("uebsb91sfdc.it.att.com:3904");
+               serverList.add("uebsb92sfdc.it.att.com:3904");
+               serverList.add("uebsb93sfdc.it.att.com:3904");
+
+       }
+
+       @After
+       public void afterTest() {
+               client.stop();
+       }
+
+       @Test
+       public void validateConfigurationTest() {
+               DistributionActionResultEnum validationResult = client.validateAndInitConfiguration(new Wrapper<IDistributionClientResult>(), testConfiguration);
+               Assert.assertEquals(DistributionActionResultEnum.SUCCESS, validationResult);
+               Assert.assertEquals(testConfiguration.getPollingInterval(), client.configuration.getPollingInterval());
+               Assert.assertEquals(testConfiguration.getPollingTimeout(), client.configuration.getPollingTimeout());
+       }
+
+       @Test
+       public void validateConfigurationToDefaultTest() {
+               TestConfiguration userConfig = new TestConfiguration();
+               userConfig.setPollingInterval(1);
+               userConfig.setPollingTimeout(2);
+               DistributionActionResultEnum validationResult = client.validateAndInitConfiguration(new Wrapper<IDistributionClientResult>(), userConfig);
+               Assert.assertEquals(DistributionActionResultEnum.SUCCESS, validationResult);
+               Assert.assertEquals(15, client.configuration.getPollingInterval());
+               Assert.assertEquals(15, client.configuration.getPollingTimeout());
+       }
+
+       @Test
+       public void validateConfigurationFqdnTest() {
+
+               String[] validFqdns = { "myHostname", "myHostname:80", "myHostname:8080", "172.20.43.118", "172.20.43.118:8080", "ueb01hydc.it.att.com", "ueb01hydc.it.att.com:8080", "ueb01hydc.it", "my-good.and-simple.fqdn" };
+
+               String[] invalidFqdns = { "myHostname:808080", /* 70 letters */"abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij", "not**good", "very#not#good#" };
+
+               boolean validationResult = true;
+
+               for (int i = 0; i < validFqdns.length; i++) {
+                       validationResult = client.isValidFqdn(validFqdns[i]);
+                       assertEquals("assertion failed for FQDN " + validFqdns[i] + " expected to be valid, actual invalid", true, validationResult);
+               }
+
+               for (int i = 0; i < invalidFqdns.length; i++) {
+                       validationResult = client.isValidFqdn(invalidFqdns[i]);
+                       assertEquals("assertion failed for FQDN " + invalidFqdns[i] + " expected to be invalid, actual valid", false, validationResult);
+               }
+
+       }
+
+       @Test
+       public void validateConfigurationPasswordTest() {
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               TestConfiguration testPassword = new TestConfiguration();
+               testPassword.setPassword(null);
+               DistributionActionResultEnum validationResult = client.validateAndInitConfiguration(errorWrapper, testPassword);
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_PASSWORD, validationResult);
+
+               testPassword.setPassword("");
+               validationResult = client.validateAndInitConfiguration(errorWrapper, testPassword);
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_PASSWORD, validationResult);
+
+       }
+
+       @Test
+       public void validateConfigurationUserTest() {
+               Wrapper<IDistributionClientResult> errorWrapper = new Wrapper<>();
+               TestConfiguration testUser = new TestConfiguration();
+               testUser.setUser(null);
+               DistributionActionResultEnum validationResult = client.validateAndInitConfiguration(errorWrapper, testUser);
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_USERNAME, validationResult);
+
+               testUser.setUser("");
+               validationResult = client.validateAndInitConfiguration(errorWrapper, testUser);
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_USERNAME, validationResult);
+
+       }
+
+       @Test
+       public void initWithMocksBadConfigurationTest() throws HttpException, CambriaApiException, IOException {
+
+               // connectorMock
+               Either<List<String>, IDistributionClientResult> serversResult = Either.left(serverList);
+               Mockito.when(connector.getServerList()).thenReturn(serversResult);
+
+               TopicRegistrationResponse topics = new TopicRegistrationResponse();
+               topics.setDistrNotificationTopicName("notificationTopic");
+               topics.setDistrStatusTopicName("statusTopic");
+               Either<TopicRegistrationResponse, DistributionClientResultImpl> topicsResult = Either.left(topics);
+               Mockito.when(connector.registerAsdcTopics(Mockito.any(ApiCredential.class))).thenReturn(topicsResult);
+
+               client.asdcConnector = connector;
+
+               // cambriaMock
+
+               CambriaIdentityManager cambriaMock = Mockito.mock(CambriaIdentityManager.class);
+               Mockito.when(cambriaMock.createApiKey(Mockito.any(String.class), Mockito.any(String.class))).thenReturn(new ApiCredential("public", "secret"));
+               client.cambriaIdentityManager = cambriaMock;
+
+               // no password
+               TestConfiguration testPassword = new TestConfiguration();
+               testPassword.setPassword(null);
+               IDistributionClientResult validationResult = client.init(testPassword, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_PASSWORD, validationResult.getDistributionActionResult());
+
+               testPassword.setPassword("");
+               validationResult = client.init(testPassword, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_PASSWORD, validationResult.getDistributionActionResult());
+
+               // no username
+               TestConfiguration testUser = new TestConfiguration();
+               testUser.setUser(null);
+               validationResult = client.init(testUser, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_USERNAME, validationResult.getDistributionActionResult());
+
+               testUser.setUser("");
+               validationResult = client.init(testUser, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_USERNAME, validationResult.getDistributionActionResult());
+
+               // no ASDC server fqdn
+               TestConfiguration testServerFqdn = new TestConfiguration();
+               testServerFqdn.setAsdcAddress(null);
+               validationResult = client.init(testServerFqdn, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_ASDC_FQDN, validationResult.getDistributionActionResult());
+
+               testServerFqdn.setAsdcAddress("");
+               validationResult = client.init(testServerFqdn, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_ASDC_FQDN, validationResult.getDistributionActionResult());
+
+               testServerFqdn.setAsdcAddress("this##is##bad##fqdn");
+               validationResult = client.init(testServerFqdn, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_INVALID_ASDC_FQDN, validationResult.getDistributionActionResult());
+
+               // no consumerId
+               TestConfiguration testConsumerId = new TestConfiguration();
+               testConsumerId.setComsumerID(null);
+               validationResult = client.init(testConsumerId, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_CONSUMER_ID, validationResult.getDistributionActionResult());
+
+               testConsumerId.setComsumerID("");
+               validationResult = client.init(testConsumerId, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_CONSUMER_ID, validationResult.getDistributionActionResult());
+
+               // no environmentName
+               TestConfiguration testEnv = new TestConfiguration();
+               testEnv.setEnvironmentName(null);
+               validationResult = client.init(testEnv, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_ENVIRONMENT_NAME, validationResult.getDistributionActionResult());
+
+               testEnv.setEnvironmentName("");
+               validationResult = client.init(testEnv, new TestNotificationCallback());
+               Assert.assertEquals(DistributionActionResultEnum.CONF_MISSING_ENVIRONMENT_NAME, validationResult.getDistributionActionResult());
+
+               Mockito.verify(connector, Mockito.times(0)).getServerList();
+               Mockito.verify(cambriaMock, Mockito.times(0)).createApiKey(Mockito.anyString(), Mockito.anyString());
+               Mockito.verify(connector, Mockito.times(0)).registerAsdcTopics(Mockito.any(ApiCredential.class));
+       }
+
+       @Test
+       public void initFailedConnectAsdcTest() throws HttpException, CambriaApiException, IOException {
+               // cambriaMock
+
+               CambriaIdentityManager cambriaMock = Mockito.mock(CambriaIdentityManager.class);
+               Mockito.when(cambriaMock.createApiKey(Mockito.any(String.class), Mockito.any(String.class))).thenReturn(new ApiCredential("public", "secret"));
+               client.cambriaIdentityManager = cambriaMock;
+
+               TestConfiguration badAsdcConfig = new TestConfiguration();
+               badAsdcConfig.setAsdcAddress("badhost:8080");
+
+               IDistributionClientResult init = client.init(badAsdcConfig, new TestNotificationCallback());
+               assertEquals(DistributionActionResultEnum.ASDC_CONNECTION_FAILED, init.getDistributionActionResult());
+
+               badAsdcConfig = new TestConfiguration();
+               badAsdcConfig.setAsdcAddress("localhost:8181");
+
+               init = client.init(badAsdcConfig, new TestNotificationCallback());
+               assertEquals(DistributionActionResultEnum.ASDC_CONNECTION_FAILED, init.getDistributionActionResult());
+
+       }
+
+       @Test
+       public void getConfigurationTest() throws HttpException, CambriaApiException, IOException {
+               // connectorMock
+               Either<List<String>, IDistributionClientResult> serversResult = Either.left(serverList);
+               Mockito.when(connector.getServerList()).thenReturn(serversResult);
+               mockArtifactTypeList();
+               TopicRegistrationResponse topics = new TopicRegistrationResponse();
+               topics.setDistrNotificationTopicName("notificationTopic");
+               topics.setDistrStatusTopicName("statusTopic");
+               Either<TopicRegistrationResponse, DistributionClientResultImpl> topicsResult = Either.left(topics);
+               Mockito.when(connector.registerAsdcTopics(Mockito.any(ApiCredential.class))).thenReturn(topicsResult);
+               IDistributionClientResult success = initSuccesResult();
+               Mockito.when(connector.unregisterTopics(Mockito.any(ApiCredential.class))).thenReturn(success);
+
+               client.asdcConnector = connector;
+
+               // cambriaMock
+
+               CambriaIdentityManager cambriaMock = Mockito.mock(CambriaIdentityManager.class);
+               Mockito.when(cambriaMock.createApiKey(Mockito.any(String.class), Mockito.any(String.class))).thenReturn(new ApiCredential("public", "secret"));
+               client.cambriaIdentityManager = cambriaMock;
+
+               TestConfiguration badAsdcConfig = new TestConfiguration();
+               badAsdcConfig.setPollingInterval(-5);
+
+               IDistributionClientResult init = client.init(badAsdcConfig, new TestNotificationCallback());
+               assertEquals(DistributionActionResultEnum.SUCCESS, init.getDistributionActionResult());
+
+               String confString = client.getConfiguration().toString();
+               System.out.println(confString);
+
+       }
+
+       private IDistributionClientResult initSuccesResult() {
+               return new IDistributionClientResult() {
+
+                       @Override
+                       public String getDistributionMessageResult() {
+                               return "success";
+                       }
+
+                       @Override
+                       public DistributionActionResultEnum getDistributionActionResult() {
+                               return DistributionActionResultEnum.SUCCESS;
+                       }
+               };
+       }
+
+       @Test
+       public void initWithMocksTest() throws HttpException, CambriaApiException, IOException {
+
+               // connectorMock
+               Either<List<String>, IDistributionClientResult> serversResult = Either.left(serverList);
+               Mockito.when(connector.getServerList()).thenReturn(serversResult);
+               mockArtifactTypeList();
+
+               TopicRegistrationResponse topics = new TopicRegistrationResponse();
+               topics.setDistrNotificationTopicName("notificationTopic");
+               topics.setDistrStatusTopicName("statusTopic");
+               Either<TopicRegistrationResponse, DistributionClientResultImpl> topicsResult = Either.left(topics);
+               Mockito.when(connector.registerAsdcTopics(Mockito.any(ApiCredential.class))).thenReturn(topicsResult);
+               IDistributionClientResult success = initSuccesResult();
+               Mockito.when(connector.unregisterTopics(Mockito.any(ApiCredential.class))).thenReturn(success);
+
+               client.asdcConnector = connector;
+
+               // cambriaMock
+
+               CambriaIdentityManager cambriaMock = Mockito.mock(CambriaIdentityManager.class);
+               Mockito.when(cambriaMock.createApiKey(Mockito.any(String.class), Mockito.any(String.class))).thenReturn(new ApiCredential("public", "secret"));
+               client.cambriaIdentityManager = cambriaMock;
+
+               IDistributionClientResult initResponse = client.init(testConfiguration, new TestNotificationCallback());
+               assertEquals(DistributionActionResultEnum.SUCCESS, initResponse.getDistributionActionResult());
+               Mockito.verify(connector, Mockito.times(1)).getServerList();
+               Mockito.verify(cambriaMock, Mockito.times(1)).createApiKey(Mockito.anyString(), Mockito.anyString());
+               Mockito.verify(connector, Mockito.times(1)).registerAsdcTopics(Mockito.any(ApiCredential.class));
+               System.out.println(initResponse);
+       }
+
+       private void mockArtifactTypeList() {
+               List<String> artifactTypes = new ArrayList<>();
+               for (ArtifactTypeEnum artifactType : ArtifactTypeEnum.values()) {
+                       artifactTypes.add(artifactType.name());
+               }
+
+               final Either<List<String>, IDistributionClientResult> eitherArtifactTypes = Either.left(artifactTypes);
+               Mockito.when(connector.getValidArtifactTypesList()).thenReturn(eitherArtifactTypes);
+       }
+
+       @Test
+       public void testAlreadyInitTest() throws HttpException, CambriaApiException, IOException {
+               initWithMocksTest();
+               IDistributionClientResult initResponse = client.init(testConfiguration, new TestNotificationCallback());
+               assertEquals(DistributionActionResultEnum.DISTRIBUTION_CLIENT_ALREADY_INITIALIZED, initResponse.getDistributionActionResult());
+       }
+
+       @Test
+       public void initGetServerFailedTest() throws HttpException, CambriaApiException, IOException {
+
+               // connectorMock
+               IDistributionClientResult getServersResult = new DistributionClientResultImpl(DistributionActionResultEnum.ASDC_SERVER_PROBLEM, "problem");
+               Either<List<String>, IDistributionClientResult> serversResult = Either.right(getServersResult);
+               Mockito.when(connector.getServerList()).thenReturn(serversResult);
+
+               TopicRegistrationResponse topics = new TopicRegistrationResponse();
+               topics.setDistrNotificationTopicName("notificationTopic");
+               topics.setDistrStatusTopicName("statusTopic");
+               Either<TopicRegistrationResponse, DistributionClientResultImpl> topicsResult = Either.left(topics);
+               Mockito.when(connector.registerAsdcTopics(Mockito.any(ApiCredential.class))).thenReturn(topicsResult);
+
+               client.asdcConnector = connector;
+
+               // cambriaMock
+
+               CambriaIdentityManager cambriaMock = Mockito.mock(CambriaIdentityManager.class);
+               Mockito.when(cambriaMock.createApiKey(Mockito.any(String.class), Mockito.any(String.class))).thenReturn(new ApiCredential("public", "secret"));
+               client.cambriaIdentityManager = cambriaMock;
+
+               IDistributionClientResult initResponse = client.init(testConfiguration, new TestNotificationCallback());
+               assertEquals(DistributionActionResultEnum.ASDC_SERVER_PROBLEM, initResponse.getDistributionActionResult());
+
+               Mockito.verify(connector, Mockito.times(1)).getServerList();
+               Mockito.verify(cambriaMock, Mockito.times(0)).createApiKey(Mockito.anyString(), Mockito.anyString());
+               Mockito.verify(connector, Mockito.times(0)).registerAsdcTopics(Mockito.any(ApiCredential.class));
+
+               System.out.println(initResponse);
+       }
+
+       @Test
+       public void initCreateKeysFailedTest() throws HttpException, CambriaApiException, IOException {
+
+               // connectorMock
+               Either<List<String>, IDistributionClientResult> serversResult = Either.left(serverList);
+               Mockito.when(connector.getServerList()).thenReturn(serversResult);
+               mockArtifactTypeList();
+
+               TopicRegistrationResponse topics = new TopicRegistrationResponse();
+               topics.setDistrNotificationTopicName("notificationTopic");
+               topics.setDistrStatusTopicName("statusTopic");
+               Either<TopicRegistrationResponse, DistributionClientResultImpl> topicsResult = Either.left(topics);
+               Mockito.when(connector.registerAsdcTopics(Mockito.any(ApiCredential.class))).thenReturn(topicsResult);
+
+               client.asdcConnector = connector;
+
+               // cambriaMock
+
+               CambriaIdentityManager cambriaMock = Mockito.mock(CambriaIdentityManager.class);
+               Mockito.when(cambriaMock.createApiKey(Mockito.any(String.class), Mockito.any(String.class))).thenThrow(new CambriaApiException("failure"));
+               client.cambriaIdentityManager = cambriaMock;
+
+               IDistributionClientResult initResponse = client.init(testConfiguration, new TestNotificationCallback());
+               assertEquals(DistributionActionResultEnum.UEB_KEYS_CREATION_FAILED, initResponse.getDistributionActionResult());
+
+               Mockito.verify(connector, Mockito.times(1)).getServerList();
+               Mockito.verify(cambriaMock, Mockito.times(1)).createApiKey(Mockito.anyString(), Mockito.anyString());
+               Mockito.verify(connector, Mockito.times(0)).registerAsdcTopics(Mockito.any(ApiCredential.class));
+               System.out.println(initResponse);
+       }
+
+       @Test
+       public void initRegistrationFailedTest() throws HttpException, CambriaApiException, IOException {
+
+               // connectorMock
+               Either<List<String>, IDistributionClientResult> serversResult = Either.left(serverList);
+               Mockito.when(connector.getServerList()).thenReturn(serversResult);
+               mockArtifactTypeList();
+               DistributionClientResultImpl failureResult = new DistributionClientResultImpl(DistributionActionResultEnum.BAD_REQUEST, "Bad Request");
+               Either<TopicRegistrationResponse, DistributionClientResultImpl> topicsResult = Either.right(failureResult);
+               Mockito.when(connector.registerAsdcTopics(Mockito.any(ApiCredential.class))).thenReturn(topicsResult);
+
+               client.asdcConnector = connector;
+
+               // cambriaMock
+
+               CambriaIdentityManager cambriaMock = Mockito.mock(CambriaIdentityManager.class);
+               Mockito.when(cambriaMock.createApiKey(Mockito.any(String.class), Mockito.any(String.class))).thenReturn(new ApiCredential("public", "secret"));
+               client.cambriaIdentityManager = cambriaMock;
+
+               IDistributionClientResult initResponse = client.init(testConfiguration, new TestNotificationCallback());
+               assertEquals(DistributionActionResultEnum.BAD_REQUEST, initResponse.getDistributionActionResult());
+               Mockito.verify(connector, Mockito.times(1)).getServerList();
+               Mockito.verify(cambriaMock, Mockito.times(1)).createApiKey(Mockito.anyString(), Mockito.anyString());
+               Mockito.verify(connector, Mockito.times(1)).registerAsdcTopics(Mockito.any(ApiCredential.class));
+               System.out.println(initResponse);
+       }
+
+       @Test
+       public void testStartWithoutInit() {
+               IDistributionClientResult result = client.start();
+               assertTrue(result.getDistributionActionResult() == DistributionActionResultEnum.DISTRIBUTION_CLIENT_NOT_INITIALIZED);
+       }
+
+       private IArtifactInfo initArtifactInfo() {
+               ArtifactInfoImpl artifactInfo = new ArtifactInfoImpl();
+               artifactInfo.setArtifactURL("/asdc/v1/services/serviceName/0.1/artifacts/aaa.hh");
+               artifactInfo.setArtifactChecksum(ArtifactsUtils.getValidChecksum());
+               return artifactInfo;
+       }
+
+       // ########### TESTS TO ADD TO CI START ###########
+       public void createKeysTestCI() throws MalformedURLException, GeneralSecurityException {
+               validateConfigurationTest();
+               CambriaIdentityManager trueCambria = new CambriaClientBuilders.IdentityManagerBuilder().usingHosts(serverList).build();
+               client.cambriaIdentityManager = trueCambria;
+               DistributionClientResultImpl keysResult = client.createUebKeys();
+               Assert.assertEquals(DistributionActionResultEnum.SUCCESS, keysResult.getDistributionActionResult());
+               Assert.assertFalse(client.credential.getApiKey().isEmpty());
+               Assert.assertFalse(client.credential.getApiSecret().isEmpty());
+
+               System.out.println(keysResult);
+               System.out.println("keys: public=" + client.credential.getApiKey() + " | secret=" + client.credential.getApiSecret());
+       }
+
+       public void initTestCI() {
+               IDistributionClient distributionClient = DistributionClientFactory.createDistributionClient();
+               IDistributionClientResult init = distributionClient.init(testConfiguration, new TestNotificationCallback());
+               assertEquals(DistributionActionResultEnum.SUCCESS, init.getDistributionActionResult());
+
+       }
+
+       // @Test
+       public void registerProducerCI() {
+
+               try {
+                       CambriaTopicManager topicManager = new CambriaClientBuilders.TopicManagerBuilder().usingHosts(serverList).authenticatedBy("sSJc5qiBnKy2qrlc", "4ZRPzNJfEUK0sSNBvccd2m7X").build();
+                       topicManager.allowProducer("ASDC-DISTR-STATUS-TOPIC-TESTER", "1FSVAA3bRjhSKNAI");
+               } catch (HttpException | IOException | GeneralSecurityException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+
+               // publish
+               // StringBuilder sb = new StringBuilder();
+               // for (String s : serverList)
+               // {
+               // sb.append(s);
+               // sb.append(",");
+               // }
+               // CambriaBatchingPublisher pub = CambriaClientFactory.createSimplePublisher(sb.toString(), "ASDC-DISTR-STATUS-TOPIC-TESTER");
+               // pub.setApiCredentials("yPMwjhmOgHUyJEeW", "3RYpgvBsjpA8Y2CHdA1PM8xK" );
+               //
+               //
+               // try {
+               // pub.send("MyPartitionKey", "{\"artifactURL\":\"artifactURL_Val\", \"consumerID\" : \"123\", \"distributionID\" : \"AAA\", \"status\" : \"DOWNLOAD_OK\", \"timestamp\" : 1000}");
+               // } catch (IOException e) {
+               // e.printStackTrace();
+               // }
+               //
+               // finally{
+               //
+               //
+               // try {
+               // List<message> stuck = pub.close(15L, TimeUnit.SECONDS);
+               // assertTrue(stuck.isEmpty());
+               // } catch (IOException | InterruptedException e) {
+               // // TODO Auto-generated catch block
+               // e.printStackTrace();
+               // }
+               // }
+
+       }
+
+       public void connectorGetServersTestCI() {
+               AsdcConnectorClient connector = new AsdcConnectorClient();
+               connector.init(testConfiguration);
+
+               Either<List<String>, IDistributionClientResult> serverListFromAsdc = connector.getServerList();
+               assertTrue(serverListFromAsdc.isLeft());
+               assertEquals(serverList, serverListFromAsdc.left().value());
+       }
+
+       public void connectorRegisterCI() {
+               AsdcConnectorClient connector = new AsdcConnectorClient();
+               connector.init(testConfiguration);
+
+               ApiCredential creds = new ApiCredential("publicKey", "secretKey");
+               Either<TopicRegistrationResponse, DistributionClientResultImpl> topicsFromAsdc = connector.registerAsdcTopics(creds);
+               assertTrue(topicsFromAsdc.isLeft());
+
+       }
+
+       public void downloadArtifactTestCI() {
+               AsdcConnectorClient connector = new AsdcConnectorClient();
+               connector.init(testConfiguration);
+               IArtifactInfo artifactInfo = initArtifactInfo();
+               connector.dowloadArtifact(artifactInfo);
+
+       }
+       // ########### TESTS TO ADD TO CI END ###########
+
+}
diff --git a/src/test/java/org/openecomp/sdc/impl/HeatParserTest.java b/src/test/java/org/openecomp/sdc/impl/HeatParserTest.java
new file mode 100644 (file)
index 0000000..3b5b1a1
--- /dev/null
@@ -0,0 +1,139 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.openecomp.sdc.utils.heat.HeatParameter;
+import org.openecomp.sdc.utils.heat.HeatParameterConstraint;
+import org.openecomp.sdc.utils.heat.HeatParser;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Resources;
+
+public class HeatParserTest {
+
+       @Test
+       public void testParametersParsing() throws IOException{
+               String resourceName = "heatExample.yaml";
+               URL url = Resources.getResource(resourceName);
+               String heatFileContents = Resources.toString(url, Charsets.UTF_8);
+               assertNotNull("Didn't find "+resourceName, heatFileContents);
+
+               HeatParser heatParser = new HeatParser();
+               //Flat parameter entry
+               Map<String, HeatParameter> parameters = heatParser.getHeatParameters(heatFileContents);
+               HeatParameter heatParameter1 = parameters.get("image_name_1");
+               validateField("string", heatParameter1.getType(), "type");
+               validateField("Image Name", heatParameter1.getLabel(), "label");
+               validateField("SCOIMAGE Specify an image name for instance1", heatParameter1.getDescription(), "description");
+               validateField("cirros-0.3.1-x86_64", heatParameter1.getDefault(), "default");
+               validateField(null, heatParameter1.getConstraints(), "constraints");
+               validateField("false", heatParameter1.getHidden(), "hidden");
+
+
+               //Flat parameter entry with constraints
+               heatParameter1 = parameters.get("network_id");
+               validateField("string", heatParameter1.getType(), "type");
+               validateField("Network ID", heatParameter1.getLabel(), "label");
+               validateField("SCONETWORK Network to be used for the compute instance", heatParameter1.getDescription(), "description");
+               validateField(null, heatParameter1.getDefault(), "default");
+               validateField("true", heatParameter1.getHidden(), "hidden");
+
+               //Constraints
+               List<HeatParameterConstraint> constraints = heatParameter1.getConstraints();
+               assertEquals("Number of constraints", 6, constraints.size());
+
+               //Length
+               HeatParameterConstraint lengthConstraint = heatParameter1.getLengthConstraint();
+               assertNotNull(lengthConstraint);
+               Map<String, String> expectedMap = new HashMap<>();
+               expectedMap.put("min", "6");
+               expectedMap.put("max", "8");
+               validateField(expectedMap, lengthConstraint.getLength(), "length");
+               validateField("Password length must be between 6 and 8 characters.", lengthConstraint.getDescription(), "length description");
+
+               //Range
+               HeatParameterConstraint rangeConstraint = heatParameter1.getRangeConstraint();
+               assertNotNull(rangeConstraint);
+               validateField(expectedMap, rangeConstraint.getRange(), "range");
+               validateField("Range description", rangeConstraint.getDescription(), "range description");
+
+               //Allowed values
+               HeatParameterConstraint allowedValues = heatParameter1.getAllowedValuesConstraint();
+               assertNotNull(allowedValues);
+               List<String> expectedValues = new ArrayList<>();
+               expectedValues.add("m1.small");
+               expectedValues.add("m1.medium");
+               expectedValues.add("m1.large");
+               validateField(expectedValues, allowedValues.getAllowed_values(), "allowed_values");     
+               validateField("Allowed values description", allowedValues.getDescription(), "allowed_values description");
+
+               //Allowed pattern
+               List<HeatParameterConstraint> allowedPatternList = heatParameter1.getAllowedPatternConstraint();
+               assertNotNull(allowedPatternList);
+               assertEquals("Allowed pattern list", 2, allowedPatternList.size());
+               HeatParameterConstraint allowedPattern = allowedPatternList.get(0);
+               validateField("[a-zA-Z0-9]+", allowedPattern.getAllowed_pattern(), "allowed_pattern");  
+               validateField("Password must consist of characters and numbers only.", allowedPattern.getDescription(), "allowed_pattern description");
+               allowedPattern = allowedPatternList.get(1);
+               validateField("[A-Z]+[a-zA-Z0-9]*", allowedPattern.getAllowed_pattern(), "allowed_pattern");    
+               validateField("Password must start with an uppercase character.", allowedPattern.getDescription(), "allowed_pattern description");
+
+               //Custom constraint
+               List<HeatParameterConstraint> customConstraintList = heatParameter1.getCustomConstraintConstraint();
+               assertNotNull(customConstraintList);
+               assertEquals("Custom constraint list", 1, customConstraintList.size());
+               HeatParameterConstraint customConstraint = customConstraintList.get(0);
+               validateField("nova.keypair", customConstraint.getCustom_constraint(), "custom_constraint");    
+               validateField("Custom description", customConstraint.getDescription(), "custom_constraint description");
+       }
+       
+       @Test
+       public void testParametersParsingInvalidYaml() throws IOException{
+               String invalidHeatFileContents = "just text";
+               HeatParser heatParser = new HeatParser();
+               //Flat parameter entry
+               Map<String, HeatParameter> parameters = heatParser.getHeatParameters(invalidHeatFileContents);
+               assertNull(parameters);
+       }
+       
+       @Test
+       public void testParametersParsingNoParamteresSection() throws IOException{
+               String heatFileContentsNoParams = "heat_template_version: 2013-05-23\r\n\r\ndescription: Simple template to deploy a stack with two virtual machine instances";
+               HeatParser heatParser = new HeatParser();
+               //Flat parameter entry
+               Map<String, HeatParameter> parameters = heatParser.getHeatParameters(heatFileContentsNoParams);
+               assertNull(parameters);
+       }
+
+       private void validateField(Object expected, Object actual, String type){
+               assertEquals("Field of type "+type+":", expected, actual);
+       }
+}
diff --git a/src/test/java/org/openecomp/sdc/impl/NotificationConsumerTest.java b/src/test/java/org/openecomp/sdc/impl/NotificationConsumerTest.java
new file mode 100644 (file)
index 0000000..281a157
--- /dev/null
@@ -0,0 +1,281 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.impl;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.util.ArrayQueue;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.openecomp.sdc.api.consumer.INotificationCallback;
+import org.openecomp.sdc.api.notification.INotificationData;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.impl.ArtifactInfoImpl;
+import org.openecomp.sdc.impl.DistributionClientImpl;
+import org.openecomp.sdc.impl.NotificationConsumer;
+import org.openecomp.sdc.utils.ArtifactTypeEnum;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+import org.openecomp.sdc.utils.DistributionClientConstants;
+
+import com.att.nsa.cambria.client.CambriaConsumer;
+
+public class NotificationConsumerTest {
+       private CambriaConsumer cambriaConsumer = mock(CambriaConsumer.class);
+       private INotificationCallback clientCallback = spy(INotificationCallback.class);
+       private Queue<Iterable<String>> notificationsQueue = new ArrayQueue<>(100);
+       private DistributionClientImpl distributionClient = spy(DistributionClientImpl.class);
+       private List<String> artifactsTypes = Arrays.asList(ArtifactTypeEnum.HEAT.name());
+       private List<Boolean> notificationStatusResults = new ArrayList<>();
+       final static IDistributionClientResult DISTRIBUTION_SUCCESS_RESULT = buildSuccessResult();
+
+       private NotificationConsumer createNotificationConsumer() {
+               return new NotificationConsumer(cambriaConsumer, clientCallback, artifactsTypes, distributionClient);
+       }
+
+       @Before
+       public void beforeTest() throws IOException {
+               Mockito.reset(clientCallback, distributionClient);
+               when(cambriaConsumer.fetch()).then(new Answer<Iterable<String>>() {
+                       @Override
+                       public Iterable<String> answer(InvocationOnMock invocation) throws Throwable {
+                               if (!notificationsQueue.isEmpty()) {
+                                       return notificationsQueue.remove();
+                               } else {
+                                       return new ArrayList<>();
+                               }
+                       }
+               });
+               when(distributionClient.sendNotificationStatus(Mockito.anyLong(), Mockito.anyString(), Mockito.any(ArtifactInfoImpl.class), Mockito.anyBoolean())).then(new Answer<IDistributionClientResult>() {
+                       @Override
+                       public IDistributionClientResult answer(InvocationOnMock invocation) throws Throwable {
+                               boolean isNotified = (boolean) invocation.getArguments()[3];
+                               notificationStatusResults.add(Boolean.valueOf(isNotified));
+                               return DISTRIBUTION_SUCCESS_RESULT;
+                       }
+               });
+
+       }
+
+       private static IDistributionClientResult buildSuccessResult() {
+               return new IDistributionClientResult() {
+
+                       @Override
+                       public String getDistributionMessageResult() {
+                               return "";
+                       }
+
+                       @Override
+                       public DistributionActionResultEnum getDistributionActionResult() {
+                               return DistributionActionResultEnum.SUCCESS;
+                       }
+               };
+       }
+
+       @Test
+       public void testNoNotifiactionsSent() throws InterruptedException {
+
+               ScheduledExecutorService executorPool = Executors.newScheduledThreadPool(DistributionClientConstants.POOL_SIZE);
+               executorPool.scheduleAtFixedRate(createNotificationConsumer(), 0, 100, TimeUnit.MILLISECONDS);
+
+               Thread.sleep(1000);
+               executorPool.shutdown();
+
+               Mockito.verify(clientCallback, Mockito.times(0)).activateCallback(Mockito.any(INotificationData.class));
+
+       }
+
+       @Test
+       public void testNonRelevantNotificationSent() throws InterruptedException {
+
+               simulateNotificationFromUEB(getAsdcServiceNotificationWithoutHeatArtifact());
+               Mockito.verify(clientCallback, Mockito.times(0)).activateCallback(Mockito.any(INotificationData.class));
+
+       }
+
+       @Test
+       public void testRelevantNotificationSent() throws InterruptedException {
+               simulateNotificationFromUEB(getAsdcServiceNotificationWithHeatArtifact());
+               Mockito.verify(clientCallback, Mockito.times(1)).activateCallback(Mockito.any(INotificationData.class));
+
+       }
+
+       @Test
+       public void testNonExistingArtifactsNotificationSent() throws InterruptedException {
+               simulateNotificationFromUEB(getAsdcNotificationWithNonExistentArtifact());
+               Mockito.verify(clientCallback, Mockito.times(1)).activateCallback(Mockito.any(INotificationData.class));
+
+       }
+
+       @Test
+       public void testNotificationStatusSent() throws InterruptedException {
+               simulateNotificationFromUEB(getAsdcServiceNotificationWithHeatArtifact());
+
+               Mockito.verify(distributionClient, Mockito.times(3)).sendNotificationStatus(Mockito.anyLong(), Mockito.anyString(), Mockito.any(ArtifactInfoImpl.class), Mockito.anyBoolean());
+               assertTrue(countInstances(notificationStatusResults, Boolean.TRUE) == 1);
+               assertTrue(countInstances(notificationStatusResults, Boolean.FALSE) == 2);
+       }
+
+       @Test
+       public void testNotificationRelatedArtifacts() throws InterruptedException {
+               List<String> artifactTypesTmp = new ArrayList<>();
+               for (ArtifactTypeEnum artifactTypeEnum : ArtifactTypeEnum.values()) {
+                       artifactTypesTmp.add(artifactTypeEnum.name());
+               }
+               artifactsTypes = artifactTypesTmp;
+               simulateNotificationFromUEB(getAsdcServiceNotificationWithRelatedArtifacts());
+
+               Mockito.verify(distributionClient, Mockito.times(3)).sendNotificationStatus(Mockito.anyLong(), Mockito.anyString(), Mockito.any(ArtifactInfoImpl.class), Mockito.anyBoolean());
+               assertTrue(countInstances(notificationStatusResults, Boolean.TRUE) == 3);
+               assertTrue(countInstances(notificationStatusResults, Boolean.FALSE) == 0);
+       }
+
+       @Test
+       public void testNotificationStatusWithServiceArtifatcs() throws InterruptedException {
+               simulateNotificationFromUEB(getNotificationWithServiceArtifatcs());
+               Mockito.verify(distributionClient, Mockito.times(6)).sendNotificationStatus(Mockito.anyLong(), Mockito.anyString(), Mockito.any(ArtifactInfoImpl.class), Mockito.anyBoolean());
+               assertTrue(countInstances(notificationStatusResults, Boolean.TRUE) == 2);
+               assertTrue(countInstances(notificationStatusResults, Boolean.FALSE) == 4);
+
+       }
+
+       private void simulateNotificationFromUEB(final String notificationFromUEB) throws InterruptedException {
+               ScheduledExecutorService executorPool = Executors.newScheduledThreadPool(DistributionClientConstants.POOL_SIZE);
+               executorPool.scheduleAtFixedRate(createNotificationConsumer(), 0, 100, TimeUnit.MILLISECONDS);
+
+               Thread.sleep(200);
+
+               List<String> nonHeatNotification = Arrays.asList(notificationFromUEB);
+               notificationsQueue.add(nonHeatNotification);
+               Thread.sleep(800);
+               executorPool.shutdown();
+       }
+
+       private String getAsdcServiceNotificationWithHeatArtifact() {
+               return "{\"distributionID\" : \"bcc7a72e-90b1-4c5f-9a37-28dc3cd86416\",\r\n" + "        \"serviceName\" : \"Testnotificationser1\",\r\n" + "    \"serviceVersion\" : \"1.0\",\r\n"
+                               + "     \"serviceUUID\" : \"7f7f94f4-373a-4b71-a0e3-80ae2ba4eb5d\",\r\n" + "    \"serviceDescription\" : \"TestNotificationVF1\",\r\n" + "      \"resources\" : [{\r\n" + "                     \"resourceInstanceName\" : \"testnotificationvf11\",\r\n"
+                               + "                     \"resourceName\" : \"TestNotificationVF1\",\r\n" + "                    \"resourceVersion\" : \"1.0\",\r\n" + "                 \"resoucreType\" : \"VF\",\r\n" + "                     \"resourceUUID\" : \"907e1746-9f69-40f5-9f2a-313654092a2d\",\r\n"
+                               + "                     \"artifacts\" : [{\r\n" + "                                     \"artifactName\" : \"sample-xml-alldata-1-1.xml\",\r\n" + "                                     \"artifactType\" : \"YANG_XML\",\r\n"
+                               + "                                     \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/sample-xml-alldata-1-1.xml\",\r\n"
+                               + "                                     \"artifactChecksum\" : \"MTUxODFkMmRlOTNhNjYxMGYyYTI1ZjA5Y2QyNWQyYTk\\u003d\",\r\n" + "                                 \"artifactDescription\" : \"MyYang\",\r\n" + "                                  \"artifactTimeout\" : 0,\r\n"
+                               + "                                     \"artifactUUID\" : \"0005bc4a-2c19-452e-be6d-d574a56be4d0\",\r\n" + "                                   \"artifactVersion\" : \"1\"\r\n" + "                            }, {\r\n" + "                                   \"artifactName\" : \"heat.yaml\",\r\n"
+                               + "                                     \"artifactType\" : \"HEAT\",\r\n" + "                                   \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.yaml\",\r\n"
+                               + "                                     \"artifactChecksum\" : \"ODEyNjE4YTMzYzRmMTk2ODVhNTU2NTg3YWEyNmIxMTM\\u003d\",\r\n" + "                                 \"artifactDescription\" : \"heat\",\r\n" + "                                    \"artifactTimeout\" : 60,\r\n"
+                               + "                                     \"artifactUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\",\r\n" + "                                   \"artifactVersion\" : \"1\"\r\n" + "                            }, {\r\n" + "                                   \"artifactName\" : \"heat.env\",\r\n"
+                               + "                                     \"artifactType\" : \"HEAT_ENV\",\r\n" + "                                       \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.env\",\r\n"
+                               + "                                     \"artifactChecksum\" : \"NGIzMjExZTM1NDc2NjBjOTQyMGJmMWNiMmU0NTE5NzM\\u003d\",\r\n" + "                                 \"artifactDescription\" : \"Auto-generated HEAT Environment deployment artifact\",\r\n"
+                               + "                                     \"artifactTimeout\" : 0,\r\n" + "                                       \"artifactUUID\" : \"ce65d31c-35c0-43a9-90c7-596fc51d0c86\",\r\n" + "                                   \"artifactVersion\" : \"1\",\r\n"
+                               + "                                     \"generatedFromUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\"\r\n" + "                               }\r\n" + "                      ]\r\n" + "              }\r\n" + "      ]}";
+       }
+
+       private String getAsdcNotificationWithNonExistentArtifact() {
+               return "{\"distributionID\" : \"bcc7a72e-90b1-4c5f-9a37-28dc3cd86416\",\r\n" + "        \"serviceName\" : \"Testnotificationser1\",\r\n" + "    \"serviceVersion\" : \"1.0\",\r\n"
+                               + "     \"serviceUUID\" : \"7f7f94f4-373a-4b71-a0e3-80ae2ba4eb5d\",\r\n" + "    \"serviceDescription\" : \"TestNotificationVF1\",\r\n" + "      \"bugabuga\" : \"xyz\",\r\n" + "        \"resources\" : [{\r\n"
+                               + "                     \"resourceInstanceName\" : \"testnotificationvf11\",\r\n" + "                   \"resourceName\" : \"TestNotificationVF1\",\r\n" + "                    \"resourceVersion\" : \"1.0\",\r\n" + "                 \"resoucreType\" : \"VF\",\r\n"
+                               + "                     \"resourceUUID\" : \"907e1746-9f69-40f5-9f2a-313654092a2d\",\r\n" + "                   \"artifacts\" : [{\r\n" + "                                     \"artifactName\" : \"heat.yaml\",\r\n" + "                                      \"artifactType\" : \"HEAT\",\r\n"
+                               + "                                     \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.yaml\",\r\n"
+                               + "                                     \"artifactChecksum\" : \"ODEyNjE4YTMzYzRmMTk2ODVhNTU2NTg3YWEyNmIxMTM\\u003d\",\r\n" + "                                 \"artifactDescription\" : \"heat\",\r\n" + "                                    \"artifactTimeout\" : 60,\r\n"
+                               + "                                     \"artifactUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\",\r\n" + "                                   \"artifactBuga\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\",\r\n" + "                                   \"artifactVersion\" : \"1\"\r\n"
+                               + "                             }, {\r\n" + "                                   \"artifactName\" : \"buga.bug\",\r\n" + "                                       \"artifactType\" : \"BUGA_BUGA\",\r\n"
+                               + "                                     \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.env\",\r\n"
+                               + "                                     \"artifactChecksum\" : \"NGIzMjExZTM1NDc2NjBjOTQyMGJmMWNiMmU0NTE5NzM\\u003d\",\r\n" + "                                 \"artifactDescription\" : \"Auto-generated HEAT Environment deployment artifact\",\r\n"
+                               + "                                     \"artifactTimeout\" : 0,\r\n" + "                                       \"artifactUUID\" : \"ce65d31c-35c0-43a9-90c7-596fc51d0c86\",\r\n" + "                                   \"artifactVersion\" : \"1\",\r\n"
+                               + "                                     \"generatedFromUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\"\r\n" + "                               }\r\n" + "                      ]\r\n" + "              }\r\n" + "      ]}";
+       }
+
+       private String getAsdcServiceNotificationWithRelatedArtifacts() {
+               return "{\"distributionID\" : \"bcc7a72e-90b1-4c5f-9a37-28dc3cd86416\",\r\n" + "        \"serviceName\" : \"Testnotificationser1\",\r\n" + "    \"serviceVersion\" : \"1.0\",\r\n"
+                               + "     \"serviceUUID\" : \"7f7f94f4-373a-4b71-a0e3-80ae2ba4eb5d\",\r\n" + "    \"serviceDescription\" : \"TestNotificationVF1\",\r\n" + "      \"resources\" : [{\r\n" + "                     \"resourceInstanceName\" : \"testnotificationvf11\",\r\n"
+                               + "                     \"resourceName\" : \"TestNotificationVF1\",\r\n" + "                    \"resourceVersion\" : \"1.0\",\r\n" + "                 \"resoucreType\" : \"VF\",\r\n" + "                     \"resourceUUID\" : \"907e1746-9f69-40f5-9f2a-313654092a2d\",\r\n"
+                               + "                     \"artifacts\" : [{\r\n" + "                                     \"artifactName\" : \"sample-xml-alldata-1-1.xml\",\r\n" + "                                     \"artifactType\" : \"YANG_XML\",\r\n"
+                               + "                                     \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/sample-xml-alldata-1-1.xml\",\r\n"
+                               + "                                     \"artifactChecksum\" : \"MTUxODFkMmRlOTNhNjYxMGYyYTI1ZjA5Y2QyNWQyYTk\\u003d\",\r\n" + "                                 \"artifactDescription\" : \"MyYang\",\r\n" + "                                  \"artifactTimeout\" : 0,\r\n"
+                               + "                                     \"artifactUUID\" : \"0005bc4a-2c19-452e-be6d-d574a56be4d0\",\r\n" + "                                   \"artifactVersion\" : \"1\",\r\n" + "                   \"relatedArtifacts\" : [\r\n"
+                               + "                                             \"ce65d31c-35c0-43a9-90c7-596fc51d0c86\"\r\n" + "                                       ]" + "                          }, {\r\n" + "                                   \"artifactName\" : \"heat.yaml\",\r\n"
+                               + "                                     \"artifactType\" : \"HEAT\",\r\n" + "                                   \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.yaml\",\r\n"
+                               + "                                     \"artifactChecksum\" : \"ODEyNjE4YTMzYzRmMTk2ODVhNTU2NTg3YWEyNmIxMTM\\u003d\",\r\n" + "                                 \"artifactDescription\" : \"heat\",\r\n" + "                                    \"artifactTimeout\" : 60,\r\n"
+                               + "                                     \"artifactUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\",\r\n" + "                                   \"artifactVersion\" : \"1\", \r\n" + "                                  \"relatedArtifacts\" : [\r\n"
+                               + "                                             \"0005bc4a-2c19-452e-be6d-d574a56be4d0\", \r\n" + "                                             \"ce65d31c-35c0-43a9-90c7-596fc51d0c86\"\r\n" + "                                       ]" + "                          }, {\r\n"
+                               + "                                     \"artifactName\" : \"heat.env\",\r\n" + "                                       \"artifactType\" : \"HEAT_ENV\",\r\n"
+                               + "                                     \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.env\",\r\n"
+                               + "                                     \"artifactChecksum\" : \"NGIzMjExZTM1NDc2NjBjOTQyMGJmMWNiMmU0NTE5NzM\\u003d\",\r\n" + "                                 \"artifactDescription\" : \"Auto-generated HEAT Environment deployment artifact\",\r\n"
+                               + "                                     \"artifactTimeout\" : 0,\r\n" + "                                       \"artifactUUID\" : \"ce65d31c-35c0-43a9-90c7-596fc51d0c86\",\r\n" + "                                   \"artifactVersion\" : \"1\",\r\n"
+                               + "                                     \"generatedFromUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\"\r\n" + "                               }\r\n" + "                      ]\r\n" + "              }\r\n" + "      ]}";
+       }
+
+       private String getAsdcServiceNotificationWithoutHeatArtifact() {
+               return "{" + "   \"distributionID\" : \"5v1234d8-5b6d-42c4-7t54-47v95n58qb7\"," + "   \"serviceName\" : \"srv1\"," + "   \"serviceVersion\": \"2.0\"," + "   \"serviceUUID\" : \"4e0697d8-5b6d-42c4-8c74-46c33d46624c\","
+                               + "   \"serviceArtifacts\":[" + "                    {" + "                       \"artifactName\" : \"ddd.yml\"," + "                       \"artifactType\" : \"DG_XML\"," + "                       \"artifactTimeout\" : \"65\","
+                               + "                       \"artifactDescription\" : \"description\"," + "                       \"artifactURL\" :" + "                      \"/asdc/v1/catalog/services/srv1/2.0/resources/ddd/3.0/artifacts/ddd.xml\" ,"
+                               + "                       \"resourceUUID\" : \"4e5874d8-5b6d-42c4-8c74-46c33d90drw\" ," + "                       \"checksum\" : \"15e389rnrp58hsw==\"" + "                    }" + "                  ]" + "}";
+       }
+
+       private String getNotificationWithServiceArtifatcs() {
+               return "{\r\n" + "  \"distributionID\" : \"bcc7a72e-90b1-4c5f-9a37-28dc3cd86416\",\r\n" + "  \"serviceName\" : \"Testnotificationser1\",\r\n" + "  \"serviceVersion\" : \"1.0\",\r\n"
+                               + "  \"serviceUUID\" : \"7f7f94f4-373a-4b71-a0e3-80ae2ba4eb5d\",\r\n" + "  \"serviceDescription\" : \"TestNotificationVF1\",\r\n" + "  \"serviceArtifacts\" : [{\r\n" + "          \"artifactName\" : \"sample-xml-alldata-1-1.xml\",\r\n"
+                               + "          \"artifactType\" : \"YANG_XML\",\r\n" + "          \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/sample-xml-alldata-1-1.xml\",\r\n"
+                               + "          \"artifactChecksum\" : \"MTUxODFkMmRlOTNhNjYxMGYyYTI1ZjA5Y2QyNWQyYTk\\u003d\",\r\n" + "          \"artifactDescription\" : \"MyYang\",\r\n" + "          \"artifactTimeout\" : 0,\r\n"
+                               + "          \"artifactUUID\" : \"0005bc4a-2c19-452e-be6d-d574a56be4d0\",\r\n" + "          \"artifactVersion\" : \"1\"\r\n" + "        }, {\r\n" + "          \"artifactName\" : \"heat.yaml\",\r\n"
+                               + "          \"artifactType\" : \"HEAT\",\r\n" + "          \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.yaml\",\r\n"
+                               + "          \"artifactChecksum\" : \"ODEyNjE4YTMzYzRmMTk2ODVhNTU2NTg3YWEyNmIxMTM\\u003d\",\r\n" + "          \"artifactDescription\" : \"heat\",\r\n" + "          \"artifactTimeout\" : 60,\r\n"
+                               + "          \"artifactUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\",\r\n" + "          \"artifactVersion\" : \"1\"\r\n" + "        }, {\r\n" + "          \"artifactName\" : \"heat.env\",\r\n"
+                               + "          \"artifactType\" : \"HEAT_ENV\",\r\n" + "          \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.env\",\r\n"
+                               + "          \"artifactChecksum\" : \"NGIzMjExZTM1NDc2NjBjOTQyMGJmMWNiMmU0NTE5NzM\\u003d\",\r\n" + "          \"artifactDescription\" : \"Auto-generated HEAT Environment deployment artifact\",\r\n"
+                               + "          \"artifactTimeout\" : 0,\r\n" + "          \"artifactUUID\" : \"ce65d31c-35c0-43a9-90c7-596fc51d0c86\",\r\n" + "          \"artifactVersion\" : \"1\",\r\n"
+                               + "          \"generatedFromUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\"\r\n" + "        }\r\n" + "      ],\r\n" + "  \"resources\" : [{\r\n" + "      \"resourceInstanceName\" : \"testnotificationvf11\",\r\n"
+                               + "      \"resourceName\" : \"TestNotificationVF1\",\r\n" + "      \"resourceVersion\" : \"1.0\",\r\n" + "      \"resoucreType\" : \"VF\",\r\n" + "      \"resourceUUID\" : \"907e1746-9f69-40f5-9f2a-313654092a2d\",\r\n"
+                               + "      \"artifacts\" : [{\r\n" + "          \"artifactName\" : \"sample-xml-alldata-1-1.xml\",\r\n" + "          \"artifactType\" : \"YANG_XML\",\r\n"
+                               + "          \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/sample-xml-alldata-1-1.xml\",\r\n"
+                               + "          \"artifactChecksum\" : \"MTUxODFkMmRlOTNhNjYxMGYyYTI1ZjA5Y2QyNWQyYTk\\u003d\",\r\n" + "          \"artifactDescription\" : \"MyYang\",\r\n" + "          \"artifactTimeout\" : 0,\r\n"
+                               + "          \"artifactUUID\" : \"0005bc4a-2c19-452e-be6d-d574a56be4d0\",\r\n" + "          \"artifactVersion\" : \"1\"\r\n" + "        }, {\r\n" + "          \"artifactName\" : \"heat.yaml\",\r\n"
+                               + "          \"artifactType\" : \"HEAT\",\r\n" + "          \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.yaml\",\r\n"
+                               + "          \"artifactChecksum\" : \"ODEyNjE4YTMzYzRmMTk2ODVhNTU2NTg3YWEyNmIxMTM\\u003d\",\r\n" + "          \"artifactDescription\" : \"heat\",\r\n" + "          \"artifactTimeout\" : 60,\r\n"
+                               + "          \"artifactUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\",\r\n" + "          \"artifactVersion\" : \"1\"\r\n" + "        }, {\r\n" + "          \"artifactName\" : \"heat.env\",\r\n"
+                               + "          \"artifactType\" : \"HEAT_ENV\",\r\n" + "          \"artifactURL\" : \"/asdc/v1/catalog/services/Testnotificationser1/1.0/resourceInstances/testnotificationvf11/artifacts/heat.env\",\r\n"
+                               + "          \"artifactChecksum\" : \"NGIzMjExZTM1NDc2NjBjOTQyMGJmMWNiMmU0NTE5NzM\\u003d\",\r\n" + "          \"artifactDescription\" : \"Auto-generated HEAT Environment deployment artifact\",\r\n"
+                               + "          \"artifactTimeout\" : 0,\r\n" + "          \"artifactUUID\" : \"ce65d31c-35c0-43a9-90c7-596fc51d0c86\",\r\n" + "          \"artifactVersion\" : \"1\",\r\n"
+                               + "          \"generatedFromUUID\" : \"8df6123c-f368-47d3-93be-1972cefbcc35\"\r\n" + "        }\r\n" + "      ]\r\n" + "    }\r\n" + "  ]\r\n" + "}";
+       }
+
+       private <T> int countInstances(List<T> list, T element) {
+               int count = 0;
+               for (T curr : list) {
+                       if (curr.equals(element)) {
+                               count++;
+                       }
+               }
+               return count;
+       }
+}
diff --git a/src/test/java/org/openecomp/sdc/utils/ArtifactsUtils.java b/src/test/java/org/openecomp/sdc/utils/ArtifactsUtils.java
new file mode 100644 (file)
index 0000000..5a24849
--- /dev/null
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+
+
+import org.apache.commons.codec.binary.Base64;
+import org.openecomp.sdc.impl.mock.DistributionClientDownloadResultStubImpl;
+import org.openecomp.sdc.utils.GeneralUtils;
+
+
+
+public class ArtifactsUtils {
+       static DistributionClientDownloadResultStubImpl distributionClientDownloadResultStubImpl = new DistributionClientDownloadResultStubImpl();
+       
+       public static byte [] getArtifactPayload(){
+               return distributionClientDownloadResultStubImpl.getArtifactPayload();
+       }
+       
+       public static String getValidChecksum(){
+               
+               String payloadStr = new String(distributionClientDownloadResultStubImpl.getArtifactPayload());
+                               
+               byte[] decodedPayload = Base64.decodeBase64(payloadStr);
+               String checkSum = GeneralUtils.calculateMD5 (new String(decodedPayload));
+               
+               return checkSum;
+       }
+
+}
diff --git a/src/test/java/org/openecomp/sdc/utils/TestConfiguration.java b/src/test/java/org/openecomp/sdc/utils/TestConfiguration.java
new file mode 100644 (file)
index 0000000..e4b0ca8
--- /dev/null
@@ -0,0 +1,272 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openecomp.sdc.api.consumer.IConfiguration;
+import org.openecomp.sdc.utils.ArtifactTypeEnum;
+import org.openecomp.sdc.utils.DistributionClientConstants;
+
+public class TestConfiguration implements IConfiguration {
+
+       private String asdcAddress;
+       private String user;
+       private String password;
+       private int pollingInterval = DistributionClientConstants.MIN_POLLING_INTERVAL_SEC;
+       private int pollingTimeout = DistributionClientConstants.POLLING_TIMEOUT_SEC;
+       private List<String> relevantArtifactTypes;
+       private String consumerGroup;
+       private String environmentName;
+       private String comsumerID;
+       private String keyStorePath;
+       private String keyStorePassword;
+       private boolean activateServerTLSAuth;
+
+       public TestConfiguration(IConfiguration other) {
+               this.asdcAddress = other.getAsdcAddress();
+               this.comsumerID = other.getConsumerID();
+               this.consumerGroup = other.getConsumerGroup();
+               this.environmentName = other.getEnvironmentName();
+               this.password = other.getPassword();
+               this.pollingInterval = other.getPollingInterval();
+               this.pollingTimeout = other.getPollingTimeout();
+               this.relevantArtifactTypes = other.getRelevantArtifactTypes();
+               this.user = other.getUser();
+               this.keyStorePath = other.getKeyStorePath();
+               this.keyStorePassword = other.getKeyStorePassword();
+               this.activateServerTLSAuth = other.activateServerTLSAuth();
+       }
+
+       public TestConfiguration() {
+               this.asdcAddress = "localhost:8443";
+               this.comsumerID = "mso-123456";
+               this.consumerGroup = "mso-group";
+               this.environmentName = "PROD";
+               this.password = "password";
+               this.pollingInterval = 20;
+               this.pollingTimeout = 20;
+               this.relevantArtifactTypes = new ArrayList<String>();
+               this.relevantArtifactTypes.add(ArtifactTypeEnum.HEAT.name());
+               this.user = "mso-user";
+               this.keyStorePath = "etc/asdc-client.jks";
+               this.keyStorePassword = "Aa123456";
+               this.activateServerTLSAuth = false;
+       }
+
+       @Override
+       public String getAsdcAddress() {
+               return asdcAddress;
+       }
+
+       @Override
+       public String getUser() {
+               return user;
+       }
+
+       @Override
+       public String getPassword() {
+               return password;
+       }
+
+       @Override
+       public int getPollingInterval() {
+               return pollingInterval;
+       }
+
+       @Override
+       public int getPollingTimeout() {
+               return pollingTimeout;
+       }
+
+       @Override
+       public List<String> getRelevantArtifactTypes() {
+               return relevantArtifactTypes;
+       }
+
+       @Override
+       public String getConsumerGroup() {
+               return consumerGroup;
+       }
+
+       @Override
+       public String getEnvironmentName() {
+               return environmentName;
+       }
+
+       @Override
+       public String getConsumerID() {
+               return comsumerID;
+       }
+
+       @Override
+       public String getKeyStorePath() {
+               return keyStorePath;
+       }
+
+       @Override
+       public String getKeyStorePassword() {
+               return keyStorePassword;
+       }
+
+       public String getComsumerID() {
+               return comsumerID;
+       }
+
+       public void setComsumerID(String comsumerID) {
+               this.comsumerID = comsumerID;
+       }
+
+       public void setAsdcAddress(String asdcAddress) {
+               this.asdcAddress = asdcAddress;
+       }
+
+       public void setUser(String user) {
+               this.user = user;
+       }
+
+       public void setPassword(String password) {
+               this.password = password;
+       }
+
+       public void setPollingInterval(int pollingInterval) {
+               this.pollingInterval = pollingInterval;
+       }
+
+       public void setPollingTimeout(int pollingTimeout) {
+               this.pollingTimeout = pollingTimeout;
+       }
+
+       public void setRelevantArtifactTypes(List<String> relevantArtifactTypes) {
+               this.relevantArtifactTypes = relevantArtifactTypes;
+       }
+
+       public void setConsumerGroup(String consumerGroup) {
+               this.consumerGroup = consumerGroup;
+       }
+
+       public void setEnvironmentName(String environmentName) {
+               this.environmentName = environmentName;
+       }
+
+       public void setKeyStorePath(String keyStorePath) {
+               this.keyStorePath = keyStorePath;
+       }
+
+       public void setKeyStorePassword(String keyStorePassword) {
+               this.keyStorePassword = keyStorePassword;
+       }
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + ((asdcAddress == null) ? 0 : asdcAddress.hashCode());
+               result = prime * result + ((comsumerID == null) ? 0 : comsumerID.hashCode());
+               result = prime * result + ((consumerGroup == null) ? 0 : consumerGroup.hashCode());
+               result = prime * result + ((environmentName == null) ? 0 : environmentName.hashCode());
+               result = prime * result + ((password == null) ? 0 : password.hashCode());
+               result = prime * result + pollingInterval;
+               result = prime * result + pollingTimeout;
+               result = prime * result + ((relevantArtifactTypes == null) ? 0 : relevantArtifactTypes.hashCode());
+               result = prime * result + ((user == null) ? 0 : user.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean activateServerTLSAuth() {
+
+               return activateServerTLSAuth;
+       }
+
+       public void setactivateServerTLSAuth(boolean activateServerTLSAuth) {
+               this.activateServerTLSAuth = activateServerTLSAuth;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass())
+                       return false;
+               TestConfiguration other = (TestConfiguration) obj;
+               if (asdcAddress == null) {
+                       if (other.asdcAddress != null)
+                               return false;
+               } else if (!asdcAddress.equals(other.asdcAddress))
+                       return false;
+               if (comsumerID == null) {
+                       if (other.comsumerID != null)
+                               return false;
+               } else if (!comsumerID.equals(other.comsumerID))
+                       return false;
+               if (consumerGroup == null) {
+                       if (other.consumerGroup != null)
+                               return false;
+               } else if (!consumerGroup.equals(other.consumerGroup))
+                       return false;
+               if (environmentName == null) {
+                       if (other.environmentName != null)
+                               return false;
+               } else if (!environmentName.equals(other.environmentName))
+                       return false;
+               if (password == null) {
+                       if (other.password != null)
+                               return false;
+               } else if (!password.equals(other.password))
+                       return false;
+               if (pollingInterval != other.pollingInterval)
+                       return false;
+               if (pollingTimeout != other.pollingTimeout)
+                       return false;
+               if (relevantArtifactTypes == null) {
+                       if (other.relevantArtifactTypes != null)
+                               return false;
+               } else if (!relevantArtifactTypes.equals(other.relevantArtifactTypes))
+                       return false;
+               if (user == null) {
+                       if (other.user != null)
+                               return false;
+               } else if (!user.equals(other.user))
+                       return false;
+               if (keyStorePath == null) {
+                       if (other.keyStorePath != null)
+                               return false;
+               } else if (!keyStorePath.equals(other.keyStorePath))
+                       return false;
+               if (keyStorePassword == null) {
+                       if (other.keyStorePassword != null)
+                               return false;
+               } else if (!keyStorePassword.equals(other.keyStorePassword))
+                       return false;
+
+               return true;
+       }
+
+       @Override
+       public String toString() {
+               return "TestConfiguration [asdcAddress=" + asdcAddress + ", user=" + user + ", password=" + password + ", pollingInterval=" + pollingInterval + ", pollingTimeout=" + pollingTimeout + ", relevantArtifactTypes=" + relevantArtifactTypes
+                               + ", consumerGroup=" + consumerGroup + ", environmentName=" + environmentName + ", comsumerID=" + comsumerID + "]";
+       }
+}
diff --git a/src/test/java/org/openecomp/sdc/utils/TestNotificationCallback.java b/src/test/java/org/openecomp/sdc/utils/TestNotificationCallback.java
new file mode 100644 (file)
index 0000000..bef643a
--- /dev/null
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * sdc-distribution-client
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.utils;
+
+import org.openecomp.sdc.api.consumer.INotificationCallback;
+import org.openecomp.sdc.api.notification.INotificationData;
+
+public class TestNotificationCallback implements INotificationCallback{
+
+       @Override
+       public void activateCallback(INotificationData data) {
+               System.out.println("notification callback was called");
+               
+       }
+
+}
diff --git a/src/test/resources/heatExample.yaml b/src/test/resources/heatExample.yaml
new file mode 100644 (file)
index 0000000..85b4e7c
--- /dev/null
@@ -0,0 +1,52 @@
+heat_template_version: 2013-05-23
+
+description: Simple template to deploy a stack with two virtual machine instances
+
+parameters:
+  image_name_1:
+    type: string
+    label: Image Name
+    description: SCOIMAGE Specify an image name for instance1
+    default: cirros-0.3.1-x86_64
+  image_name_2:
+    type: string
+    label: Image Name
+    description: SCOIMAGE Specify an image name for instance2
+    default: cirros-0.3.1-x86_64
+  network_id:
+    type: string
+    label: Network ID
+    description: SCONETWORK Network to be used for the compute instance
+    hidden: true
+    constraints:
+      - length: { min: 6, max: 8 }
+        description: Password length must be between 6 and 8 characters.
+      - range: { min: 6, max: 8 }
+        description: Range description
+      - allowed_values:
+        - m1.small
+        - m1.medium
+        - m1.large
+        description: Allowed values description
+      - allowed_pattern: "[a-zA-Z0-9]+"
+        description: Password must consist of characters and numbers only.
+      - allowed_pattern: "[A-Z]+[a-zA-Z0-9]*"
+        description: Password must start with an uppercase character.
+      - custom_constraint: nova.keypair
+        description: Custom description
+
+resources:
+  my_instance1:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: image_name_1 }
+      flavor: m1.small
+      networks:
+        - network : { get_param : network_id }
+  my_instance2:
+    type: OS::Nova::Server
+    properties:
+      image: { get_param: image_name_2 }
+      flavor: m1.tiny
+      networks:
+        - network : { get_param : network_id }
\ No newline at end of file