diff options
author | Michael Lando <ml636r@att.com> | 2017-02-15 16:02:49 +0200 |
---|---|---|
committer | Michael Lando <ml636r@att.com> | 2017-02-15 16:03:20 +0200 |
commit | 4e33d89a0863f5f4ec95f537f5f60241e28132c3 (patch) | |
tree | b0f7bef94ecb2e99dfa608e52c007f8c6acc1471 | |
parent | 78744d32005cd31e7c4954bfcdf546802fbbc0f5 (diff) |
Initial OpenECOMP sdc-distribution-client commit
Change-Id: I6dd20cdaf36d22836db1e9b6956c90652b6a38d7
Signed-off-by: Michael Lando <ml636r@att.com>
58 files changed, 6491 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b6d5d3 --- /dev/null +++ b/.gitignore @@ -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 index 0000000..c8c7a5e --- /dev/null +++ b/.gitreview @@ -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 index 0000000..3d6f0e2 --- /dev/null +++ b/LICENSE.TXT @@ -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 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 *** + @@ -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&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 index 0000000..a620e49 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/IDistributionClient.java @@ -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 index 0000000..7c28271 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/IDistributionStatusMessageJsonBuilder.java @@ -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 index 0000000..f6ce949 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/asdc/RegistrationRequest.java @@ -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 index 0000000..c131a95 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/asdc/ServerListResponse.java @@ -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 index 0000000..67eebce --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/consumer/IConfiguration.java @@ -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 index 0000000..86251d1 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/consumer/IDistributionStatusMessage.java @@ -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 index 0000000..60666ed --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/consumer/INotificationCallback.java @@ -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 index 0000000..135fd45 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/notification/IArtifactInfo.java @@ -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 index 0000000..df314ea --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/notification/INotificationData.java @@ -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 index 0000000..5a29d4b --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/notification/IResourceInstance.java @@ -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 index 0000000..a769d71 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/notification/IVfModuleMetadata.java @@ -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 index 0000000..e101636 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/results/IDistributionClientDownloadResult.java @@ -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 index 0000000..b4086ac --- /dev/null +++ b/src/main/java/org/openecomp/sdc/api/results/IDistributionClientResult.java @@ -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 index 0000000..59a879c --- /dev/null +++ b/src/main/java/org/openecomp/sdc/http/AsdcConnectorClient.java @@ -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 index 0000000..2112f39 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/http/AsdcUrls.java @@ -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 index 0000000..a08416c --- /dev/null +++ b/src/main/java/org/openecomp/sdc/http/HttpAsdcClient.java @@ -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 index 0000000..9e48d5e --- /dev/null +++ b/src/main/java/org/openecomp/sdc/http/HttpAsdcResponse.java @@ -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 index 0000000..aa62bac --- /dev/null +++ b/src/main/java/org/openecomp/sdc/http/IHttpAsdcClient.java @@ -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 index 0000000..280d7da --- /dev/null +++ b/src/main/java/org/openecomp/sdc/http/TopicRegistrationResponse.java @@ -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 index 0000000..64ff9a8 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/ArtifactInfoImpl.java @@ -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 index 0000000..3b8f3bd --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/Configuration.java @@ -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 index 0000000..b69cb24 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/DistributionClientDownloadResultImpl.java @@ -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 index 0000000..467f9cb --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/DistributionClientFactory.java @@ -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 index 0000000..ce74b26 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/DistributionClientImpl.java @@ -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 index 0000000..a5af31a --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/DistributionClientResultImpl.java @@ -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 index 0000000..d570142 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/DistributionStatusMessageImpl.java @@ -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 index 0000000..9d97805 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/DistributionStatusMessageJsonBuilderFactory.java @@ -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 index 0000000..68d557c --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/JsonContainerResourceInstance.java @@ -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 index 0000000..d337650 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/NotificationConsumer.java @@ -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 index 0000000..7ad3987 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/NotificationDataImpl.java @@ -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 index 0000000..3932253 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/VfModuleMetadata.java @@ -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 index 0000000..d69451a --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/mock/DistributionClientDownloadResultStubImpl.java @@ -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 index 0000000..13d64a4 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/mock/DistributionClientResultStubImpl.java @@ -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 index 0000000..b8044cd --- /dev/null +++ b/src/main/java/org/openecomp/sdc/impl/mock/DistributionClientStubImpl.java @@ -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 index 0000000..ca5339f --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/ArtifactTypeEnum.java @@ -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 index 0000000..47333d5 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/DistributionActionResultEnum.java @@ -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 index 0000000..37b8ae3 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/DistributionClientConstants.java @@ -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 index 0000000..1d2d03c --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/DistributionStatusEnum.java @@ -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 index 0000000..9d786d0 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/GeneralUtils.java @@ -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 index 0000000..eca644a --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/Pair.java @@ -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 index 0000000..047ea86 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/Wrapper.java @@ -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 index 0000000..50feb6c --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/YamlToObjectConverter.java @@ -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 index 0000000..6cd2de0 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/heat/HeatConfiguration.java @@ -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 index 0000000..954152d --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/heat/HeatParameter.java @@ -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 index 0000000..b89ad48 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/heat/HeatParameterConstraint.java @@ -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 index 0000000..5aa4968 --- /dev/null +++ b/src/main/java/org/openecomp/sdc/utils/heat/HeatParser.java @@ -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 index 0000000..9e6461d --- /dev/null +++ b/src/test/java/org/openecomp/sdc/impl/DistributionClientTest.java @@ -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 index 0000000..3b5b1a1 --- /dev/null +++ b/src/test/java/org/openecomp/sdc/impl/HeatParserTest.java @@ -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 index 0000000..281a157 --- /dev/null +++ b/src/test/java/org/openecomp/sdc/impl/NotificationConsumerTest.java @@ -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 index 0000000..5a24849 --- /dev/null +++ b/src/test/java/org/openecomp/sdc/utils/ArtifactsUtils.java @@ -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 index 0000000..e4b0ca8 --- /dev/null +++ b/src/test/java/org/openecomp/sdc/utils/TestConfiguration.java @@ -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 index 0000000..bef643a --- /dev/null +++ b/src/test/java/org/openecomp/sdc/utils/TestNotificationCallback.java @@ -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 index 0000000..85b4e7c --- /dev/null +++ b/src/test/resources/heatExample.yaml @@ -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 |