aboutsummaryrefslogtreecommitdiffstats
path: root/appc-asdc-listener/appc-asdc-listener-bundle/src/main
diff options
context:
space:
mode:
authorPatrick Brady <pb071s@att.com>2017-02-15 23:11:26 -0800
committerPatrick Brady <pb071s@att.com>2017-02-15 23:13:06 -0800
commit1c192d2dd68724e292b6a30f463085a262e1e813 (patch)
treed0e2b3a396e169863cd0efaa835c8675e9d5aaac /appc-asdc-listener/appc-asdc-listener-bundle/src/main
parentc69ba05c7508aa7d7f675189a45c8c87569369ef (diff)
Moving all files to root directory
Change-Id: Ica5535fd6ec85f350fe1640b42137b49f83f10f0 Signed-off-by: Patrick Brady <pb071s@att.com>
Diffstat (limited to 'appc-asdc-listener/appc-asdc-listener-bundle/src/main')
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java121
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java182
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java131
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java227
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderOperations.java208
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderResponse.java42
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java122
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/tlv/sdc/security/Passwords.java167
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml40
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc-packages.yaml10
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc.yaml35
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/log4j.properties55
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/titan.properties26
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/scripts/startTest.sh109
-rw-r--r--appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/org/openecomp/appc/default.properties37
15 files changed, 1512 insertions, 0 deletions
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java
new file mode 100644
index 000000000..651ea282c
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.sdc.listener;
+
+import java.net.URI;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.openecomp.appc.adapter.dmaap.EventSender;
+
+import org.openecomp.sdc.api.IDistributionClient;
+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 com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+public class AsdcCallback implements INotificationCallback {
+
+ private final EELFLogger logger = EELFManager.getInstance().getLogger(AsdcCallback.class);
+
+ private URI storeUri;
+ private IDistributionClient client;
+
+ private EventSender eventSender = null;
+
+ private ThreadPoolExecutor executor;
+ private int threadCount = 10;
+
+ private AtomicBoolean isRunning = new AtomicBoolean(false);
+
+
+ public AsdcCallback(URI storeUri, IDistributionClient client) {
+ this.storeUri = storeUri;
+ this.client = client;
+
+ // Create the thread pool
+ executor = new ThreadPoolExecutor(threadCount, threadCount, 1, TimeUnit.SECONDS,
+ new ArrayBlockingQueue<Runnable>(threadCount * 2));
+
+ // Custom Named thread factory
+ BasicThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("Appc-Listener-%d").build();
+ executor.setThreadFactory(threadFactory);
+
+ isRunning.set(true);
+ }
+
+ @Override
+ public void activateCallback(INotificationData data) {
+ if (null == eventSender) {
+ try {
+ BundleContext bctx = FrameworkUtil.getBundle(EventSender.class).getBundleContext();
+ ServiceReference sref = bctx.getServiceReference(EventSender.class);
+ eventSender = (EventSender) bctx.getService(sref);
+ } catch (Throwable t) {
+ logger.error("AsdcCallback failed on initializing EventSender", t);
+ }
+ }
+
+ if (isRunning.get()) {
+ for (IResourceInstance resource : data.getResources()) {
+ for (IArtifactInfo artifact : resource.getArtifacts()) {
+ logger.info(Util.toAsdcStoreDocumentInput(data, resource, artifact, "abc"));
+ if (executor.getQueue().size() >= threadCount) {
+ // log warning about job backlog
+ }
+ executor.submit(new DownloadAndStoreOp(client, eventSender, data, resource, artifact, storeUri));
+ }
+ }
+ } else {
+ // TODO - return a failed result so asdc knows we are shut down
+ }
+ }
+
+ public void stop() {
+ stop(10);
+ }
+
+ public void stop(int waitSec) {
+ isRunning.set(false);
+ logger.info(String.format("Stopping the ASDC listener and waiting up to %ds for %d pending jobs", waitSec,
+ executor.getQueue().size()));
+ boolean cleanShutdown = false;
+ executor.shutdown();
+ try {
+ cleanShutdown = executor.awaitTermination(waitSec, TimeUnit.SECONDS);
+ executor.shutdownNow(); // In case of timeout
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ logger.info(String.format("Attempting to shutdown cleanly: %s", cleanShutdown ? "SUCCESS" : "FAILURE"));
+ logger.info("Shutdown complete.");
+ }
+
+}
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java
new file mode 100644
index 000000000..e73b90695
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.sdc.listener;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.openecomp.sdc.api.consumer.IConfiguration;
+import org.openecomp.sdc.utils.ArtifactTypeEnum;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class AsdcConfig implements IConfiguration {
+
+ private String host;
+ private String consumer;
+ private String consumerId;
+ private String env;
+ private String keystorePath;
+ private String keystorePass;
+ private int pollingInterval; // Time between listening sessions
+ private int pollingTimeout; // Time to listen for (dmaap timeout url param)/1000
+ private List<String> types = new ArrayList<>(1);
+ private String user;
+ private String pass;
+
+ private URI storeOp;
+
+ Properties props;
+
+ private final EELFLogger logger = EELFManager.getInstance().getLogger(AsdcConfig.class);
+
+ public AsdcConfig(Properties props) throws Exception {
+ this.props = props;
+ init();
+ }
+
+ private void init() throws Exception {
+ if (props != null) {
+ // Keystore for ca cert
+ keystorePath = props.getProperty("appc.asdc.keystore.path");
+ keystorePass = props.getProperty("appc.asdc.keystore.pass");
+
+ // ASDC host
+ host = props.getProperty("appc.asdc.host");
+ env = props.getProperty("appc.asdc.env");
+ user = props.getProperty("appc.asdc.user");
+ pass = props.getProperty("appc.asdc.pass");
+
+ // DMaaP properties
+ consumer = props.getProperty("appc.asdc.consumer");
+ consumerId = props.getProperty("appc.asdc.consumer.id");
+
+ pollingInterval = Integer.valueOf(props.getProperty("interval", "60"));
+
+ // Client uses cambriaClient-0.2.4 which throws non relevant (wrong)
+ // exceptions with times > 30s
+ pollingTimeout = Integer.valueOf(props.getProperty("timeout", "25"));
+
+ // Anything less than 60 and we risk 429 Too Many Requests
+ if (pollingInterval < 60) {
+ pollingInterval = 60;
+ }
+
+ if (pollingInterval > pollingInterval) {
+ logger.warn(String.format(
+ "Message acknowledgement may be delayed by %ds in the ADSC listener. [Listening Time: %s, Poll Period: %s]",
+ pollingInterval - pollingTimeout, pollingTimeout, pollingInterval));
+ }
+
+ logParams();
+
+ // Download type
+ types.add("APPC_CONFIG");
+ types.add("VF_LICENSE");
+
+ storeOp = new URI(props.getProperty("appc.asdc.provider.url"));
+ }
+ }
+
+ @Override
+ public boolean activateServerTLSAuth() {
+ return false;
+ }
+
+ @Override
+ public String getAsdcAddress() {
+ return host;
+ }
+
+ @Override
+ public String getConsumerGroup() {
+ return consumer;
+ }
+
+ @Override
+ public String getConsumerID() {
+ return consumerId;
+ }
+
+ @Override
+ public String getEnvironmentName() {
+ return env;
+ }
+
+ @Override
+ public String getKeyStorePassword() {
+ return keystorePass;
+ }
+
+ @Override
+ public String getKeyStorePath() {
+ return keystorePath;
+ }
+
+ @Override
+ public String getPassword() {
+ return pass;
+ }
+
+ @Override
+ public int getPollingInterval() {
+ return pollingInterval;
+ }
+
+ @Override
+ public int getPollingTimeout() {
+ return pollingTimeout;
+ }
+
+ @Override
+ public List<String> getRelevantArtifactTypes() {
+ return types;
+ }
+
+ @Override
+ public String getUser() {
+ return user;
+ }
+
+ public URI getStoreOpURI() {
+ return storeOp;
+ }
+
+ /**
+ * Logs the relevant parameters
+ */
+ public void logParams() {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("ASDC Host", getAsdcAddress());
+ params.put("ASDC Environment", getEnvironmentName());
+ params.put("Consumer Name", getConsumerGroup());
+ params.put("Consumer ID", getConsumerID());
+ params.put("Poll Active Wait", String.valueOf(getPollingInterval()));
+ params.put("Poll Timeout", String.valueOf(getPollingTimeout()));
+
+ logger.info(String.format("ASDC Params: %s", params));
+ }
+}
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java
new file mode 100644
index 000000000..2d6192749
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java
@@ -0,0 +1,131 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.sdc.listener;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.api.results.IDistributionClientResult;
+import org.openecomp.sdc.impl.DistributionClientFactory;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+
+public class AsdcListener {
+
+ /**
+ * The bundle context
+ */
+ private IDistributionClient client;
+ private AsdcCallback callback;
+ private AsdcConfig config;
+ private CountDownLatch latch;
+
+
+ private final EELFLogger logger = EELFManager.getInstance().getLogger(AsdcListener.class);
+
+ @SuppressWarnings("unused")
+ public void start() throws Exception {
+ logger.info("Starting bundle ASDC Listener");
+ Configuration configuration = ConfigurationFactory.getConfiguration();
+ Properties props = configuration.getProperties();
+
+ config = new AsdcConfig(props);
+
+ client = DistributionClientFactory.createDistributionClient();
+ callback = new AsdcCallback(config.getStoreOpURI(), client);
+
+ latch = new CountDownLatch(1);
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ initialRegistration(config);
+
+ IDistributionClientResult result = client.init(config, callback);
+
+ if (result.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS) {
+ client.start();
+ } else {
+ logger.error(String.format("Could not register ASDC client. %s - %s", result.getDistributionActionResult(),
+ result.getDistributionMessageResult()));
+ }
+
+ latch.countDown();
+ }
+ }).start();
+ }
+
+ @SuppressWarnings("unused")
+ public void stop() throws InterruptedException {
+ logger.info("Stopping ASDC Listener");
+ latch.await(10, TimeUnit.SECONDS);
+
+ if (callback != null) {
+ callback.stop();
+ }
+ if (client != null) {
+ client.stop();
+
+ }
+ logger.info("ASDC Listener stopped successfully");
+ }
+
+ private boolean initialRegistration(AsdcConfig config) {
+ try {
+ final String jsonTemplate = "{\"consumerName\": \"%s\",\"consumerSalt\": \"%s\",\"consumerPassword\":\"%s\"}";
+ String saltedPassStr = org.openecomp.tlv.sdc.security.Passwords.hashPassword(config.getPassword());
+ if (saltedPassStr == null || !saltedPassStr.contains(":")) {
+ return false;
+ }
+
+ String[] saltedPass = saltedPassStr.split(":");
+ String json = String.format(jsonTemplate, config.getUser(), saltedPass[0], saltedPass[1]);
+
+ Map<String, String> headers = new HashMap<>();
+ // TODO - Replace the header below to sdc's requirements. What should the new value be
+ headers.put("HTTP_CSP_ID", "test");
+
+ // TODO - How to format the url. Always same endpoint or ports?
+ String host = config.getAsdcAddress();
+ URL url = new URL(
+ String.format("http%s://%s/sdc2/rest/v1/consumers", host.contains("443") ? "s" : "", host));
+
+ logger.info(String.format("Attempting to register user %s on %s with salted pass of %s", config.getUser(),
+ url, saltedPass[1]));
+
+ ProviderResponse result = ProviderOperations.post(url, json, headers);
+ return result.getStatus() == 200;
+ } catch (Exception e) {
+ logger.error("Error performing initial registration with ASDC server. User may not be able to connect", e);
+ return false;
+ }
+ }
+}
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java
new file mode 100644
index 000000000..fcc5e7dda
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java
@@ -0,0 +1,227 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.sdc.listener;
+
+import org.openecomp.appc.adapter.dmaap.EventSender;
+import org.openecomp.appc.adapter.dmaap.DmaapDestination;
+import org.openecomp.appc.adapter.dmaap.event.EventHeader;
+import org.openecomp.appc.adapter.dmaap.event.EventMessage;
+import org.openecomp.appc.adapter.dmaap.event.EventStatus;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.licmgr.Constants;
+import org.openecomp.appc.licmgr.LicenseManager;
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.api.notification.IArtifactInfo;
+import org.openecomp.sdc.api.notification.INotificationData;
+import org.openecomp.sdc.api.notification.IResourceInstance;
+import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
+import org.openecomp.sdc.utils.DistributionActionResultEnum;
+import org.openecomp.sdc.utils.DistributionStatusEnum;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+import static org.openecomp.appc.licmgr.Constants.ASDC_ARTIFACTS_FIELDS.*;
+
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@SuppressWarnings("JavaDoc")
+public class DownloadAndStoreOp implements Runnable {
+
+ public static final String PAYLOAD_CHARSET = "UTF-8";
+
+ private static final String DATE_FORMAT = "yyyy/MM/dd HH:mm:ss";
+
+ private final EELFLogger logger = EELFManager.getInstance().getLogger(DownloadAndStoreOp.class);
+
+ private IDistributionClient client;
+ private EventSender eventSender;
+
+ private INotificationData notification;
+ private IResourceInstance resource;
+ private IArtifactInfo artifact;
+
+ private URI storeUri;
+
+ public DownloadAndStoreOp(IDistributionClient client, EventSender eventSender, INotificationData notification, IResourceInstance resource,
+ IArtifactInfo artifact, URI storeUri) {
+ this.client = client;
+ this.eventSender = eventSender;
+ this.notification = notification;
+ this.resource = resource;
+ this.artifact = artifact;
+ this.storeUri = storeUri;
+ }
+
+ @Override
+ public void run() {
+ logger.info(String.format("Attempting to download artifact %s", artifact));
+ // Download artifact
+ IDistributionClientDownloadResult download = client.download(artifact);
+ logger.info(String.format("Download of artifact %s completed with status %s", artifact.getArtifactUUID(), download));
+
+ // Notify of download status
+ if (download.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
+ client.sendDownloadStatus(Util.buildDistributionStatusMessage(client, notification, artifact,
+ DistributionStatusEnum.DOWNLOAD_ERROR), download.getDistributionMessageResult());
+ sendDCAEEvent(notification.getDistributionID(), notification.getServiceName(), notification.getServiceVersion(), "Download is failed.");
+ return;
+ }
+
+ client.sendDownloadStatus(Util.buildDistributionStatusMessage(client, notification, artifact, DistributionStatusEnum.DOWNLOAD_OK));
+
+ String data = null;
+ try {
+ if (download.getArtifactPayload() != null) {
+ data = new String(download.getArtifactPayload(), PAYLOAD_CHARSET);
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+
+ boolean providerSuccess = false;
+ String providerReason = "Unknown Error";
+ // Send data to provider
+ if (data != null && artifact != null) {
+ switch(artifact.getArtifactType()) {
+ case "APPC_CONFIG":
+ String postData = Util.toAsdcStoreDocumentInput(notification, resource, artifact, data);
+ try {
+ ProviderResponse result = ProviderOperations.post(storeUri.toURL(), postData, null);
+ if (result.getStatus() == 200) {
+ providerSuccess = Util.parseResponse(result.getBody());
+ providerReason = "Success";
+ }
+ } catch (MalformedURLException | APPCException e) {
+ providerReason = e.getMessage();
+ e.printStackTrace();
+ }
+ break;
+
+ case "VF_LICENSE":
+ BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ ServiceReference srefLicenseService = bctx.getServiceReference(LicenseManager.class);
+ LicenseManager licenseService = (LicenseManager) bctx.getService(srefLicenseService);
+
+ Map<String, String> artifactPayload = prepareArtifactPayloadParamsMap(data);
+
+ String vnfType = artifactPayload.get(RESOURCE_NAME.name());
+ String version = artifactPayload.get(RESOURCE_VERSION.name());
+ String packageArtifactID = artifactPayload.get(ARTIFACT_UUID.name());
+ String packageArtifactVersion = artifactPayload.get(INTERNAL_VERSION.name());
+
+ try {
+ if (null == vnfType || null == version || null == packageArtifactID || null == packageArtifactVersion || vnfType.isEmpty() || version.isEmpty() || packageArtifactID.isEmpty() || packageArtifactVersion.isEmpty()) {
+ throw new APPCException(String.format("Missing information in ASDC request. Details: resource_type='%s', resource_version='%s', artifactID='%s', artifactVersion='%s'", vnfType, version, packageArtifactID, packageArtifactVersion));
+ }
+
+ Map<String, String> existingArtifactPayload = licenseService.retrieveLicenseModelData(vnfType, version);
+
+ if (existingArtifactPayload.isEmpty()) { // new resource
+ licenseService.storeArtifactPayload(artifactPayload);
+ } else { // duplicate
+ logger.warn(String.format("Artifact of type '%s' already deployed for resource_type='%s' and resource_version='%s'", Constants.VF_LICENSE, vnfType, version));
+ }
+
+ providerSuccess = true;
+
+ } catch (Exception e) {
+ providerSuccess = false;
+ providerReason = e.getMessage();
+ }
+ break;
+
+ default:
+ throw new UnsupportedOperationException("Artifact type " + artifact.getArtifactType() + " is not supported");
+ }
+
+ }
+
+ // Notify of provider's response
+ if (providerSuccess) {
+ client.sendDeploymentStatus(
+ Util.buildDistributionStatusMessage(client, notification, artifact, DistributionStatusEnum.DEPLOY_OK));
+ } else {
+ client.sendDeploymentStatus(Util.buildDistributionStatusMessage(client, notification, artifact,
+ DistributionStatusEnum.DEPLOY_ERROR), providerReason);
+ sendDCAEEvent(notification.getDistributionID(), notification.getServiceName(), notification.getServiceVersion(), providerReason);
+ }
+
+ }
+
+ /**
+ * Prepares Artifact Payload params map
+ * @param data
+ * @return Map<String,String>
+ */
+ private Map<String, String> prepareArtifactPayloadParamsMap(String data) {
+ Map<String, String> paramsMap = new HashMap<>();
+
+ paramsMap.put(SERVICE_UUID.name(), this.notification.getServiceUUID());
+ paramsMap.put(DISTRIBUTION_ID.name(), this.notification.getDistributionID());
+ paramsMap.put(SERVICE_NAME.name(), this.notification.getServiceName());
+ paramsMap.put(SERVICE_DESCRIPTION.name(), this.notification.getServiceDescription());
+ paramsMap.put(RESOURCE_UUID.name(), this.resource.getResourceUUID());
+ paramsMap.put(RESOURCE_INSTANCE_NAME.name(), this.resource.getResourceInstanceName());
+ paramsMap.put(RESOURCE_NAME.name(), this.resource.getResourceName());
+ paramsMap.put(RESOURCE_VERSION.name(), this.resource.getResourceVersion());
+ paramsMap.put(RESOURCE_TYPE.name(), this.resource.getResourceType());
+ paramsMap.put(ARTIFACT_UUID.name(), this.artifact.getArtifactUUID());
+ paramsMap.put(ARTIFACT_TYPE.name(), this.artifact.getArtifactType());
+ paramsMap.put(ARTIFACT_VERSION.name(), this.artifact.getArtifactVersion());
+ paramsMap.put(ARTIFACT_DESCRIPTION.name(), this.artifact.getArtifactDescription());
+ paramsMap.put(CREATION_DATE.name(), getCurrentDateTime());
+ paramsMap.put(ARTIFACT_NAME.name(), this.artifact.getArtifactName());
+ paramsMap.put(ARTIFACT_CONTENT.name(), data);
+
+ return paramsMap;
+ }
+
+
+ private String getCurrentDateTime() {
+ DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+ Date date = new Date();
+ return dateFormat.format(date);
+ }
+
+ private void sendDCAEEvent(String distributionID, String serviceName, String serviceVersion, String errorMessage) {
+ if (null == eventSender) return;
+ String errorDescription = String.format("ASDC distribution of service '%s', version '%s' is failed with reason: '%s'",
+ serviceName, serviceVersion, errorMessage);
+
+ EventMessage eventMessage = new EventMessage(
+ new EventHeader((new java.util.Date()).toString(), serviceVersion, distributionID),
+ new EventStatus(401, errorDescription));
+
+ eventSender.sendEvent(DmaapDestination.DCAE, eventMessage);
+ }
+
+}
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderOperations.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderOperations.java
new file mode 100644
index 000000000..5a805205a
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderOperations.java
@@ -0,0 +1,208 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.sdc.listener;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.Socket;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.HTTP;
+import org.openecomp.appc.exceptions.APPCException;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class ProviderOperations {
+
+ private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class);
+
+ private static String basic_auth;
+
+ public static ProviderResponse post(URL url, String json, Map<String, String> adtl_headers) throws APPCException {
+ if (json == null) {
+ throw new APPCException("Provided message was null");
+ }
+
+ HttpPost post = null;
+ try {
+ post = new HttpPost(url.toExternalForm());
+ post.setHeader("Content-Type", "application/json");
+ post.setHeader("Accept", "application/json");
+
+ // Set Auth
+ if (basic_auth != null) {
+ post.setHeader("Authorization", "Basic " + basic_auth);
+ }
+
+ if (adtl_headers != null) {
+ for (Entry<String, String> header : adtl_headers.entrySet()) {
+ post.setHeader(header.getKey(), header.getValue());
+ }
+ }
+
+ StringEntity entity = new StringEntity(json);
+ entity.setContentType("application/json");
+ post.setEntity(new StringEntity(json));
+ } catch (UnsupportedEncodingException e) {
+ throw new APPCException(e);
+ }
+
+ HttpClient client = getHttpClient(url);
+
+ int httpCode = 0;
+ String respBody = null;
+ try {
+ HttpResponse response = client.execute(post);
+ httpCode = response.getStatusLine().getStatusCode();
+ respBody = IOUtils.toString(response.getEntity().getContent());
+ return new ProviderResponse(httpCode, respBody);
+ } catch (IOException e) {
+ throw new APPCException(e);
+ }
+ }
+
+ /**
+ * Sets the basic authentication header for the given user and password. If either entry is null then set basic auth
+ * to null
+ *
+ * @param user
+ * The user with optional domain name (for AAF)
+ * @param password
+ * The password for the user
+ * @return The new value of the basic auth string that will be used in the request headers
+ */
+ public static String setAuthentication(String user, String password) {
+ if (user != null && password != null) {
+ String authStr = user + ":" + password;
+ basic_auth = new String(Base64.encodeBase64(authStr.getBytes()));
+ } else {
+ basic_auth = null;
+ }
+ return basic_auth;
+ }
+
+ @SuppressWarnings("deprecation")
+ private static HttpClient getHttpClient(URL url) throws APPCException {
+ HttpClient client;
+ if (url.getProtocol().equals("https")) {
+ try {
+ KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ trustStore.load(null, null);
+ MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
+ sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+
+ HttpParams params = new BasicHttpParams();
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+ HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
+
+ SchemeRegistry registry = new SchemeRegistry();
+ registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ registry.register(new Scheme("https", sf, 443));
+ registry.register(new Scheme("https", sf, 8443));
+ registry.register(new Scheme("http", sf, 8181));
+
+ ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
+ client = new DefaultHttpClient(ccm, params);
+ } catch (Exception e) {
+ client = new DefaultHttpClient();
+ }
+ } else if (url.getProtocol().equals("http")) {
+ client = new DefaultHttpClient();
+ } else {
+ throw new APPCException(
+ "The provider.topology.url property is invalid. The url did not start with http[s]");
+ }
+ return client;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static class MySSLSocketFactory extends SSLSocketFactory {
+ private SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
+
+ public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException,
+ KeyStoreException, UnrecoverableKeyException {
+ super(truststore);
+
+ TrustManager tm = new X509TrustManager() {
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ };
+
+ sslContext.init(null, new TrustManager[] {
+ tm
+ }, null);
+ }
+
+ @Override
+ public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
+ throws IOException, UnknownHostException {
+ return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
+ }
+
+ @Override
+ public Socket createSocket() throws IOException {
+ return sslContext.getSocketFactory().createSocket();
+ }
+ }
+
+}
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderResponse.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderResponse.java
new file mode 100644
index 000000000..7e5ea1228
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderResponse.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.sdc.listener;
+
+public class ProviderResponse {
+
+ private int status;
+ private String body;
+
+ public ProviderResponse(int status, String body) {
+ this.status = status;
+ this.body = body;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+}
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java
new file mode 100644
index 000000000..46efba438
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java
@@ -0,0 +1,122 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.sdc.listener;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.sdc.api.IDistributionClient;
+import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
+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.utils.DistributionStatusEnum;
+
+public class Util {
+
+ // TODO - Use the yang builder instead
+ public static String toAsdcStoreDocumentInput(INotificationData notification, IResourceInstance resource,
+ IArtifactInfo artifact, String data) {
+ JSONObject json = new JSONObject();
+
+ JSONObject requestInfo = new JSONObject();
+ requestInfo.put("request-id", notification.getServiceUUID());
+ requestInfo.put("request-action", "StoreAsdcDocumentRequest");
+ requestInfo.put("source", "ASDC");
+
+ JSONObject docParams = new JSONObject();
+ docParams.put("service-uuid", notification.getServiceUUID());
+ docParams.put("distribution-id", notification.getDistributionID());
+ docParams.put("service-name", notification.getServiceName());
+ docParams.put("service-description", notification.getServiceDescription());
+ docParams.put("service-artifacts", "[]");
+ docParams.put("resource-uuid", resource.getResourceUUID());
+ docParams.put("resource-instance-name", resource.getResourceInstanceName());
+ docParams.put("resource-name", resource.getResourceName());
+ docParams.put("resource-version", resource.getResourceVersion());
+ docParams.put("resource-type", resource.getResourceType());
+ docParams.put("artifact-uuid", artifact.getArtifactUUID());
+ docParams.put("artifact-name", artifact.getArtifactName());
+ docParams.put("artifact-type", artifact.getArtifactType());
+ docParams.put("artifact-version", artifact.getArtifactVersion());
+ docParams.put("artifact-description", artifact.getArtifactDescription());
+ docParams.put("artifact-contents", data);
+
+ json.put("request-information", requestInfo);
+ json.put("document-parameters", docParams);
+
+ return String.format("{\"input\": %s}", json.toString());
+ }
+
+ public static boolean parseResponse(String input) throws APPCException {
+ JSONObject result, output, response;
+ try {
+ result = new JSONObject(input);
+ output = result.getJSONObject("output");
+ response = output.getJSONObject("config-document-response");
+ String id = response.getString("request-id");
+ String status = response.getString("status");
+ if (status.equals(DistributionStatusEnum.DEPLOY_OK.toString())) {
+ return true;
+ } else {
+ String error = response.optString("error-reason");
+ String msg = error.isEmpty() ? "No Reason Provided" : error;
+ throw new APPCException(msg);
+ }
+ } catch (JSONException jse) {
+ throw new APPCException("Did not get valid json from provider.", jse);
+ }
+ }
+
+ public static IDistributionStatusMessage buildDistributionStatusMessage(final IDistributionClient client,
+ final INotificationData data, final IArtifactInfo relevantArtifact, final DistributionStatusEnum status) {
+ IDistributionStatusMessage statusMessage = new IDistributionStatusMessage() {
+
+ @Override
+ public long getTimestamp() {
+ long currentTimeMillis = System.currentTimeMillis();
+ return currentTimeMillis;
+ }
+
+ @Override
+ public DistributionStatusEnum getStatus() {
+ return status;
+ }
+
+ @Override
+ public String getDistributionID() {
+ return data.getDistributionID();
+ }
+
+ @Override
+ public String getConsumerID() {
+ return client.getConfiguration().getConsumerID();
+ }
+
+ @Override
+ public String getArtifactURL() {
+ return relevantArtifact.getArtifactURL();
+ }
+ };
+ return statusMessage;
+ }
+}
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/tlv/sdc/security/Passwords.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/tlv/sdc/security/Passwords.java
new file mode 100644
index 000000000..39d809352
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/tlv/sdc/security/Passwords.java
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.tlv.sdc.security;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * A copy from the org.openecomp.sdc:security-utils artifact that works with java 7.
+ */
+public class Passwords {
+
+ private static final Random RANDOM = new SecureRandom();
+ private static final int SALT = 0;
+ private static final int HASH = 1;
+ private static final String HASH_ALGORITHM = "SHA-256";
+
+ /**
+ * static utility class
+ */
+ private Passwords() {
+ }
+
+ /**
+ * the method calculates a hash with a generated salt for the given password
+ *
+ * @param password
+ * @return a "salt:hash" value
+ */
+ public static String hashPassword(String password) {
+ byte[] salt = getNextSalt();
+ byte byteData[] = hash(salt, password.getBytes());
+ if (byteData != null) {
+ return toHex(salt) + ":" + toHex(byteData);
+ }
+ return null;
+
+ }
+
+ /**
+ * the method checks if the given password matches the calculated hash
+ *
+ * @param password
+ * @param expectedHash
+ * @return
+ */
+ public static boolean isExpectedPassword(String password, String expectedHash) {
+ String[] params = expectedHash.split(":");
+ return isExpectedPassword(password, params[SALT], params[HASH]);
+ }
+
+ /**
+ * the method checks if the given password matches the calculated hash
+ *
+ * @param password
+ * @param salt
+ * @param hash
+ * the hash generated using the salt
+ * @return true if the password matched the hash
+ */
+ public static boolean isExpectedPassword(String password, String salt, String hash) {
+ byte[] saltBytes = fromHex(salt);
+ byte[] hashBytes = fromHex(hash);
+
+ byte byteData[] = hash(saltBytes, password.getBytes());
+ if (byteData != null) {
+ return Arrays.equals(byteData, hashBytes);
+ }
+ return false;
+ }
+
+ public static void main(String[] args) {
+ if (args.length > 1 || args.length > 0) {
+ System.out.println("[" + hashPassword(args[0]) + "]");
+ } else {
+ System.out.println("no passward passed.");
+ }
+
+ }
+
+ /**
+ * Returns a random salt to be used to hash a password.
+ *
+ * @return a 16 bytes random salt
+ */
+ private static byte[] getNextSalt() {
+ byte[] salt = new byte[16];
+ RANDOM.nextBytes(salt);
+ return salt;
+ }
+
+ /**
+ * hase's the salt and value using the chosen algorithm
+ *
+ * @param salt
+ * @param password
+ * @return an array of bytes resulting from the hash
+ */
+ private static byte[] hash(byte[] salt, byte[] password) {
+ MessageDigest md;
+ byte[] byteData = null;
+ try {
+ md = MessageDigest.getInstance(HASH_ALGORITHM);
+ md.update(salt);
+ md.update(password);
+ byteData = md.digest();
+ } catch (NoSuchAlgorithmException e) {
+ System.out.println("in vlide algorithem name");
+ }
+ return byteData;
+ }
+
+ /**
+ * Converts a string of hexadecimal characters into a byte array.
+ *
+ * @param hex
+ * the hex string
+ * @return the hex string decoded into a byte array
+ */
+ private static byte[] fromHex(String hex) {
+ byte[] binary = new byte[hex.length() / 2];
+ for (int i = 0; i < binary.length; i++) {
+ binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
+ }
+ return binary;
+ }
+
+ /**
+ * Converts a byte array into a hexadecimal string.
+ *
+ * @param array
+ * the byte array to convert
+ * @return a length*2 character string encoding the byte array
+ */
+ private static String toHex(byte[] array) {
+ BigInteger bi = new BigInteger(1, array);
+ String hex = bi.toString(16);
+ int paddingLength = (array.length * 2) - hex.length();
+ if (paddingLength > 0)
+ return String.format("%0" + paddingLength + "d", 0) + hex;
+ else
+ return hex;
+ }
+}
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 000000000..08b864c63
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights
+ reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+ -->
+
+<!--
+ Starter Blueprint Camel Definition appc-aai-adapter-blueprint
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+
+
+ <bean id="AsdcListener" class="org.openecomp.appc.sdc.listener.AsdcListener" init-method="start" destroy-method="stop" scope="singleton" activation="eager">
+ </bean>
+
+ <!--
+ <bean id="AsdcListenerBean" class="org.openecomp.appc.sdc.listener.impl.AsdcListenerBean" init-method="start" destroy-method="stop" activation="eager" scope="singleton" />
+ <service id="AsdcListener" interface="org.openecomp.appc.sdc.listener.AsdcListener" ref="AsdcListenerBean"/>
+ -->
+
+</blueprint>
+
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc-packages.yaml b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc-packages.yaml
new file mode 100644
index 000000000..8385dc988
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc-packages.yaml
@@ -0,0 +1,10 @@
+packages:
+ - org.openecomp.tlv.sdc.ci.tests.execute.general
+ - org.openecomp.tlv.sdc.ci.tests.execute.user
+ - org.openecomp.tlv.sdc.ci.tests.execute.property
+ - org.openecomp.tlv.sdc.ci.tests.execute.lifecycle
+ - org.openecomp.tlv.sdc.ci.tests.execute.resource
+ - org.openecomp.tlv.sdc.ci.tests.execute.service
+ - org.openecomp.tlv.sdc.ci.tests.execute.artifacts
+ - org.openecomp.tlv.sdc.ci.tests.execute.imports
+ - org.openecomp.tlv.sdc.ci.tests.execute.category \ No newline at end of file
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc.yaml b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc.yaml
new file mode 100644
index 000000000..7e612fe9b
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc.yaml
@@ -0,0 +1,35 @@
+outputFolder: target
+reportName: index.html
+catalogBeHost: localhost
+catalogFeHost: localhost
+esHost: localhost
+disributionClientHost: localhost
+catalogFePort: 8181
+catalogBePort: 8080
+disributionClientPort: 8181
+esPort: 9200
+neoHost: localhost
+neoPort: 7474
+neoDBusername: neo4j
+neoDBpassword: 123456
+
+resourceConfigDir: src/test/resources/CI/tests
+componentsConfigDir: src/test/resources/CI/components
+importResourceConfigDir: src/test/resources/CI/importResource
+importResourceTestsConfigDir: src/test/resources/CI/importResourceTests
+errorConfigurationFile: ../catalog-be/src/main/resources/config/error-configuration.yaml
+
+titanPropertiesFile: src/main/resources/ci/conf/titan.properties
+
+stopOnClassFailure: false
+
+#List of non-abstract resources to keep during titan cleanup between tests
+#Only 1.0 version will be kept
+resourcesNotToDelete:
+ - tosca.nodes.Compute
+ - tosca.nodes.Database
+ - tosca.nodes.ObjectStorage
+ - tosca.nodes.BlockStorage
+ - tosca.nodes.LoadBalancer
+ - org.openecomp.d2.resource.cp.Port
+ - org.openecomp.d2.resource.vl.Network \ No newline at end of file
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/log4j.properties b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/log4j.properties
new file mode 100644
index 000000000..4b99de0c9
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/log4j.properties
@@ -0,0 +1,55 @@
+###
+# ============LICENSE_START=======================================================
+# openECOMP : APP-C
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+# reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+# Define the root logger with appender file
+log4j.rootLogger = DEBUG, FILE, stdout
+
+# Define the file appender
+log4j.appender.FILE=org.apache.log4j.RollingFileAppender
+log4j.appender.FILE.File=${targetlog}logs/ci-log.out
+
+# Define the layout for file appender
+log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.FILE.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p [%10c] : %m%n
+
+# Set the maximum file size before rollover
+log4j.appender.FILE.maxFileSize=5MB
+
+# Set the the backup index
+log4j.appender.FILE.maxBackupIndex=10
+
+
+#############################################################
+
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p %10c:%L - %m%n
+
+log4j.logger.org.apache.cassandra.service.StorageProxy=DEBUG
+log4j.logger.com.thinkaurelius.titan.diskstorage.cassandra.CassandraTransaction=INFO, FILE, stdout
+
+log4j.logger.org.openecomp.tlv.sdc.ci.tests.utils=TRACE, FILE, stdout
+log4j.additivity.org.openecomp.tlv.sdc.ci.tests.utils=false
+
+
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/titan.properties b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/titan.properties
new file mode 100644
index 000000000..2aa4b0189
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/titan.properties
@@ -0,0 +1,26 @@
+###
+# ============LICENSE_START=======================================================
+# openECOMP : APP-C
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+# reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+storage.backend=cassandra
+storage.hostname=locahost
+storage.port=9160
+
+cache.db-cache = false
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/scripts/startTest.sh b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/scripts/startTest.sh
new file mode 100644
index 000000000..321476e90
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/scripts/startTest.sh
@@ -0,0 +1,109 @@
+###
+# ============LICENSE_START=======================================================
+# openECOMP : APP-C
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+# reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+#!/bin/bash
+
+function usage {
+ echo "Usage: $0 <jar file>"
+}
+
+function exitOnError() {
+ if [ $1 -ne 0 ]
+ then
+ echo "Failed running task $2"
+ exit 2
+ fi
+}
+
+if [ $# -lt 1 ]
+then
+ usage
+ exit 2
+fi
+
+CURRENT_DIR=`pwd`
+BASEDIR=$(dirname $0)
+
+if [ ${BASEDIR:0:1} = "/" ]
+then
+ FULL_PATH=$BASEDIR
+else
+ FULL_PATH=$CURRENT_DIR/$BASEDIR
+fi
+
+LOGS_PROP_FILE=file:${FULL_PATH}/conf/log4j.properties
+#############################################
+TARGET_DIR=${FULL_PATH}/target
+CONF_FILE=${FULL_PATH}/conf/attsdc.yaml
+DEBUG=true
+#MainClass=org.openecomp.tlv.sdc.ci.tests.run.StartTest
+MainClass=org.openecomp.test.ClientTest
+
+JAR_FILE=$1
+
+#TARGET_DIR=`echo ${TARGET_DIR} | sed 's/\//\//g'`
+#echo $TARGET_DIR
+
+TESTS_DIR=/opt/app/sdc/ci/resources/tests
+COMPONENTS_DIR=/opt/app/sdc/ci/resources/components
+
+#sed -i 's#\(outputFolder:\).*#\1 '${TARGET_DIR}'#g' $CONF_FILE
+#sed -i 's#\(resourceConfigDir:\).*#\1 '${TESTS_DIR}'#g' $CONF_FILE
+#sed -i 's#\(componentsConfigDir:\).*#\1 '${COMPONENTS_DIR}'#g' $CONF_FILE
+TARGET_LOG_DIR="${TARGET_DIR}/"
+
+mkdir -p ${TARGET_DIR}
+if [ -d ${TARGET_DIR} ]
+then
+ rm -rf ${TARGET_DIR}/*
+ exitOnError $? "Failed_to_delete_target_dir"
+fi
+
+debug_port=8800
+#JAVA_OPTION="-javaagent:/var/tmp/jacoco/lib/jacocoagent.jar=destfile=jacoco-it.exec"
+JAVA_OPTION=""
+case "$2" in
+ -debug) echo "Debug mode, Listen on port $debug_port"; JAVA_OPTION="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=${debug_port}" ;;
+ "") echo "Standard mode";;
+ *) echo "USAGE: startTest.sh [-debug]";;
+esac
+
+cmd="java $JAVA_OPTION -DdisplayException=true -Dtargetlog=${TARGET_LOG_DIR} -Dconfig.resource=${CONF_FILE} -Ddebug=${DEBUG} -Dlog4j.configuration=${LOGS_PROP_FILE} -cp $JAR_FILE ${MainClass}"
+
+#echo $cmd
+#console=`$cmd`
+
+if [ $DEBUG == "true" ]
+then
+ $cmd
+else
+ $cmd >> /dev/null
+fi
+status=`echo $?`
+
+
+
+echo "##################################################"
+echo "################# status is ${status} #################"
+echo "##################################################"
+
+exit $status
+
diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/org/openecomp/appc/default.properties b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/org/openecomp/appc/default.properties
new file mode 100644
index 000000000..5742b8945
--- /dev/null
+++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/org/openecomp/appc/default.properties
@@ -0,0 +1,37 @@
+###
+# ============LICENSE_START=======================================================
+# openECOMP : APP-C
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights
+# reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+###
+
+org.openecomp.appc.bootstrap.file=appc.properties
+org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+
+# These ASDC properties were provided by the ASDC Op-So team
+appc.asdc.keystore.path=etc/asdc-client.jks
+appc.asdc.keystore.pass=Aa123456
+
+appc.asdc.host=192.168.1.2:8443
+appc.asdc.env=TEST
+appc.asdc.user=appc
+appc.asdc.pass=appc
+
+appc.asdc.consumer=TEST
+appc.asdc.consumer.id=TEST
+appc.asdc.provider.url=http://localhost:8181/restconf/operations/AsdcMessage:configuration-document-request
+