<module>appc-metric</module>
                 <module>appc-dg</module>
                 <module>appc-dg-util</module>
+                <module>services</module>
             </modules>
         </profile>
     </profiles>
 
--- /dev/null
+/target-ide/
 
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+  Copyright (C) 2017 Amdocs
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.appc.parent</groupId>
+        <artifactId>binding-parent</artifactId>
+        <version>2.6.2</version>
+                <relativePath />
+    </parent>
+        <groupId>org.onap.appc.services.dmaap</groupId>
+    <artifactId>appc-dmaap-adapter-bundle</artifactId>
+    <packaging>jar</packaging>
+    <name>DMaaP Adapter - bundle</name>
+
+    <dependencies>
+       <dependency>
+           <groupId>org.apache.httpcomponents</groupId>
+           <artifactId>httpclient</artifactId>
+       </dependency>
+       <dependency>
+            <groupId>org.onap.appc</groupId>
+            <artifactId>appc-common-bundle</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.appc.services.dmaap</groupId>
+            <artifactId>appc-message-adapter-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>${logback.version}</version>
+        </dependency>
+       <dependency>
+            <groupId>com.att.eelf</groupId>
+            <artifactId>eelf-core</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            </dependency>
+
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+            </dependency>
+        <dependency>
+            <groupId>org.objenesis</groupId>
+            <artifactId>objenesis</artifactId>
+            <version>2.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            </dependency>-->
+        <dependency>
+            <groupId>org.onap.ccsdk.sli.core</groupId>
+            <artifactId>sli-common</artifactId>
+            <scope>compile</scope>
+            <!-- Added exclusion to prevent missing dependency issue on dblib -->
+            <exclusions>
+                <exclusion>
+                    <groupId>org.onap.ccsdk.sli.core</groupId>
+                    <artifactId>dblib-provider</artifactId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>slf4j-simple</artifactId>
+                    <groupId>org.slf4j</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onap.ccsdk.sli.core</groupId>
+            <artifactId>sli-provider</artifactId>
+            <scope>compile</scope>
+            <!-- Added exclusion to prevent missing dependency issue on dblib -->
+            <exclusions>
+                <exclusion>
+                    <groupId>org.onap.ccsdk.sli.core</groupId>
+                    <artifactId>dblib-provider</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>            
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+        </dependency>
+    </dependencies>
+
+    <version>1.7.0-SNAPSHOT</version>
+</project>
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+
+
+/**
+ * This activator is used to initialize and terminate the connection pool to one or more providers.
+ * <p>
+ * The CDP abstraction layer supports multiple types of providers, with each provider supporting multiple tenants. The
+ * "connection" to a specific tenant on a specific provider is represented by a "context" object. These context objects
+ * are authenticated to a specific tenant on the provider, but can be reused from one request to another. Contexts are
+ * slow to set up and are resource intensive, so they are cached. However, the contexts for a specific tenant on a
+ * specific provider must be cached separately.
+ * </p>
+ * <p>
+ * Activation of the bundle creates an empty cache which is organized first by provider type, then by tenant name, with
+ * the contents being an empty pool of contexts for that provider/tenant combination. The pool is created on first use,
+ * and retained for as long as the bundle is active.
+ * </p>
+ * <p>
+ * When the bundle is deactivated, the cache is torn down with all contexts being closed.
+ * </p>
+ */
+public class AppcDmaapAdapterActivator implements BundleActivator {
+
+    /**
+     * The logger to be used
+     */
+    private static final EELFLogger LOG = EELFManager.getInstance().getLogger(AppcDmaapAdapterActivator.class);
+
+    /**
+     * Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start
+     * this bundle. This method can be used to register services or to allocate any resources that this bundle needs.
+     * <p>
+     * This method must complete and return to its caller in a timely manner.
+     * </p>
+     *
+     * @param bundleContext
+     *            The execution context of the bundle being started.
+     * @throws java.lang.Exception
+     *             If this method throws an exception, this bundle is marked as stopped and the Framework will remove
+     *             this bundle's listeners, unregister all services registered by this bundle, and release all services
+     *             used by this bundle.
+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void start(final BundleContext bundleContext) throws Exception {
+        LOG.info("Starting Bundle " + getName());
+    }
+
+    /**
+     * Called when this bundle is stopped so the Framework can perform the bundle-specific activities necessary to stop
+     * the bundle. In general, this method should undo the work that the BundleActivator.start method started. There
+     * should be no active threads that were started by this bundle when this bundle returns. A stopped bundle must not
+     * call any Framework objects.
+     * <p>
+     * This method must complete and return to its caller in a timely manner.
+     * </p>
+     *
+     * @param ctx
+     *            The execution context of the bundle being stopped.
+     * @throws java.lang.Exception
+     *             If this method throws an exception, the bundle is still marked as stopped, and the Framework will
+     *             remove the bundle's listeners, unregister all services registered by the bundle, and release all
+     *             services used by the bundle. *
+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void stop(BundleContext ctx) throws Exception {
+        LOG.info("Stopped Bundle " + getName());
+    }
+
+    public String getName() {
+        return "DMaaP Adapter";
+    }
+
+}
 
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap.http;
+
+class AuthenticationException extends Exception {
+
+    public AuthenticationException(String message) {
+        super(message);
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap.http;
+
+import java.net.URI;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.config.RequestConfig.Builder;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+
+abstract class CommonHttpClient {
+
+    private static final int HTTP_PORT = 3904;
+    private static final int HTTPS_PORT = 3905;
+    private static final int TIMEOUT_OFFSET = 5000;
+
+    private String authStr;
+
+    protected void setBasicAuth(String username, String password) {
+        if (username != null && password != null) {
+            String plain = String.format("%s:%s", username, password);
+            authStr = Base64.encodeBase64String(plain.getBytes());
+        } else {
+            authStr = null;
+        }
+    }
+
+    protected HttpGet getReq(URI uri, int timeoutMs) throws AuthenticationException {
+
+        HttpGet out = (uri == null) ? new HttpGet() : new HttpGet(uri);
+        if (authStr != null) {
+            out.setHeader("Authorization", String.format("Basic %s", authStr));
+        }
+      
+        out.setConfig(getConfig(timeoutMs));
+        return out;
+    }
+
+    protected HttpPost postReq(String url) throws AuthenticationException {
+
+        HttpPost out = (url == null) ? new HttpPost() : new HttpPost(url);
+        if (authStr != null) {
+            out.setHeader("Authorization", String.format("Basic %s", authStr));
+        }
+        out.setConfig(getConfig(0));
+        return out;
+    }
+
+    private RequestConfig getConfig(int timeoutMs) {
+        Builder builder = RequestConfig.custom();
+        builder.setSocketTimeout(timeoutMs + TIMEOUT_OFFSET);
+        return builder.build();
+    }
+
+    protected CloseableHttpClient getClient() {
+        return HttpClientBuilder.create().build();
+    }
+
+    protected String formatHostString(String host) {
+        return formatHostString(host, host.contains(String.valueOf(HTTPS_PORT)));
+    }
+
+    private String formatHostString(String host, boolean useHttps) {
+        // Trim trailing slash
+        String out = host.endsWith("/") ? host.substring(0, host.length() - 1) : host;
+
+        boolean hasProtocol = out.startsWith("http");
+        boolean hasPort = out.contains(":");
+
+        // Add protocol
+        if (!hasProtocol) {
+            out = String.format("%s%s", (useHttps) ? "https://" : "http://", out);
+        }
+        // Add port
+        if (!hasPort) {
+            out = String.format("%s:%d", out, (useHttps) ? HTTPS_PORT : HTTP_PORT);
+        }
+        return out;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap.http;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONArray;
+import org.onap.appc.adapter.message.Consumer;
+
+public class HttpDmaapConsumerImpl extends CommonHttpClient implements Consumer {
+
+    private static final EELFLogger LOG = EELFManager.getInstance().getLogger(HttpDmaapConsumerImpl.class);
+
+    // Default values
+    private static final int DEFAULT_TIMEOUT_MS = 15000;
+    private static final int DEFAULT_LIMIT = 1000;
+    private static final String URL_TEMPLATE = "%s/events/%s/%s/%s";
+
+    private List<String> urls;
+    private String filter;
+
+    public HttpDmaapConsumerImpl(Collection<String> hosts, String topicName, String consumerName, String consumerId,
+                                 String filter) {
+
+        this(hosts, topicName, consumerName, consumerId, filter, null, null);
+    }
+
+    public HttpDmaapConsumerImpl(Collection<String> hosts, String topicName, String consumerName, String consumerId,
+                                 String filter, String user, String password) {
+
+        urls = new ArrayList<>();
+        for (String host : hosts) {
+            urls.add(String.format(URL_TEMPLATE, formatHostString(host), topicName, consumerName, consumerId));
+        }
+        this.filter = filter;
+        updateCredentials(user, password);
+    }
+
+    @Override
+    public void updateCredentials(String user, String pass) {
+        LOG.debug(String.format("Setting auth to %s for %s", user, this.toString()));
+        this.setBasicAuth(user, pass);
+    }
+
+    @Override
+    public List<String> fetch(int waitMs, int limit) {
+        LOG.debug(String.format("Fetching up to %d records with %dms wait on %s", limit, waitMs, this.toString()));
+        List<String> out = new ArrayList<>();
+        try {
+            List<NameValuePair> urlParams = new ArrayList<>();
+            urlParams.add(new BasicNameValuePair("timeout", String.valueOf(waitMs)));
+            urlParams.add(new BasicNameValuePair("limit", String.valueOf(limit)));
+            if (filter != null) {
+                urlParams.add(new BasicNameValuePair("filter", filter));
+            }
+
+            URIBuilder builder = new URIBuilder(urls.get(0));
+            builder.setParameters(urlParams);
+
+            URI uri = builder.build();
+            LOG.info(String.format("GET %s", uri));
+            HttpGet request = getReq(uri, waitMs);
+            CloseableHttpResponse response = getClient().execute(request);
+
+            int httpStatus = response.getStatusLine().getStatusCode();
+            HttpEntity entity = response.getEntity();
+            String body = (entity != null) ? entityToString(entity) : null;
+
+            LOG.debug(String.format("Request to %s completed with status %d and a body size of %s", uri, httpStatus,
+                body != null ? body.length() : "null"));
+
+            response.close();
+            if (httpStatus == 200 && body != null) {
+                JSONArray json = new JSONArray(body);
+                LOG.info(String.format("Got %d messages from DMaaP", json.length()));
+                for (int i = 0; i < json.length(); i++) {
+                    out.add(json.getString(i));
+                }
+            } else {
+                LOG.error(String.format("Did not get 200 from DMaaP. Got %d - %s", httpStatus, body));
+                sleep(waitMs);
+            }
+        } catch (Exception e) {
+            if (urls.size() > 1) {
+                String failedUrl = urls.remove(0);
+                urls.add(failedUrl);
+                LOG.debug(String.format("Moving host %s to the end of the pool. New primary host is %s", failedUrl,
+                    urls.get(0)));
+            }
+            LOG.error(String.format("Got exception while querying DMaaP. Message: %s", e.getMessage()), e);
+            sleep(waitMs);
+        }
+        return out;
+    }
+
+    @Override
+    public List<String> fetch() {
+        return fetch(DEFAULT_TIMEOUT_MS, DEFAULT_LIMIT);
+    }
+
+    @Override
+    public String toString() {
+        String hostStr = (urls == null || urls.isEmpty()) ? "N/A" : urls.get(0);
+        return String.format("Consumer listening to [%s]", hostStr);
+    }
+
+    String entityToString(HttpEntity entity) throws IOException {
+        return EntityUtils.toString(entity);
+    }
+
+    private void sleep(int ms) {
+        LOG.info(String.format("Sleeping for %ds after failed request", ms / 1000));
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e1) {
+            LOG.error("Interrupted while sleeping", e1);
+            Thread.currentThread().interrupt();
+        }
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap.http;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.onap.appc.adapter.message.Producer;
+
+public class HttpDmaapProducerImpl extends CommonHttpClient implements Producer {
+
+    private static final EELFLogger LOG = EELFManager.getInstance().getLogger(HttpDmaapProducerImpl.class);
+
+    private static final String CONTENT_TYPE = "application/cambria";
+    private static final String URL_TEMPLATE = "%s/events/%s";
+
+    private List<String> hosts;
+    private Set<String> topics;
+
+    public HttpDmaapProducerImpl() {
+        //for test purposes
+    }
+
+    public HttpDmaapProducerImpl(Collection<String> urls, String topicName, String username, String password) {
+        this(urls, topicName);
+        updateCredentials(username, password);
+    }
+    
+    public HttpDmaapProducerImpl(Collection<String> urls, String topicName) {
+        topics = new HashSet<>();
+        topics.add(topicName);
+
+        hosts = new ArrayList<>();
+        for (String host : urls) {
+            hosts.add(formatHostString(host));
+        }
+    }
+
+    @Override
+    public void updateCredentials(String user, String pass) {
+        LOG.debug(String.format("Setting auth to %s for %s", user, this.toString()));
+        this.setBasicAuth(user, pass);
+    }
+
+    @Override
+    public boolean post(String partition, String data) {
+        LOG.debug("Entering HttpDmaapProducerImpl::: post ");
+        long sent = 0;
+        try {
+            HttpPost request = postReq(null);
+            request.setHeader("Content-Type", CONTENT_TYPE);
+            request.setEntity(new StringEntity(bodyLine(partition, data)));
+
+            LOG.debug("Before sendRequest HttpDmaapProducerImpl::: post ");
+            sent = topics.stream()
+                .filter(topic -> sendRequest(request, topic))
+                .count();
+
+        } catch (Exception buildEx) {
+            LOG.error(
+                String.format("Failed to build request with string [%s]. Message not sent to any topic. Reason: %s",
+                    data, buildEx.getMessage()),
+                buildEx);
+        }
+        LOG.debug("Exiting HttpDmaapProducerImpl::: post ");
+        return sent == topics.size();
+    }
+
+    private boolean sendRequest(HttpPost request, String topic) {
+        boolean successful = false;
+        String uriStr = String.format(URL_TEMPLATE, hosts.get(0), topic);
+        try {
+            request.setURI(new URI(uriStr));
+            LOG.debug("HttpDmaapProducerImpl::: before sendRequest()");
+            CloseableHttpResponse response = getClient().execute(request);
+            LOG.debug("HttpDmaapProducerImpl::: after sendRequest()");
+            if (response.getStatusLine().getStatusCode() == 200) {
+                successful = true;
+            }
+            else {
+                LOG.debug("HttpDmaapProducerImpl::: did not receive 200 for sendRequest");
+            }
+            response.close();
+        } catch (Exception sendEx) {
+            LOG.error(String.format("Failed to send message to %s. Reason: %s", uriStr, sendEx.getMessage()),
+                sendEx);
+            if (hosts.size() > 1) {
+                String failedUrl = hosts.remove(0);
+                hosts.add(failedUrl);
+                LOG.debug(String.format("Moving host %s to the end of the pool. New primary host is %s",
+                    failedUrl, hosts.get(0)));
+            }
+        }
+        return successful;
+    }
+
+    /**
+     * Format the body for the application/cambria content type with no partitioning. See
+     *
+     * @param message
+     *            The message body to format
+     * @return A string in the application/cambria content type
+     */
+    private String bodyLine(String partition, String message) {
+        String prt = (partition == null) ? "" : partition;
+        String msg = (message == null) ? "" : message;
+        return String.format("%d.%d.%s%s", prt.length(), msg.length(), prt, msg);
+    }
+
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.onap.appc.configuration.Configuration;
+import org.onap.appc.configuration.ConfigurationFactory;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class DmaapUtil {
+
+    private static final char   DELIMITER             = '_';
+
+    static final String         DMAAP_PROPERTIES_PATH = "org.onap.appc.dmaap.profile.path";
+
+    private static final EELFLogger log                = EELFManager.getInstance().getLogger(DmaapUtil.class);
+
+    private DmaapUtil() {
+    }
+
+    private static String createPreferredRouteFileIfNotExist(String topic) throws IOException {
+        String topicPreferredRouteFileName;
+        topicPreferredRouteFileName = topic + "preferredRoute.properties";
+        File fo = new File(topicPreferredRouteFileName);
+        if (!fo.exists()) {
+            ClassLoader classLoader = DmaapUtil.class.getClassLoader();
+            InputStream inputStream = classLoader.getResourceAsStream("preferredRoute.txt");
+            Properties props = new Properties();
+            props.load(inputStream);
+            String fileName = topic != null ? topic + DELIMITER + "MR1" : DELIMITER + "MR1";
+            props.setProperty("preferredRouteKey", fileName);
+            topicPreferredRouteFileName = topic + "preferredRoute.properties";
+            props.store(new FileOutputStream(topicPreferredRouteFileName),
+                    "preferredRoute.properties -This file is generated automatically for topic:" + topic + " on:"
+                            + System.currentTimeMillis());
+        }
+        return topicPreferredRouteFileName;
+    }
+
+    public static String createConsumerPropFile(String topic, Properties props) throws IOException {
+        String defaultProfFileName = "consumer.properties";
+
+        log.debug("Creating DMaaP Consumer Property File for topic " + topic);
+        return createConsumerProducerPropFile(topic, defaultProfFileName, props);
+    }
+
+    public static String createProducerPropFile(String topic, Properties props) throws IOException {
+        String defaultProfFileName = "producer.properties";
+
+        log.debug("Creating DMaaP Producer Property File for topic " + topic);
+        return createConsumerProducerPropFile(topic, defaultProfFileName, props);
+    }
+
+    private static String createConsumerProducerPropFile(String topic, String defaultProfFileName, Properties props)
+            throws IOException {
+        Properties defaultProps = getDefaultProperties(defaultProfFileName);
+
+        defaultProps.setProperty("topic", topic);
+
+        String preferredRouteFileName = DmaapUtil.createPreferredRouteFileIfNotExist(topic);
+        if (props != null && !props.isEmpty()) {
+            defaultProps.putAll(props);
+        }
+        defaultProps.setProperty("topic", topic);
+        defaultProps.setProperty("DME2preferredRouterFilePath", preferredRouteFileName);
+        String id = defaultProps.getProperty("id");
+        String topicConsumerPropFileName = defaultProfFileName;
+        topicConsumerPropFileName = id != null ? id + DELIMITER + topicConsumerPropFileName
+                : DELIMITER + topicConsumerPropFileName;
+        topicConsumerPropFileName = topic != null ? topic + DELIMITER + topicConsumerPropFileName
+                : DELIMITER + topicConsumerPropFileName;
+
+        defaultProps.store(new FileOutputStream(topicConsumerPropFileName), defaultProfFileName
+                + " - This file is generated automatically for topic:" + topic + " on:" + System.currentTimeMillis());
+        return topicConsumerPropFileName;
+    }
+
+    private static Properties getDefaultProperties(String profileName) {
+        Properties props = new Properties();
+
+        // use appc configuration to get all properties which includes
+        // appc.properties and system properties
+        // allowing variable to be set in any location
+        Configuration config = ConfigurationFactory.getConfiguration();
+        String dmaapPropPath = config.getProperty(DMAAP_PROPERTIES_PATH);
+
+        if (dmaapPropPath != null) {
+            // load from file system
+
+            File profileFile = new File(dmaapPropPath, profileName);
+            FileInputStream inputStream = null;
+
+            log.info("Loading DMaaP Profile from " + profileFile.getAbsolutePath());
+
+            if (profileFile.exists()) {
+                try {
+                    inputStream = new FileInputStream(profileFile);
+                    props.load(inputStream);
+                } catch (IOException e) {
+                    log.error("Exception loading DMaaP Profile from " + profileFile.getAbsolutePath(), e);
+                } finally {
+                    try {
+                        if (inputStream != null) {
+                            inputStream.close();
+                        }
+                    } catch (IOException ex) {
+                        log.warn("Exception closing DMaaP Profile file " + profileFile.getAbsolutePath(), ex);
+                    }
+                }
+            }
+        }
+        if (props.isEmpty()) {
+            // load default Profile from class
+            log.info("Loading Default DMaaP Profile");
+
+            ClassLoader classLoader = DmaapUtil.class.getClassLoader();
+            InputStream inputStream = classLoader.getResourceAsStream(profileName);
+            try {
+                props.load(inputStream);
+            } catch (IOException e) {
+                log.error("Exception loading Default DMaaP Profile", e);
+            }
+        }
+
+        return props;
+    }
+}
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+#TransportType-Specify which way user want to use. I.e. <HTTPAAF,DME2,HTTPAUTH  >
+TransportType=HTTPNOAUTH
+Latitude =50.000000
+Longitude =-100.000000
+Version =1.0
+ServiceName =dmaap-v1.dev.dmaap.dt.saat.acsi.openecomp.org/events
+Environment =TEST
+Partner=BOT_R
+routeOffer=MR1
+SubContextPath =/
+Protocol =http
+MethodType =GET
+username =admin
+password =admin
+contenttype =application/json
+authKey=01234567890abcde:01234567890abcdefghijklmn
+authDate=2016-02-18T13:57:37-0800
+host=127.0.0.1
+topic=org.onap.appc.UNIT-TEST
+group=jmsgrp
+id=2
+timeout=15000
+limit=1000
+filter=
+AFT_DME2_EXCHANGE_REQUEST_HANDLERS=com.att.nsa.test.PreferredRouteRequestHandler
+AFT_DME2_EXCHANGE_REPLY_HANDLERS=com.att.nsa.test.PreferredRouteReplyHandler
+AFT_DME2_REQ_TRACE_ON=true
+AFT_ENVIRONMENT=AFTUAT
+AFT_DME2_EP_CONN_TIMEOUT=15000
+AFT_DME2_ROUNDTRIP_TIMEOUT_MS=240000
+AFT_DME2_EP_READ_TIMEOUT_MS=50000
+sessionstickinessrequired=NO
+DME2preferredRouterFilePath=preferredRoute.txt
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+# ${user.home} usually goes to /root if instantiation uses the appc-docker approach
+
+org.onap.appc.bootstrap.file=appc.properties
+org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},.
 
--- /dev/null
+# ============LICENSE_START==========================================
+# ONAP : APPC
+# ===================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ===================================================================
+#
+# Unless otherwise specified, all software contained herein is licensed
+# under the Apache License, Version 2.0 (the License);
+# you may not use this software except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+# ============LICENSE_END============================================
+preferredRouteKey=MR1
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+#TransportType-Specify which way user want to use. I.e. <HTTPAAF,DME2,HTTPAUTH >
+TransportType=HTTPNOAUTH
+Latitude =50.000000
+Longitude =-100.000000
+Version =1.0
+ServiceName =dmaap-v1.dev.dmaap.dt.saat.acsi.openecomp.org/events
+Environment =TEST
+Partner=BOT_R
+SubContextPath =/
+Protocol =http
+MethodType =POST
+username =admin
+password =admin
+contenttype = application/json
+authKey=01234567890abcde:01234567890abcdefghijklmn
+authDate=2016-07-20T11:30:56-0700
+host=127.0.0.1
+topic=org.onap.appc.UNIT-TEST
+partition=2
+maxBatchSize=100
+maxAgeMs=250
+AFT_DME2_EXCHANGE_REQUEST_HANDLERS=com.att.nsa.test.PreferredRouteRequestHandler
+AFT_DME2_EXCHANGE_REPLY_HANDLERS=com.att.nsa.test.PreferredRouteReplyHandler
+AFT_DME2_REQ_TRACE_ON=true
+AFT_ENVIRONMENT=AFTUAT
+AFT_DME2_EP_CONN_TIMEOUT=15000
+AFT_DME2_ROUNDTRIP_TIMEOUT_MS=240000
+AFT_DME2_EP_READ_TIMEOUT_MS=50000
+sessionstickinessrequired=NO
+DME2preferredRouterFilePath=preferredRoute.txt
+MessageSentThreadOccurance=50
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.onap.appc.adapter.messaging.dmaap.AppcDmaapAdapterActivator;
+
+public class TestAppcDmaapAdapterActivator {
+
+    @Test
+    public void test_dmaap_activator() {
+        // This does nothing since the activator does nothing
+       AppcDmaapAdapterActivator appc = new AppcDmaapAdapterActivator();
+        try {
+            appc.start(null);
+            appc.stop(null);
+        } catch (Exception e) {
+            fail("Got exception when starting stopping. " + e.getMessage());
+        }
+        assertNotNull(appc.getName());
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap;
+
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.appc.adapter.message.Consumer;
+import org.onap.appc.adapter.messaging.dmaap.http.HttpDmaapConsumerImpl;
+import org.onap.appc.configuration.Configuration;
+import org.onap.appc.configuration.ConfigurationFactory;
+import org.junit.Ignore;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Must have a DMaaP cluster or simulator up and running
+ * Update the hostname, topic, client properties in
+ * resources/org/onap/appc/default.properties
+ *
+ */
+public class TestDmaapConsuming {
+
+    private static Consumer httpConsumer;
+
+    @BeforeClass
+    public static void setUp() {
+
+        Configuration configuration = ConfigurationFactory.getConfiguration();
+
+        List<String> hosts = Arrays.asList(configuration.getProperty("poolMembers").split(","));
+        String topic = configuration.getProperty("topic.read");
+        String consumerName = configuration.getProperty("client.name");
+        String consumerId = configuration.getProperty("client.name.id");
+        String msgFilter = configuration.getProperty("message.filter");
+        String user = configuration.getProperty("dmaap.appc.username");
+        String password = configuration.getProperty("dmaap.appc.password");
+
+        httpConsumer = new HttpDmaapConsumerImpl(hosts, topic, consumerName, consumerId, msgFilter);
+    }
+
+    @Test
+    @Ignore
+    public void testHttpFetchMessages() {
+        testFetchMessages(httpConsumer);
+    }
+
+     @Test
+     @Ignore
+    public void testFetchMessages() {
+        testFetchMessages(httpConsumer);
+    }
+
+    private void testFetchMessages(Consumer consumer) {
+        List<String> messages = consumer.fetch(1000, 100);
+        Assert.assertNotNull(messages);
+        Assert.assertFalse(messages.isEmpty());
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap;
+
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onap.appc.adapter.message.Producer;
+import org.onap.appc.adapter.messaging.dmaap.http.HttpDmaapProducerImpl;
+import org.onap.appc.configuration.Configuration;
+import org.onap.appc.configuration.ConfigurationFactory;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Must have a DMaaP cluster or simulator up and running
+ * Update the hostname, topic, client properties in
+ * resources/org/onap/appc/default.properties
+ *
+ */
+public class TestDmaapProducing {
+
+    private static Producer httpProducer;
+
+    @BeforeClass
+    public static void setUp() {
+
+        Configuration configuration = ConfigurationFactory.getConfiguration();
+
+        List<String> hosts = Arrays.asList(configuration.getProperty("poolMembers").split(","));
+        String topic = configuration.getProperty("topic.write");
+        String user = configuration.getProperty("dmaap.appc.username");
+        String password = configuration.getProperty("dmaap.appc.password");
+
+        httpProducer = new HttpDmaapProducerImpl(hosts, topic);
+        httpProducer.updateCredentials(user,password);
+    }
+
+    @Test
+    @Ignore
+    public void testHttpPostMessage() {
+        testPostMessage(httpProducer);
+    }
+
+    @Test
+    @Ignore
+    public void testPostMessages() {
+        testPostMessage(httpProducer);
+    }
+
+    private void testPostMessage(Producer producer) {
+        Assert.assertTrue(producer.post("partition", "{\"message\": \"Hello, world!\"}"));
+    }
+
+}
 
--- /dev/null
+/*
+ * ============LICENSE_START==========================================
+ *  org.onap.music
+ * ===================================================================
+ *  Copyright (c) 2019 IBM.
+ * ===================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * 
+ * ============LICENSE_END=============================================
+ * ====================================================================
+ */
+package org.onap.appc.adapter.messaging.dmaap.http;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestAuthenticationException {
+
+    @Test
+    public void testAuthException() {
+        AuthenticationException authException = new AuthenticationException("AuthenticationException");
+        Assert.assertEquals("AuthenticationException", authException.getMessage());
+    }
+
+}
 
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap.http;
+
+import static org.junit.Assert.*;
+
+import java.net.URI;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommonHttpClient {
+
+    private static final String HTTP = "http://";
+    private static final String HTTPS = "https://";
+    private static final String URL = "example.org/location";
+    private static final URI URI = java.net.URI.create(HTTP + URL);
+    private static final String USERNAME = "username";
+    private static final String PASSWORD = "password";
+    private static final int TIMEOUT = 15000;
+    private static final int TIMEOUT_OFFSET = 5000;
+    private static final int HTTP_PORT = 3904;
+    private static final int HTTPS_PORT = 3905;
+
+    private CommonHttpClient commonHttpClient;
+
+    @Before
+    public void setUp() {
+        commonHttpClient = new CommonHttpClient() {};
+    }
+
+    private void setBasicAuth() {
+        commonHttpClient.setBasicAuth(USERNAME, PASSWORD);
+    }
+
+    private void noBasicAuth() {
+        commonHttpClient.setBasicAuth(null, null);
+    }
+
+    @Test
+    public void shouldGetHttpRequest_whenSetBasicAuth() throws AuthenticationException {
+
+        setBasicAuth();
+
+        HttpGet httpGet = commonHttpClient.getReq(URI, TIMEOUT);
+
+        assertNotNull(httpGet);
+        assertNotNull(httpGet.getFirstHeader("Authorization"));
+        assertNotNull(httpGet.getConfig());
+        assertEquals(httpGet.getConfig().getSocketTimeout(), TIMEOUT + TIMEOUT_OFFSET);
+    }
+
+    @Test
+    public void shouldPostHttpRequest_whenSetBasicAuth() throws AuthenticationException {
+
+        setBasicAuth();
+
+        HttpPost httpPost = commonHttpClient.postReq(URL);
+
+        assertNotNull(httpPost);
+        assertNotNull(httpPost.getFirstHeader("Authorization"));
+        assertNotNull(httpPost.getConfig());
+        assertEquals(httpPost.getConfig().getSocketTimeout(), TIMEOUT_OFFSET);
+    }
+
+    @Test
+    public void shouldGetClient() {
+        assertNotNull(commonHttpClient.getClient());
+    }
+
+    @Test
+    public void shouldFormatHostString() {
+        String httpUrl = HTTP + URL + ":" + HTTP_PORT;
+        String httpsUrl = HTTPS + URL + ":" + HTTPS_PORT;
+        String outputUrl;
+
+        outputUrl = commonHttpClient.formatHostString(httpUrl);
+        assertTrue(assertMessage(httpUrl, outputUrl), httpUrl.equals(outputUrl));
+
+        outputUrl = commonHttpClient.formatHostString(httpsUrl);
+        assertTrue(assertMessage(httpsUrl, outputUrl), httpsUrl.equals(outputUrl));
+
+        outputUrl = commonHttpClient.formatHostString(httpsUrl + "/");
+        assertTrue(assertMessage(httpsUrl, outputUrl), httpsUrl.equals(outputUrl));
+
+        outputUrl = commonHttpClient.formatHostString(URL + ":" + HTTP_PORT);
+        assertTrue(assertMessage(httpUrl, outputUrl), httpUrl.equals(outputUrl));
+
+        outputUrl = commonHttpClient.formatHostString(URL + ":" + HTTPS_PORT);
+        assertTrue(assertMessage(httpsUrl, outputUrl), httpsUrl.equals(outputUrl));
+
+        outputUrl = commonHttpClient.formatHostString(URL);
+        assertTrue(assertMessage(httpUrl, outputUrl), httpUrl.equals(outputUrl));
+    }
+
+    private String assertMessage(String expected, String actual) {
+        return "Expected: " + expected + " Actual: " + actual;
+    }
+}
\ No newline at end of file
 
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap.http;
+
+import static javax.ws.rs.core.Response.Status.FORBIDDEN;
+import static javax.ws.rs.core.Response.Status.OK;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import org.apache.http.HttpEntity;
+import org.apache.http.StatusLine;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+public class TestHttpDmaapConsumerImpl {
+
+    private static final Collection<String> URLS = Arrays.asList("test.com", "test.org");
+    private static final Collection<String> OUTPUT_MSG = Arrays.asList("FirstMessage", "SecondMessage");
+    private static final String TOPIC_NAME = "Topic";
+    private static final String CONSUMER_NAME = "Consumer";
+    private static final String CONSUMER_ID = "Id";
+    private static final String FILTER = "filter";
+    private static final String USERNAME = "username";
+    private static final String PASSWORD = "password";
+    private static final String MESSAGE_BODY = "[FirstMessage, SecondMessage]";
+    private static final int TIMEOUT_MS = 1000;
+    private static final int LIMIT = 1000;
+
+    @Spy
+    private HttpDmaapConsumerImpl httpDmaapConsumer;
+
+    @Mock
+    private CloseableHttpClient httpClient;
+
+    @Mock
+    private CloseableHttpResponse httpResponse;
+
+    @Mock
+    private StatusLine statusLine;
+
+    @Mock
+    private HttpEntity entity;
+
+    @Before
+    public void setUp() throws Exception {
+        httpDmaapConsumer = new HttpDmaapConsumerImpl(URLS, TOPIC_NAME, CONSUMER_NAME, CONSUMER_ID, FILTER);
+        httpDmaapConsumer.updateCredentials(USERNAME, PASSWORD);
+
+        MockitoAnnotations.initMocks(this);
+        doReturn(httpClient).when(httpDmaapConsumer).getClient();
+        when(httpClient.execute(any(HttpGet.class))).thenReturn(httpResponse);
+        when(httpResponse.getStatusLine()).thenReturn(statusLine);
+        when(httpResponse.getEntity()).thenReturn(entity);
+        doReturn(MESSAGE_BODY).when(httpDmaapConsumer).entityToString(same(entity));
+    }
+
+    @Test
+    public void shouldGetHttpRequest() throws Exception {
+
+        when(statusLine.getStatusCode()).thenReturn(OK.getStatusCode());
+
+        List<String> output =  httpDmaapConsumer.fetch();
+
+        assertFalse(output.isEmpty());
+        assertTrue(output.containsAll(OUTPUT_MSG));
+        verify(httpClient).execute(any(HttpGet.class));
+        verify(httpResponse).getStatusLine();
+        verify(httpResponse).getEntity();
+        verify(httpResponse).close();
+        verify(statusLine).getStatusCode();
+        verifyNoMoreInteractions(httpClient, httpResponse, statusLine, entity);
+    }
+
+    @Test
+    public void shouldNotBeSuccessful_whenHttpResponseIsOtherThanOk() throws Exception {
+
+        when(statusLine.getStatusCode()).thenReturn(FORBIDDEN.getStatusCode());
+
+        List<String> output =  httpDmaapConsumer.fetch(TIMEOUT_MS, LIMIT);
+
+        assertTrue(output.isEmpty());
+        verify(httpClient).execute(any(HttpGet.class));
+        verify(httpResponse).getStatusLine();
+        verify(httpResponse).getEntity();
+        verify(httpResponse).close();
+        verify(statusLine).getStatusCode();
+        verifyNoMoreInteractions(httpClient, httpResponse, statusLine, entity);
+    }
+
+    @Test
+    public void shouldNotBeSuccessful_whenRequestToOneOfUrlsCannotBeSent() throws Exception {
+
+        when(httpClient.execute(any(HttpGet.class))).thenThrow(new ClientProtocolException());
+
+        List<String> output =  httpDmaapConsumer.fetch(TIMEOUT_MS, LIMIT);
+
+        assertTrue(output.isEmpty());
+        verify(httpClient).execute(any(HttpGet.class));
+        verifyNoMoreInteractions(httpClient, httpResponse, statusLine, entity);
+
+
+        reset(httpClient);
+        when(httpClient.execute(any(HttpGet.class))).thenReturn(httpResponse);
+        when(statusLine.getStatusCode()).thenReturn(OK.getStatusCode());
+
+        output =  httpDmaapConsumer.fetch(TIMEOUT_MS, LIMIT);
+
+        assertFalse(output.isEmpty());
+        assertTrue(output.containsAll(OUTPUT_MSG));
+        verify(httpClient).execute(any(HttpGet.class));
+        verify(httpResponse).getStatusLine();
+        verify(httpResponse).getEntity();
+        verify(httpResponse).close();
+        verify(statusLine).getStatusCode();
+        verifyNoMoreInteractions(httpClient, httpResponse, statusLine, entity);
+    }
+
+}
\ No newline at end of file
 
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap.http;
+
+import static javax.ws.rs.core.Response.Status.FORBIDDEN;
+import static javax.ws.rs.core.Response.Status.OK;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collection;
+import org.apache.http.StatusLine;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+public class TestHttpDmaapProducerImpl {
+
+    private static final Collection<String> URLS = Arrays.asList("test.com", "test.org");
+    private static final String TOPIC_NAME = "Topic";
+    private static final String USERNAME = "username";
+    private static final String PASSWORD = "password";
+    private static final String PARTITION = "partition";
+    private static final String DATA = "data";
+
+
+    @Spy
+    private HttpDmaapProducerImpl httpDmaapProducer = new HttpDmaapProducerImpl();
+
+    @Mock
+    private CloseableHttpClient httpClient;
+
+    @Mock
+    private CloseableHttpResponse httpResponse;
+
+    @Mock
+    private StatusLine statusLine;
+
+    @Before
+    public void setUp() throws Exception {
+        httpDmaapProducer = new HttpDmaapProducerImpl(URLS, TOPIC_NAME);
+        httpDmaapProducer.updateCredentials(USERNAME, PASSWORD);
+
+        MockitoAnnotations.initMocks(this);
+        doReturn(httpClient).when(httpDmaapProducer).getClient();
+        when(httpClient.execute(any(HttpPost.class))).thenReturn(httpResponse);
+        when(httpResponse.getStatusLine()).thenReturn(statusLine);
+    }
+
+    @Test
+    public void shouldPostHttpRequest() throws Exception {
+
+        when(statusLine.getStatusCode()).thenReturn(OK.getStatusCode());
+
+        boolean successful = httpDmaapProducer.post(PARTITION, DATA);
+
+        assertTrue(successful);
+        verify(httpClient).execute(any(HttpPost.class));
+        verify(httpResponse).getStatusLine();
+        verify(httpResponse).close();
+        verify(statusLine).getStatusCode();
+        verifyNoMoreInteractions(httpClient, httpResponse, statusLine);
+    }
+
+    @Test
+    public void shouldNotBeSuccessful_whenHttpResponseIsOtherThanOk() throws Exception {
+
+        when(statusLine.getStatusCode()).thenReturn(FORBIDDEN.getStatusCode());
+
+        boolean successful = httpDmaapProducer.post(PARTITION, DATA);
+
+        assertFalse(successful);
+        verify(httpClient).execute(any(HttpPost.class));
+        verify(httpResponse).getStatusLine();
+        verify(httpResponse).close();
+        verify(statusLine).getStatusCode();
+        verifyNoMoreInteractions(httpClient, httpResponse, statusLine);
+    }
+
+    @Test
+    public void shouldNotBeSuccessful_whenRequestToOneOfUrlsCannotBeSent() throws Exception {
+
+        when(httpClient.execute(any(HttpPost.class))).thenThrow(new ClientProtocolException());
+
+        boolean successful = httpDmaapProducer.post(PARTITION, DATA);
+
+        assertFalse(successful);
+        verify(httpClient).execute(any(HttpPost.class));
+        verifyNoMoreInteractions(httpClient, httpResponse, statusLine);
+
+
+        reset(httpClient);
+        when(httpClient.execute(any(HttpPost.class))).thenReturn(httpResponse);
+        when(statusLine.getStatusCode()).thenReturn(OK.getStatusCode());
+
+        successful = httpDmaapProducer.post(PARTITION, DATA);
+
+        assertTrue(successful);
+        verify(httpClient).execute(any(HttpPost.class));
+        verify(httpResponse).getStatusLine();
+        verify(httpResponse).close();
+        verify(statusLine).getStatusCode();
+        verifyNoMoreInteractions(httpClient, httpResponse, statusLine);
+    }
+}
\ No newline at end of file
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.messaging.dmaap.utils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.util.Properties;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.appc.configuration.ConfigurationFactory;
+
+public class TestDmaapUtil {
+    private static Class<?>   configurationFactoryClass;
+    private static Field      configField;
+
+    @Test
+    public void testCreateConsumerPropFile() {
+        String topic = "JunitTopicOne";
+        Properties junitProps = new Properties();
+        junitProps.put("host", "192.168.10.10");
+        junitProps.put("group", "junit-client");
+        junitProps.put("id", "junit-consumer-one");
+        junitProps.put("filter", "none");
+
+        String junitFile = null;
+
+        // ensure file path property is not set
+        if (System.getProperty(DmaapUtil.DMAAP_PROPERTIES_PATH) != null) {
+            System.clearProperty(DmaapUtil.DMAAP_PROPERTIES_PATH);
+
+            // set configuration to null to force reloading of properties
+            try {
+                configField.set(null, null);
+            } catch (IllegalArgumentException | IllegalAccessException e1) {
+                // TODO Auto-generated catch block
+                e1.printStackTrace();
+            }
+        }
+        try {
+            junitFile = DmaapUtil.createConsumerPropFile(topic, junitProps);
+        } catch (IOException e) {
+            e.printStackTrace();
+            fail("Exception creating consumer property file");
+        }
+
+        assertNotNull(junitFile);
+
+        // open file and verify properties
+        File testFile = new File(junitFile);
+        assertTrue(testFile.exists());
+
+        InputStream is = null;
+        Properties testProps = new Properties();
+        try {
+            is = new FileInputStream(testFile);
+            testProps.load(is);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            fail("Exception opening consumer property file");
+        } catch (IOException e) {
+            e.printStackTrace();
+            fail("Exception opening consumer property file");
+        } finally {
+            try {
+                if (is != null) {
+                    is.close();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                fail("Exception closing consumer property file");
+            }
+        }
+
+        assertFalse(testProps.isEmpty());
+
+        assertEquals(testProps.get("host"), "192.168.10.10");
+        assertEquals(testProps.get("group"), "junit-client");
+        assertEquals(testProps.get("id"), "junit-consumer-one");
+        assertEquals(testProps.get("filter"), "none");
+        assertEquals(testProps.get("TransportType"), "HTTPNOAUTH");
+    }
+
+    @Test
+    public void testCreateConsumerPropFileWithCustomProfile() {
+        String topic = "JunitTopicOne";
+        Properties junitProps = new Properties();
+        junitProps.put("host", "192.168.10.10");
+        junitProps.put("group", "junit-client");
+        junitProps.put("id", "junit-consumer-two");
+        junitProps.put("filter", "none");
+
+        String junitFile = null;
+
+        // set property for DMaaP profile
+        System.setProperty(DmaapUtil.DMAAP_PROPERTIES_PATH, "src/test/resources/org/onap/appc");
+
+        // set configuration to null to force reloading of properties
+        try {
+            configField.set(null, null);
+        } catch (IllegalArgumentException | IllegalAccessException e1) {
+            // TODO Auto-generated catch block
+            e1.printStackTrace();
+        }
+
+        try {
+            junitFile = DmaapUtil.createConsumerPropFile(topic, junitProps);
+        } catch (IOException e) {
+            e.printStackTrace();
+            fail("Exception creating consumer property file");
+        }
+
+        assertNotNull(junitFile);
+
+        // open file and verify properties
+        File testFile = new File(junitFile);
+        assertTrue(testFile.exists());
+
+        InputStream is = null;
+        Properties testProps = new Properties();
+        try {
+            is = new FileInputStream(testFile);
+            testProps.load(is);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            fail("Exception opening consumer property file");
+        } catch (IOException e) {
+            e.printStackTrace();
+            fail("Exception opening consumer property file");
+        } finally {
+            try {
+                if (is != null) {
+                    is.close();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                fail("Exception closing consumer property file");
+            }
+        }
+
+        assertFalse(testProps.isEmpty());
+
+        assertEquals(testProps.get("host"), "192.168.10.10");
+        assertEquals(testProps.get("group"), "junit-client");
+        assertEquals(testProps.get("id"), "junit-consumer-two");
+        assertEquals(testProps.get("filter"), "none");
+        assertEquals(testProps.get("TransportType"), "HTTPAAF");
+    }
+
+    @Test
+    public void testCreateProducerPropFile() {
+        String topic = "JunitTopicOne";
+        Properties junitProps = new Properties();
+        junitProps.put("host", "192.168.10.10");
+        junitProps.put("group", "junit-client");
+        junitProps.put("id", "junit-producer-one");
+        junitProps.put("filter", "none");
+
+        String junitFile = null;
+
+        // ensure file path property is not set
+        if (System.getProperty(DmaapUtil.DMAAP_PROPERTIES_PATH) != null) {
+            System.clearProperty(DmaapUtil.DMAAP_PROPERTIES_PATH);
+
+            // set configuration to null to force reloading of properties
+            try {
+                configField.set(null, null);
+            } catch (IllegalArgumentException | IllegalAccessException e1) {
+                // TODO Auto-generated catch block
+                e1.printStackTrace();
+            }
+        }
+
+        try {
+            junitFile = DmaapUtil.createProducerPropFile(topic, junitProps);
+        } catch (IOException e) {
+            e.printStackTrace();
+            fail("Exception creating consumer property file");
+        }
+
+        assertNotNull(junitFile);
+
+        // open file and verify properties
+        File testFile = new File(junitFile);
+        assertTrue(testFile.exists());
+
+        InputStream is = null;
+        Properties testProps = new Properties();
+        try {
+            is = new FileInputStream(testFile);
+            testProps.load(is);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            fail("Exception opening consumer property file");
+        } catch (IOException e) {
+            e.printStackTrace();
+            fail("Exception opening consumer property file");
+        } finally {
+            try {
+                if (is != null) {
+                    is.close();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                fail("Exception closing consumer property file");
+            }
+        }
+
+        assertFalse(testProps.isEmpty());
+
+        assertEquals(testProps.get("host"), "192.168.10.10");
+        assertEquals(testProps.get("group"), "junit-client");
+        assertEquals(testProps.get("id"), "junit-producer-one");
+        assertEquals(testProps.get("filter"), "none");
+        assertEquals("HTTPNOAUTH", testProps.get("TransportType"));
+    }
+
+    /**
+     * Use reflection to locate fields and methods so that they can be
+     * manipulated during the test to change the internal state accordingly.
+     * 
+     * @throws NoSuchFieldException
+     *             if the field(s) dont exist
+     * @throws SecurityException
+     *             if reflective access is not allowed
+     * @throws NoSuchMethodException
+     *             If the method(s) dont exist
+     */
+    @SuppressWarnings("nls")
+    @BeforeClass
+    public static void once() throws NoSuchFieldException, SecurityException, NoSuchMethodException {
+        configurationFactoryClass = ConfigurationFactory.class;
+
+        configField = configurationFactoryClass.getDeclaredField("config");
+        configField.setAccessible(true);
+    }
+}
 
--- /dev/null
+{
+"requestTime": "0000-00-00 14:31:19.653787",
+"policyVersion": "13",
+"VMName": "123",
+"from": "test",
+"msgOid": ".1.3.6.1.4.1.193.183.4.1.3.5.1.4",
+"trapID": "1234567",
+"requestClient": "test",
+"message": "Abnormal condition detected",
+"time": "123567890",
+"policyName": "RESTART",
+"trapIDOID": ".1.3.6.1.4.1.193.183.4.1.3.5.1.3",
+"request": "Restart",
+"OPS_CL_timer": "15",
+"nOID": ".1.3.6.1.4.1.193.183.4.2.0.4",
+"AgentAddress": "192.168.1.2",
+"vmOID": ".1.3.6.1.4.1.193.183.4.1.2.1",
+"AICTenantID": "0123456789abcdef0123456789",
+"AICVServerSelfLink": "http://somewhere"
+}
\ No newline at end of file
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+#TransportType-Specify which way user want to use. I.e. <HTTPAAF,DME2,HTTPAUTH  >
+TransportType=HTTPAAF
+Latitude =50.000000
+Longitude =-100.000000
+Version =1.0
+ServiceName =dmaap-v1.dev.dmaap.dt.saat.acsi.openecomp.org/events
+Environment =TEST
+Partner=BOT_R
+routeOffer=MR1
+SubContextPath =/
+Protocol =http
+MethodType =GET
+contenttype =application/json
+#authKey=01234567890abcde:01234567890abcdefghijklmn
+#authDate=2016-02-18T13:57:37-0800
+host=127.0.0.1
+topic=org.onap.appc.UNIT-TEST
+group=jmsgrp
+id=2
+timeout=15000
+limit=1000
+filter=
+AFT_DME2_EXCHANGE_REQUEST_HANDLERS=com.att.nsa.test.PreferredRouteRequestHandler
+AFT_DME2_EXCHANGE_REPLY_HANDLERS=com.att.nsa.test.PreferredRouteReplyHandler
+AFT_DME2_REQ_TRACE_ON=true
+AFT_ENVIRONMENT=AFTUAT
+AFT_DME2_EP_CONN_TIMEOUT=15000
+AFT_DME2_ROUNDTRIP_TIMEOUT_MS=240000
+AFT_DME2_EP_READ_TIMEOUT_MS=50000
+sessionstickinessrequired=NO
+DME2preferredRouterFilePath=preferredRoute.txt
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+org.onap.appc.bootstrap.file=test.properties
+org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},.
+
+# Properties commented out below are provided in appc.properties
+poolMembers=10.0.0.1
+#event.pool.members=<DMAAP_IP>:3904
+
+topic.read=APPC-CL
+topic.read.timeout=5
+topic.write=APPC-CL
+event.topic.write=APPC-CL
+client.name=APPC-CLIENT-DMAAP-ADAPTER-TEST
+client.name.id=0
+
+metric.enabled=false;
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+#TransportType-Specify which way user want to use. I.e. <HTTPAAF,DME2,HTTPAUTH >
+TransportType=HTTPAAF
+Latitude =50.000000
+Longitude =-100.000000
+Version =1.0
+ServiceName =dmaap-v1.dev.dmaap.dt.saat.acsi.openecomp.org/events
+Environment =TEST
+Partner=BOT_R
+SubContextPath =/
+Protocol =http
+MethodType =POST
+contenttype = application/json
+authKey=01234567890abcde:01234567890abcdefghijklmn
+authDate=2016-07-20T11:30:56-0700
+host=127.0.0.1
+topic=org.onap.appc.UNIT-TEST
+partition=2
+maxBatchSize=100
+maxAgeMs=250
+AFT_DME2_EXCHANGE_REQUEST_HANDLERS=com.att.nsa.test.PreferredRouteRequestHandler
+AFT_DME2_EXCHANGE_REPLY_HANDLERS=com.att.nsa.test.PreferredRouteReplyHandler
+AFT_DME2_REQ_TRACE_ON=true
+AFT_ENVIRONMENT=AFTUAT
+AFT_DME2_EP_CONN_TIMEOUT=15000
+AFT_DME2_ROUNDTRIP_TIMEOUT_MS=240000
+AFT_DME2_EP_READ_TIMEOUT_MS=50000
+sessionstickinessrequired=NO
+DME2preferredRouterFilePath=preferredRoute.txt
+MessageSentThreadOccurance=50
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+# Properties commented out below are provided in appc.properties
+#poolMembers=<DMAAP_IP>:3904
+#event.pool.members=<DMAAP_IP>:3904
+
+topic.read=APPC-TEST2
+topic.read.timeout=5
+topic.write=APPC-TEST2
+event.topic.write=APPC-TEST2
+client.name=APPC-CLIENT-DMAAP-ADAPTER-TEST
+client.name.id=0
+#client.key=fakeKey
+#client.secret=fakeSecret
+#event.client.key=fakeKey
+#event.client.secret=fakeSecret
 
--- /dev/null
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.onap.appc.services.dmaap</groupId>
+  <artifactId>dmaap-event-service</artifactId>
+  <packaging>jar</packaging>
+  <version>1.7.0-SNAPSHOT</version>
+  <name>dmaapService</name>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.1.6.RELEASE</version>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.appc.services.dmaap</groupId>
+            <artifactId>appc-event-listener-bundle</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.appc.services.dmaap</groupId>
+            <artifactId>appc-message-adapter-factory</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.appc.services.dmaap</groupId>
+            <artifactId>appc-message-adapter-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.appc.services.dmaap</groupId>
+            <artifactId>appc-dmaap-adapter-bundle</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+    </dependencies>
+      <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.services.dmaapService;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Properties;
+import java.util.Set;
+import org.onap.appc.listener.AppcEventListenerActivator;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+
+/**
+ * Hello world!
+ *
+ */
+@SpringBootApplication
+public class App 
+{
+    public static void main( String[] args )
+    {
+        
+        System.out.println("Starting");
+        AppcEventListenerActivator event = new AppcEventListenerActivator();
+        try {
+            event.start();
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        
+        SpringApplication.run(App.class, args);
+    }
+    
+
+}
 
--- /dev/null
+package org.onap.appc.services.dmaapService;
+
+import java.util.Properties;
+
+import org.onap.appc.configuration.ConfigurationFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@Configuration
+public class AuthenticationConfig extends WebSecurityConfigurerAdapter {
+    
+    private final String PROPERTIES_PREFIX = "appc.srvcomm.messaging";
+    private final String DEFAULT_USER = "appc";
+    private final String DEFAULT_PASSWORD = "onapappc";
+    
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic();
+    }
+    
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        org.onap.appc.configuration.Configuration configuration = ConfigurationFactory.getConfiguration();
+        Properties props = configuration.getProperties();
+        String user = props.getProperty(PROPERTIES_PREFIX + ".user");
+        String pass = props.getProperty(PROPERTIES_PREFIX + ".pass");
+        if(user == null) {
+            user = DEFAULT_USER;
+        }
+        if(pass == null) {
+            pass = DEFAULT_PASSWORD;
+        }
+        auth.inMemoryAuthentication().withUser(user).password(encoder().encode(pass)).roles("USER");
+    }
+    
+    @Bean
+    public PasswordEncoder encoder() {
+        return new BCryptPasswordEncoder();
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.services.dmaapService;
+
+import org.onap.appc.adapter.messaging.dmaap.http.HttpDmaapConsumerImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+@RestController
+public class EventServer {
+    
+    private static final EELFLogger LOG = EELFManager.getInstance().getLogger(EventServer.class);
+
+    @Autowired
+    private PublishService publishService;
+
+    @RequestMapping("/publish")
+    public PublishResponse publish(@RequestBody String body) {
+        PublishRequest req = PublishRequest.parsePublishRequest(body);
+        String result = publishService.publishMessage(req.getProps(),req.getPartition(),
+                req.getTopic(), req.getMessage());
+        if(result.equals("Success")) {
+            return new PublishResponse(result);
+        }
+        LOG.error("Error during message publish: " + result);
+        throw new MessagingException();
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.services.dmaapService;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR, reason="Error Publishing Messsage")
+public class MessagingException extends RuntimeException {
+    
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.services.dmaapService;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class PublishRequest {
+    
+    private static final EELFLogger LOG = EELFManager.getInstance().getLogger(PublishRequest.class);
+    
+    private String props;
+    private String partition;
+    private String message;
+    private String topic;
+
+    private PublishRequest(String props, String partition, String topic, String message) {
+        this.props = props;
+        this.partition = partition;
+        this.message = message;
+        this.topic = topic;
+    }
+
+    public String getProps() {
+        return props;
+    }
+
+    public String getPartition() {
+        return partition;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public static PublishRequest parsePublishRequest(String data) {
+        //body content: props, partition, topic, message
+        String[] bodyParameters = new String[4];
+        LOG.debug("Parsing message into " + bodyParameters.length + " parts: " + data);
+        int[] bodyParameterSizes = new int[bodyParameters.length];
+        for(int i = 0; i < bodyParameters.length; i ++) {
+            String[] split = data.split("\\.", 2);
+            try {
+                bodyParameterSizes[i] = Integer.parseInt(split[0]);
+            } catch(NumberFormatException e) {
+                LOG.error("Could not parse message: " + data);
+            }
+            data = split[1];
+        }
+        int cursor = 0;
+        for(int i = 0; i < bodyParameters.length; i ++) {
+            if(bodyParameterSizes[i] > 0) {
+                bodyParameters[i] = data.substring(cursor, cursor + bodyParameterSizes[i]);
+                cursor = cursor + bodyParameterSizes[i];
+            }
+        }
+        return new PublishRequest(bodyParameters[0], bodyParameters[1], bodyParameters[2], bodyParameters[3]);
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.services.dmaapService;
+
+public class PublishResponse {
+
+    private String status;
+
+    public PublishResponse(String status) {
+        this.status = status;
+    }
+
+    public String getName() {
+        return status;
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.services.dmaapService;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+
+import org.onap.appc.adapter.factory.DmaapMessageAdapterFactoryImpl;
+import org.onap.appc.configuration.Configuration;
+import org.onap.appc.configuration.ConfigurationFactory;
+import org.springframework.stereotype.Service;
+import org.onap.appc.adapter.message.MessageAdapterFactory;
+import org.onap.appc.adapter.message.Producer;
+import org.onap.appc.adapter.messaging.dmaap.http.HttpDmaapProducerImpl;
+
+@Service
+public class PublishService {
+    
+    private Map<String,Producer> producers;
+    private MessageAdapterFactory factory;
+    Configuration configuration;
+    
+    public PublishService() {
+        this.factory = new DmaapMessageAdapterFactoryImpl();
+        producers = new HashMap<>();
+    }
+    
+    public PublishService(MessageAdapterFactory factory) {
+        this.factory = factory;
+        producers = new HashMap<>();
+    }
+    
+    public String publishMessage(String key, String partition, String topic, String message) {
+        Producer producer = getProducer(key, topic);
+        if(producer == null) {
+            return "Could not find producer with property prefix: " + key;
+        }
+        boolean success = producer.post(partition, message);
+        if(success) {
+            return "Success";
+        }
+        return "Failed. See dmaap service jar log.";
+    }
+    
+    private Producer getProducer(String key, String topic) {
+        String searchKey = key;
+        if(topic != null) {
+            searchKey += topic;
+        }
+        Producer producer = producers.get(searchKey);
+        if(producer != null) {
+            return producer;
+        }
+        producer =  newProducer(key, topic);
+        producers.put(searchKey,producer);
+        return producer;
+    }
+    
+    private Producer newProducer(String key, String topic) {
+        Configuration configuration;
+        if(this.configuration != null) {
+            configuration = this.configuration;
+        } else {
+            configuration = ConfigurationFactory.getConfiguration();
+        }
+        Properties props = configuration.getProperties();
+        HashSet<String> pool = new HashSet<>();
+        if (props != null) {
+            String writeTopic;
+            if(topic == null) {
+                writeTopic = props.getProperty(key + ".topic.write");
+            } else {
+                writeTopic = topic;
+            }
+            String apiKey = props.getProperty(key + ".client.key");
+            String apiSecret = props.getProperty(key + ".client.secret");
+            String hostnames = props.getProperty(key + ".poolMembers");
+            if (hostnames != null && !hostnames.isEmpty()) {
+                for (String name : hostnames.split(",")) {
+                    pool.add(name);
+                }
+            }
+            return factory.createProducer(pool, writeTopic, apiKey, apiSecret);
+        }
+        return null;
+    }
+    
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.services;
+
+import org.onap.appc.services.dmaapService.PublishRequest;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PublishRequestTest {
+    
+    @Test
+    public void testParsePublishRequest() {
+        //props, partition, topic, message
+        String props = "props.test";
+        String partition = "testPartition";
+        String topic = "testTopic";
+        String message = "sameple message data";
+        String data = props.length() + "." + partition.length() + "." + topic.length()
+        + "." + message.length() + "." + props + partition + topic + message;
+        PublishRequest publishRequest = PublishRequest.parsePublishRequest(data);
+        Assert.assertTrue(props.equals(publishRequest.getProps()));
+        Assert.assertTrue(partition.equals(publishRequest.getPartition()));
+        Assert.assertTrue(topic.equals(publishRequest.getTopic()));
+        Assert.assertTrue(message.equals(publishRequest.getMessage()));
+        
+    }
+    
+    @Test
+    public void testParsePublishRequest_period_in_message() {
+        //props, partition, topic, message
+        String props = "props.test";
+        String partition = "testPartition";
+        String topic = "testTopic";
+        String message = "sameple. message. dat.a";
+        String data = props.length() + "." + partition.length() + "." + topic.length()
+        + "." + message.length() + "." + props + partition + topic + message;
+        PublishRequest publishRequest = PublishRequest.parsePublishRequest(data);
+        Assert.assertTrue(props.equals(publishRequest.getProps()));
+        Assert.assertTrue(partition.equals(publishRequest.getPartition()));
+        Assert.assertTrue(topic.equals(publishRequest.getTopic()));
+        Assert.assertTrue(message.equals(publishRequest.getMessage()));
+        
+    }
+    
+    @Test
+    public void testParsePublishRequest_with_missing_value() {
+        //props, partition, topic, message
+        String props = "props.test";
+        String partition = "testPartition";
+        String topic = "";
+        String message = "sameple message data";
+        String data = props.length() + "." + partition.length() + "." + topic.length()
+        + "." + message.length() + "." + props + partition + topic + message;
+        PublishRequest publishRequest = PublishRequest.parsePublishRequest(data);
+        Assert.assertTrue(props.equals(publishRequest.getProps()));
+        Assert.assertTrue(partition.equals(publishRequest.getPartition()));
+        Assert.assertTrue(null == publishRequest.getTopic());
+        Assert.assertTrue(message.equals(publishRequest.getMessage()));
+        
+    }
+
+}
 
--- /dev/null
+# ============LICENSE_START==========================================
+# ONAP : APPC
+# ===================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ===================================================================
+#
+# Unless otherwise specified, all software contained herein is licensed
+# under the Apache License, Version 2.0 (the License);
+# you may not use this software except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+# ============LICENSE_END============================================
+/bin/*
+/target/
+/.settings/
+/bin/
+/target-ide/
+/logs/
+/debug-logs/
 
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+  Copyright (C) 2017 Amdocs
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.onap.appc.parent</groupId>
+               <artifactId>binding-parent</artifactId>
+               <version>2.6.2</version>
+                <relativePath />
+       </parent>
+        <groupId>org.onap.appc.services.dmaap</groupId>
+
+       <artifactId>appc-event-listener-bundle</artifactId>
+       <packaging>jar</packaging>
+       <name>Event Listener - bundle</name>
+
+       <dependencies>
+<!--
+               <dependency>
+                       <groupId>org.onap.appc</groupId>
+                       <artifactId>appc-rest-bundle</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+-->
+                <dependency>
+                     <groupId>ch.qos.logback</groupId>
+                     <artifactId>logback-classic</artifactId>
+                    <version>${logback.version}</version>
+                </dependency>
+               <dependency>
+                       <groupId>com.att.eelf</groupId>
+                       <artifactId>eelf-core</artifactId>
+                       <exclusions>
+                            <exclusion>
+                                 <groupId>ch.qos.logback</groupId>
+                                 <artifactId>logback-classic</artifactId>
+                            </exclusion>
+                        </exclusions>
+               </dependency>
+               <dependency>
+                       <groupId>org.onap.appc</groupId>
+                       <artifactId>appc-common-bundle</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.onap.appc.services.dmaap</groupId>
+                       <artifactId>appc-dmaap-adapter-bundle</artifactId>
+                       <version>${project.version}</version>
+            <scope>provided</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.onap.appc.services.dmaap</groupId>
+                       <artifactId>appc-message-adapter-api</artifactId>
+                       <version>${project.version}</version>
+            <scope>provided</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.onap.appc.services.dmaap</groupId>
+                       <artifactId>appc-message-adapter-factory</artifactId>
+                       <version>${project.version}</version>
+            <scope>provided</scope>
+               </dependency>
+<!--
+               <dependency>
+                       <groupId>org.onap.appc</groupId>
+                       <artifactId>appc-rest-model</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+-->
+
+               <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpclient</artifactId>
+                       <version>4.5.3</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpcore</artifactId>
+                       <version>${apache.httpcomponents.version}</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>equinoxSDK381</groupId>
+                       <artifactId>org.eclipse.osgi</artifactId>
+               </dependency>
+                <dependency>
+                  <groupId>commons-codec</groupId>
+                  <artifactId>commons-codec</artifactId>
+                </dependency>
+               <dependency>
+                       <groupId>com.fasterxml.jackson.core</groupId>
+                       <artifactId>jackson-databind</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>com.fasterxml.jackson.core</groupId>
+                       <artifactId>jackson-core</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>com.fasterxml.jackson.core</groupId>
+                       <artifactId>jackson-annotations</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>commons-logging</groupId>
+                       <artifactId>commons-logging</artifactId>
+                       <version>1.2</version>
+                       <scope>compile</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-core</artifactId>
+                       <scope>test</scope>
+               </dependency>
+       </dependencies>
+
+       <version>1.7.0-SNAPSHOT</version>
+</project>
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2019 IBM
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener;
+
+import java.security.SecureRandom;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.RejectedExecutionHandler;
+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.onap.appc.listener.impl.EventHandlerImpl;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public abstract class AbstractListener implements Listener {
+
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(AbstractListener.class);
+
+    protected AtomicBoolean run = new AtomicBoolean(false);
+    protected int QUEUED_MIN = 1;
+    protected int QUEUED_MAX = 10;
+    protected int THREAD_MIN = 4;
+    protected int THREAD_MAX = THREAD_MIN; // Fixed thread pool
+    protected int THREAD_SCALE_DOWN_SEC = 10; // Number of seconds to wait until we remove idle threads
+    protected ThreadPoolExecutor executor;
+    protected EventHandler dmaap;
+    protected ListenerProperties props;
+
+    private String listenerId;
+
+    public AbstractListener(ListenerProperties props) {
+        updateProperties(props);
+
+        dmaap = new EventHandlerImpl(props);
+        if (dmaap.getClientId().equals("0")) {
+               dmaap.setClientId(String.valueOf(new SecureRandom().nextInt(1000)));
+        }
+
+        BlockingQueue<Runnable> threadQueue = new ArrayBlockingQueue<Runnable>(QUEUED_MAX + QUEUED_MIN + 1);
+        executor = new ThreadPoolExecutor(THREAD_MIN, THREAD_MAX, THREAD_SCALE_DOWN_SEC, TimeUnit.SECONDS, threadQueue,
+            new JobRejectionHandler());
+
+        // Custom Named thread factory
+        BasicThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("DMaaP-Worker-%d").build();
+        executor.setThreadFactory(threadFactory);
+
+        run.set(true);
+    }
+
+    /**
+     * Starts a loop that will only end after stop() or stopNow() are called. The loop will read messages off the DMaaP
+     * topic and perform some action on them while writing messages back to DMaaP at critical points in the execution.
+     * Inherited from Runnable.
+     * 
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run() {
+        LOG.error("Listener.run() has not been implemented");
+    }
+
+    @Override
+    public void stop() {
+        run.set(false);
+        LOG.info(String.format("Stopping with %d messages in queue", executor.getQueue().size()));
+        executor.shutdown();
+        try {
+            executor.awaitTermination(10, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            LOG.error("Listener graceful stop() failed", e);
+            Thread.currentThread().interrupt();
+        }
+        
+        // close DMaaP clients
+        if (dmaap != null) {
+               dmaap.closeClients();
+        }
+        LOG.info("Listener Thread Pool Finished");
+    }
+
+    @Override
+    public void stopNow() {
+        run.set(false);
+        LOG.info(String.format("StopNow called. Orphaning %d messages in the queue", executor.getQueue().size()));
+        executor.getQueue().clear();
+        stop();
+    }
+
+    @Override
+    public String getBenchmark() {
+        return String.format("%s - No benchmarking implemented.", getListenerId());
+    }
+
+    @Override
+    public String getListenerId() {
+        return listenerId;
+    }
+
+    // Sets the id of the listener in
+    @Override
+    public void setListenerId(String id) {
+        listenerId = id;
+    }
+
+    private void updateProperties(ListenerProperties properties) {
+        this.props = properties;
+        QUEUED_MIN =
+            Integer.valueOf(props.getProperty(ListenerProperties.KEYS.THREADS_MIN_QUEUE, String.valueOf(QUEUED_MIN)));
+        QUEUED_MAX =
+            Integer.valueOf(props.getProperty(ListenerProperties.KEYS.THREADS_MAX_QUEUE, String.valueOf(QUEUED_MAX)));
+        THREAD_MIN =
+            Integer.valueOf(props.getProperty(ListenerProperties.KEYS.THREADS_MIN_POOL, String.valueOf(THREAD_MIN)));
+        THREAD_MAX =
+            Integer.valueOf(props.getProperty(ListenerProperties.KEYS.THREADS_MAX_POOL, String.valueOf(THREAD_MAX)));
+
+        listenerId = props.getPrefix();
+    }
+
+    /**
+     * This class will be used to handle what happens when we cannot add a job because of a ThreadPool issue. It does
+     * not get invoked if there is any fault with the job. NOTE: So far, this has only been seen when doing a
+     * {@link Listener#stopNow}
+     *
+     */
+    class JobRejectionHandler implements RejectedExecutionHandler {
+        @Override
+        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
+            LOG.error(String.format("A job was rejected. [%s]", r));
+        }
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener;
+
+import org.onap.appc.configuration.Configuration;
+import org.onap.appc.configuration.ConfigurationFactory;
+import org.onap.appc.listener.impl.ControllerImpl;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * This activator is used to initialize and terminate the dmaap listener controller and pool(s)
+ * <p>
+ * The DMaaP listener is responsible for listening to a topic on the Universal Event Bus and reading in messages that
+ * conform to the DCAE message format for APPC. These messages will then be parsed and passed along to the APPC Provider
+ * to take action on. The listener will also send messages out on DMaaP during critical phases. The messages sent out
+ * will have a status of:
+ * <ul>
+ * <li><i>PENDING</i> - The listener has read the message off of DMaaP and has put it in the queue to be processed</li>
+ * <li><i>ACTIVE</i> - The listener has begun actually processing the request and is waiting on the appc provider to
+ * complete the request</li>
+ * <li><i>SUCCESS</i> or <i>FAILURE</i> - The listener has gotten a response back from the appc provider. If it is a
+ * FAILURE, a message should also be included</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Activation of the bundle will provision 1 controller that in turn will provision 1 (or in the future more) listener
+ * to interact with DMaaP. Each listener will have a queue of messages read off of DMaaP and a thread pool of workers to
+ * process them. This worker is responsible for contacting appc provider to perform the action
+ * </p>
+ * <p>
+ * When the bundle is deactivated, the stopNow() method is called and the thread pool is emptied and all remaining jobs
+ * are orphaned. Alternatively stop() could be called which would allow all remaining jobs in the queue to complete at
+ * the cost of longer run time.
+ * </p>
+ * 
+ * @since Aug 30, 2015
+ * @version $Id$
+ */
+public class AppcEventListenerActivator {
+
+
+    /**
+     * The configuration object
+     */
+    private Configuration configuration;
+
+    /**
+     * The reference to the actual implementation object that implements the services
+     */
+    private Controller adapter;
+
+    /**
+     * The logger to be used
+     */
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(AppcEventListenerActivator.class);
+
+    /**
+     * Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start
+     * this bundle. This method can be used to register services or to allocate any resources that this bundle needs.
+     * <p>
+     * This method must complete and return to its caller in a timely manner.
+     * </p>
+     *
+     * @param ctx
+     *            The execution context of the bundle being started.
+     * @throws java.lang.Exception
+     *             If this method throws an exception, this bundle is marked as stopped and the Framework will remove
+     *             this bundle's listeners, unregister all services registered by this bundle, and release all services
+     *             used by this bundle.
+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+     */
+    public void start() throws Exception {
+        LOG.info("Starting Bundle " + getName());
+
+        Properties props = getProperties();
+
+        Set<ListenerProperties> listeners = new HashSet<>();
+
+        // Configure event listener for the demo use case
+        ListenerProperties demoProps = new ListenerProperties("appc.demo", props);
+        // Only add the listener if properties are set
+        if (!demoProps.getProperties().isEmpty()) {
+            demoProps.setListenerClass(org.onap.appc.listener.demo.impl.ListenerImpl.class);
+            listeners.add(demoProps);
+        }
+
+
+        ListenerProperties clLCMProps = new ListenerProperties("appc.LCM", props);
+        // Only add the listener if properties are set
+        if (!clLCMProps.getProperties().isEmpty()) {
+            clLCMProps.setListenerClass(org.onap.appc.listener.LCM.impl.ListenerImpl.class);
+            listeners.add(clLCMProps);
+        }
+
+
+        // Configure the OAM properties
+        String oamPropKeyPrefix = "appc.OAM";
+        ListenerProperties oamProps  = new ListenerProperties(oamPropKeyPrefix, props);
+        // Only add the listener if properties are set and enabled is true
+        if (!oamProps.getProperties().isEmpty() && isAppcOamPropsListenerEnabled(oamProps)) {
+            oamProps.setListenerClass(org.onap.appc.listener.LCM.impl.ListenerImpl.class);
+            listeners.add(oamProps);
+        } else {
+            LOG.warn(String.format("The listener %s is disabled and will not be run", oamPropKeyPrefix));
+        }
+
+        adapter = new ControllerImpl(listeners);
+        adapter.start();
+
+        LOG.info("DMaaP Listener started successfully");
+    }
+
+    /**
+     * Called when this bundle is stopped so the Framework can perform the bundle-specific activities necessary to stop
+     * the bundle. In general, this method should undo the work that the BundleActivator.start method started. There
+     * should be no active threads that were started by this bundle when this bundle returns. A stopped bundle must not
+     * call any Framework objects.
+     * <p>
+     * This method must complete and return to its caller in a timely manner.
+     * </p>
+     *
+     * @param ctx
+     *            The execution context of the bundle being stopped.
+     * @throws java.lang.Exception
+     *             If this method throws an exception, the bundle is still marked as stopped, and the Framework will
+     *             remove the bundle's listeners, unregister all services registered by the bundle, and release all
+     *             services used by the bundle. *
+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop() throws Exception {
+        boolean stopNow = true;
+        LOG.info("Stopping DMaaP Listener. StopNow=" + stopNow);
+        adapter.stop(stopNow);
+        LOG.info("DMaaP Listener stopped successfully");
+    }
+
+    public String getName() {
+        return "DMaaP Listener";
+    }
+
+    /**
+     * Check if AppcOam props disable listener or not
+     *
+     * @param listenerProperties of ListenerProperties objext
+     * @return false only if AppcOam disabled key is defined and equal to true. Otherwise, return true.
+     */
+    private boolean isAppcOamPropsListenerEnabled(ListenerProperties listenerProperties) {
+        final Properties appcOamProperties = listenerProperties.getProperties();
+
+        boolean result;
+        if (appcOamProperties == null) {
+            result = true;
+        } else {
+            result = !Boolean.parseBoolean(appcOamProperties.getProperty(
+                    ListenerProperties.KEYS.DISABLED.getPropertySuffix()));
+        }
+
+        return result;
+    }
+    
+    /**
+     * Get properties from configuration
+     */
+    Properties getProperties() {
+        configuration = ConfigurationFactory.getConfiguration();
+        return configuration.getProperties();
+    }
+    
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener;
+
+import java.util.Map;
+
+/**
+ * A controller is responsible for creating a listener for each ListenerProperties object that is passed in to it on
+ * instantiation. The controller will create a thread pool that will contain all of the listener threads so no listener
+ * can crash the controller.
+ *
+ */
+public interface Controller {
+
+    /**
+     * Creates a new thread in the thread pool for an implementation of the {@see #Listener} class set in the
+     * ListenerProperties. This thread is run immediately after it is created.
+     */
+    public void start();
+
+    /**
+     * Stops each of the listeners known by this controller. Takes an optional parameter that indicates the the listener
+     * should stop immediately rather than waiting for all threads to complete.
+     *
+     * @param stopNow
+     *            Determines what method the listeners should use to shutdown. If true, listeners will use the stopNow()
+     *            method. Otherwise they will use the stop() method.
+     */
+    public void stop(boolean stopNow);
+
+    /**
+     * @return A Map of ListenerProperties and the Listener object that is running in the controllers thread pool.
+     */
+    public Map<ListenerProperties, Listener> getListeners();
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * EventHandler defines a class that wraps DMaaP operations (most notably Get Message and Post Message) to make them
+ * easier to use.
+ *
+ */
+public interface EventHandler {
+
+    /**
+     * Gets a list of messages as Strings on the read topic.
+     *
+     * @return A list of String messages. Never returns null.
+     */
+    public List<String> getIncomingEvents();
+
+    /**
+     * Gets a list of messages as String on the read topic.
+     *
+     * @param limit
+     *            The maximum amount of entries to return
+     * @return A list of String messages. Never returns null.
+     */
+    public List<String> getIncomingEvents(int limit);
+
+    /**
+     * Gets a list of messages Mapped to the given Class. If a message cannot be mapped to that class, it is discarded.
+     *
+     * @param cls
+     *            The class to map the message to.
+     * @return A list of objects of the provided class. Never returns null.
+     */
+    public <T> List<T> getIncomingEvents(Class<T> cls);
+
+    /**
+     * Gets a list of messages Mapped to the given Class. If a message cannot be mapped to that class, it is discarded.
+     *
+     * @param cls
+     *            The class to map the message to.
+     * @param limit
+     *            The maximum amount of entries to return
+     * @return A list of objects of the provided class. Never returns null.
+     */
+    public <T> List<T> getIncomingEvents(Class<T> cls, int limit);
+
+    /**
+     * Posts the String message to the write topic(s).
+     *
+     * @param event
+     *            The String to post.
+     */
+    public void postStatus(String event);
+
+    /**
+     * Posts the String message to the write topic(s) on the specified partition. Partitions are only used to guarantee
+     * ordering and do not impact if data is retreived.
+     *
+     * @param partition
+     *            The partition to post to or null if no partition should be used.
+     * @param event
+     *            The String to post.
+     */
+    public void postStatus(String partition, String event);
+
+    /**
+     * @return The client/group id used to read messages
+     */
+    public String getClientId();
+
+    /**
+     * Set the client/group id used to read messages
+     *
+     * @param clientId
+     *            The new clientId to use
+     */
+    public void setClientId(String clientId);
+
+    /**
+     * @return The client/group name to use.
+     */
+    public String getClientName();
+
+    /**
+     * Set the client/group name used to read messages.
+     *
+     * @param clientName
+     *            The new clientName to use
+     */
+    public void setClientName(String clientName);
+
+    /**
+     * @return The name of the topic to read from
+     */
+    public String getReadTopic();
+
+    /**
+     * Set the name of the topic to read from.
+     *
+     * @param topic
+     *            The new topic to read from
+     */
+    public void setReadTopic(String topic);
+
+    /**
+     * @return The name of the topic to write to
+     */
+    public String getWriteTopic();
+
+    /**
+     * Set the name of the topic to write to
+     *
+     * @param topic
+     *            The new topic to write to
+     */
+    public void setWriteTopic(String topic);
+
+    /**
+     * Adds a DMaaP host to the host pool
+     *
+     * @param host
+     *            The host to add to the pool in <host>:<port> format
+     */
+    public void addToPool(String host);
+
+    /**
+     * Remove the host name from the pool if it exists
+     *
+     * @param host
+     *            The host to add to the pool in <host>:<port> format
+     */
+    public void removeFromPool(String host);
+
+    /**
+     * Get all of the hosts in the DMaaP pool
+     *
+     * @return A collection of host in <host>:<port> format
+     */
+    public Collection<String> getPool();
+
+    /**
+     * Clear any provided api credentials and make future requests as an unauthenticated user
+     */
+    public void clearCredentials();
+
+    /**
+     *  Sets Blacklist time for a server with response problem in seconds
+     */
+    void setResponseProblemBlacklistTime(String duration);
+
+    /**
+     *  Sets Blacklist time for a server with server problem in seconds
+     */
+    void setServerProblemBlacklistTime(String duration);
+
+    /**
+     *  Sets Blacklist time for a server with DNS problem in seconds
+     */
+    void setDnsIssueBlacklistTime(String duration);
+
+    /**
+     *  Sets Blacklist time for a server with IO Exception problem in seconds
+     */
+    void setIOExceptionBlacklistTime(String duration);
+    /**
+     * Set the api credentials and make future requests as an authenticated user
+     *
+     * @param access
+     *            The access portion of the credentials (either user name or api key)
+     * @param secret
+     *            The secret portion of the credentials (either password or api secret)
+     */
+
+
+    public void setCredentials(String access, String secret);
+
+    /**
+     * Close consumer/producer DMaaP clients
+     */
+    public void closeClients();
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.conv;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.apache.commons.lang3.StringUtils;
+import org.json.JSONObject;
+import org.onap.appc.listener.LCM.model.DmaapMessage;
+import org.onap.appc.listener.LCM.model.DmaapOutgoingMessage;
+import org.onap.appc.listener.util.Mapper;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+public class Converter {
+
+    private Converter() {
+    }
+
+    public static DmaapOutgoingMessage convertJsonNodeToDmaapOutgoingMessage(DmaapMessage event, JsonNode inObj){
+
+        if (event == null || inObj == null) {
+            throw new IllegalArgumentException("One of given arguments is null");
+        }
+
+        DmaapOutgoingMessage outObj = new DmaapOutgoingMessage();
+        outObj.setBody(inObj);
+        outObj.setRpcName(event.getRpcName());
+        outObj.setVersion(event.getVersion());
+        outObj.setType("response");
+        outObj.setCorrelationID(event.getCorrelationID());
+        return outObj;
+    }
+
+    public static String convertDmaapOutgoingMessageToJsonString(DmaapMessage inObj) throws JsonProcessingException {
+
+        if (inObj == null)
+            throw new IllegalArgumentException("Input message is null");
+
+
+        ObjectMapper objectMapper = new ObjectMapper();
+        ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
+            .configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
+            .writer().withFeatures(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
+        return writer.writeValueAsString(inObj);
+
+    }
+
+    public static DmaapOutgoingMessage buildDmaapOutgoingMessageWithUnexpectedError(DmaapMessage event,
+        Exception inputException) {
+
+        if (event == null || inputException == null) {
+            throw new IllegalArgumentException("One of given arguments is null");
+        }
+
+        DmaapOutgoingMessage dmaapOutgoingMessage;
+        String errMsg =
+            StringUtils.isEmpty(inputException.getMessage()) ? inputException.toString() : inputException.getMessage();
+        JSONObject commonHeaderJsonObject = Mapper.toJsonObject(event.getBody().get("input").get("common-header"));
+        JSONObject jsonObjectOutput = new JSONObject().accumulate("common-header", commonHeaderJsonObject)
+            .accumulate("status", new JSONObject().accumulate("code", 200).accumulate("value", errMsg));
+        dmaapOutgoingMessage = new DmaapOutgoingMessage();
+        dmaapOutgoingMessage.setRpcName(event.getRpcName());
+        dmaapOutgoingMessage.setCorrelationID(event.getCorrelationID());
+        dmaapOutgoingMessage.setType("error");
+        dmaapOutgoingMessage.setVersion(event.getVersion());
+        JSONObject jsonObjectBody = new JSONObject().accumulate("output", jsonObjectOutput);
+        JsonNode jsonNodeBody = Mapper.toJsonNodeFromJsonString(jsonObjectBody.toString());
+        dmaapOutgoingMessage.setBody(jsonNodeBody);
+        return dmaapOutgoingMessage;
+    }
+
+    public static String extractRequestIdWithSubId(JsonNode dmaapBody) {
+
+        if (dmaapBody == null) {
+            throw new IllegalArgumentException("Dmaap body is null");
+        }
+
+        JsonNode commonHeaderJsonNode = dmaapBody.get("input").get("common-header");
+        String requestId = getValue(commonHeaderJsonNode, "request-id", "");
+        String subRequestId = getValue(commonHeaderJsonNode, "sub-request-id", "");
+        if (!StringUtils.isEmpty(subRequestId)) {
+            requestId = requestId + "-" + subRequestId;
+        }
+        return requestId;
+    }
+
+    public static Integer extractStatusCode(JsonNode event) {
+
+        if (event == null){
+            throw new IllegalArgumentException("Input event is null");
+        }
+
+        Integer statusCode;
+        statusCode = event.get("output").get("status").get("code").asInt();
+        return statusCode;
+    }
+
+    private static String getValue(JsonNode jsonNode, String name, String defaultValue) {
+        if (jsonNode == null) {
+            return defaultValue;
+        }
+        JsonNode childJsonNode = jsonNode.get(name);
+        if (childJsonNode == null) {
+            return defaultValue;
+        }
+        String value = childJsonNode.asText();
+        if (value == null) {
+            return defaultValue;
+        }
+        return value;
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.impl;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import com.fasterxml.jackson.databind.JsonNode;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.concurrent.RejectedExecutionException;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.appc.listener.AbstractListener;
+import org.onap.appc.listener.LCM.conv.Converter;
+import org.onap.appc.listener.LCM.model.DmaapIncomingMessage;
+import org.onap.appc.listener.LCM.operation.ProviderOperations;
+import org.onap.appc.listener.ListenerProperties;
+
+public class ListenerImpl extends AbstractListener {
+
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(ListenerImpl.class);
+
+    private long startTime = 0;
+
+    private final ProviderOperations providerOperations;
+
+    public ListenerImpl(ListenerProperties props) {
+        super(props);
+
+        String url = props.getProperty("provider.url");
+        String user = props.getProperty("provider.user");
+        String pass = props.getProperty("provider.pass");
+        providerOperations = new ProviderOperations(url, user, pass);
+        LOG.info("DMaaP Provider Endpoint: " + url);
+    }
+
+    @Override
+    public void run() {
+        // Some vars for benchmarking
+        startTime = System.currentTimeMillis();
+
+        LOG.info("Running DMaaP Listener");
+
+        while (run.get()) {
+            // Only update if the queue is low. otherwise we read in more
+            // messages than we need
+            try {
+                if (executor.getQueue().size() <= QUEUED_MIN) {
+                    LOG.debug("DMaaP queue running low. Querying for more jobs");
+
+                    List<DmaapIncomingMessage> messages = dmaap
+                        .getIncomingEvents(DmaapIncomingMessage.class, QUEUED_MAX);
+                    LOG.debug(String.format("Read %d messages from dmaap", messages.size()));
+                    for (DmaapIncomingMessage incoming : messages) {
+                        // Acknowledge that we read the event
+                        if (isValid(incoming)) {
+                            String requestIdWithSubId = getRequestIdWithSubId(incoming.getBody());
+                            LOG.info("Acknowledging Message: " + requestIdWithSubId);
+                        }
+                    }
+                    for (DmaapIncomingMessage incoming : messages) {
+                        String requestIdWithSubId = getRequestIdWithSubId(incoming.getBody());
+                        // Add to pool if still running
+                        if (run.get()) {
+                            if (isValid(incoming)) {
+                                LOG.info(String.format("Adding DMaaP message to pool queue [%s]", requestIdWithSubId));
+                                try {
+                                    executor.execute(new WorkerImpl(incoming, dmaap, providerOperations));
+                                } catch (RejectedExecutionException rejectEx) {
+                                    LOG.error("Task Rejected: ", rejectEx);
+                                }
+                            } else {
+                                // Badly formed message
+                                LOG.error("Message was not valid. Rejecting message: " + incoming);
+                            }
+                        } else {
+                            if (isValid(incoming)) {
+                                LOG.info("Run stopped. Orphaning Message: " + requestIdWithSubId);
+                            } else {
+                                // Badly formed message
+                                LOG.error("Message was not valid. Rejecting message: " + incoming);
+                            }
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                LOG.error("Exception " + e.getClass().getSimpleName() + " caught in DMaaP listener");
+                LOG.error(EELFResourceManager.format(e));
+                LOG.error("DMaaP Listener logging and ignoring the exception, continue...");
+            }
+        }
+
+        LOG.info("Stopping DMaaP Listener thread");
+
+        // We've told the listener to stop
+        // TODO - Should we:
+        // 1) Put a message back on the queue indicating that APP-C never got to
+        // the message
+        // or
+        // 2) Let downstream figure it out after timeout between PENDING and
+        // ACTIVE messages
+    }
+
+    private boolean isValid(DmaapIncomingMessage incoming) {
+        return ((incoming != null) &&
+            incoming.getBody() != null
+            && !StringUtils.isEmpty(incoming.getRpcName()));
+    }
+
+    @Override
+    public String getBenchmark() {
+        long time = System.currentTimeMillis();
+        DateFormat df = new SimpleDateFormat("HH:mm:ss");
+        df.setTimeZone(TimeZone.getTimeZone("UTC"));
+        String runningTime = df.format(new Date(time - startTime));
+
+        String out = String.format("Running for %s and completed %d jobs using %d threads.", runningTime,
+            executor.getCompletedTaskCount(), executor.getPoolSize());
+        LOG.info("***BENCHMARK*** " + out);
+        return out;
+    }
+
+    private String getRequestIdWithSubId(JsonNode event) {
+        String requestId = "";
+        try {
+            requestId = Converter.extractRequestIdWithSubId(event);
+        } catch (Exception e) {
+            LOG.error("failed to parse request-id and sub-request-id. Json not in expected format", e);
+        }
+        return requestId;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.impl;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.EventHandler;
+import org.onap.appc.listener.LCM.conv.Converter;
+import org.onap.appc.listener.LCM.model.DmaapMessage;
+import org.onap.appc.listener.LCM.model.DmaapOutgoingMessage;
+import org.onap.appc.listener.LCM.operation.ProviderOperations;
+
+public class WorkerImpl implements Runnable {
+
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(WorkerImpl.class);
+
+    // Should have all of the data we need for processing
+    private DmaapMessage event;
+
+    // So we can post messages from inside the worker.
+    private EventHandler dmaap;
+
+    //so we know were to post the messages
+    private final ProviderOperations providerOperations;
+
+
+    public WorkerImpl(DmaapMessage message, EventHandler dmaap, ProviderOperations providerOperations) {
+        this.event = message;
+        this.dmaap = dmaap;
+        this.providerOperations = providerOperations;
+    }
+
+    @Override
+    public void run() {
+
+        if (checkParametersForNull(event, dmaap, providerOperations)) {
+            throw new IllegalStateException("Cannot run worker. One of its parameters is null");
+        }
+
+        String requestIdWithSubId = extractRequestIdWithSubId(event.getBody());
+        LOG.debug(String.format("Started working on %s", requestIdWithSubId));
+
+        // Run the dg in a try catch to handle all exceptions and update the message at the end
+        try {
+
+            JsonNode outputJsonNode = doDG(event.getRpcName(), event.getBody());
+            DmaapOutgoingMessage dmaapOutgoingMessage = Converter
+                .convertJsonNodeToDmaapOutgoingMessage(event, outputJsonNode);
+            postMessageToDMaaP(dmaapOutgoingMessage, requestIdWithSubId);
+            Integer statusCode = extractStatusCode(dmaapOutgoingMessage.getBody());
+            if (ProviderOperations.isSucceeded(statusCode)) {
+                LOG.debug(String.format("Event %s finished successfully", requestIdWithSubId));
+            } else {
+                LOG.warn(String.format("Event %s failed", requestIdWithSubId));
+            }
+
+        } catch (Exception e) {
+            // Unknown exception from DG method. Fail and pass the exception along
+            String msg = "Exception: " + e.getMessage();
+            LOG.error(String.format("Event %s finished with failure. %s", requestIdWithSubId, msg));
+            DmaapOutgoingMessage dmaapOutgoingMessage = Converter
+                .buildDmaapOutgoingMessageWithUnexpectedError(event, e);
+            postMessageToDMaaP(dmaapOutgoingMessage, requestIdWithSubId);
+        }
+
+        LOG.debug("Done working on " + requestIdWithSubId);
+    }
+
+    private boolean checkParametersForNull(DmaapMessage message, EventHandler dmaap,
+        ProviderOperations providerOperations) {
+
+        return message == null || dmaap == null || providerOperations == null;
+    }
+
+    private Integer extractStatusCode(JsonNode event) {
+        Integer statusCode = null;
+        try {
+            statusCode = Converter.extractStatusCode(event);
+        } catch (Exception e) {
+            LOG.error("failed to parse statusCode. Json not in expected format", e);
+        }
+        return statusCode;
+    }
+
+
+    private String extractRequestIdWithSubId(JsonNode event) {
+        String requestId = "";
+        try {
+            requestId = Converter.extractRequestIdWithSubId(event);
+        } catch (Exception e) {
+            LOG.error("failed to parse request-id and sub-request-id. Json not in expected format", e);
+        }
+        return requestId;
+    }
+
+
+    private void postMessageToDMaaP(DmaapOutgoingMessage dmaapOutgoingMessage, String requestIdWithSubId) {
+        String dmaapOutgoingMessageJsonString;
+        try {
+            dmaapOutgoingMessageJsonString = Converter.convertDmaapOutgoingMessageToJsonString(dmaapOutgoingMessage);
+            dmaap.postStatus(dmaapOutgoingMessage.getCambriaPartition(), dmaapOutgoingMessageJsonString);
+        } catch (JsonProcessingException e) {
+            LOG.error(
+                "failed to postMessageToDMaaP requestIdWithSubId: " + requestIdWithSubId + " dmaapOutgoingMessage: "
+                    + dmaapOutgoingMessage, e);
+        }
+    }
+
+    private JsonNode doDG(String rpcName, JsonNode msg) throws APPCException {
+        return providerOperations.topologyDG(rpcName, msg);
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+
+
+public class ActionIdentifiers implements Serializable {
+
+    @JsonProperty("service-instance-id")
+    private String serviceInstanceId;
+    @JsonProperty("vnf-id")
+    private String vnfID;
+    @JsonProperty("vnfc-name")
+    private String vnfcName;
+    @JsonProperty("vserver-id")
+    private String vserverId;
+
+    public ActionIdentifiers() {
+    }
+
+    public ActionIdentifiers(ActionIdentifiers actionIdentifiers) {
+        this.serviceInstanceId=actionIdentifiers.getServiceInstanceId();
+        this.vnfID=actionIdentifiers.getVnfID();
+        this.vnfcName=actionIdentifiers.getVnfcName();
+        this.vserverId=actionIdentifiers.getVserverId();
+    }
+
+    public String getServiceInstanceId() {
+        return serviceInstanceId;
+    }
+
+    public void setServiceInstanceId(String serviceInstanceId) {
+        this.serviceInstanceId = serviceInstanceId;
+    }
+
+    public String getVnfID() {
+        return vnfID;
+    }
+
+    public void setVnfID(String vnfID) {
+        this.vnfID = vnfID;
+    }
+
+    public String getVnfcName() {
+        return vnfcName;
+    }
+
+    public void setVnfcName(String vnfcName) {
+        this.vnfcName = vnfcName;
+    }
+
+    public String getVserverId() {
+        return vserverId;
+    }
+
+    public void setVserverId(String vserverId) {
+        this.vserverId = vserverId;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modification Copyright (C) 2019 IBM
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Map;
+
+import org.onap.appc.util.Time;
+
+public class CommonHeader implements Serializable {
+    @JsonProperty("timestamp")
+    private String timeStamp;
+    @JsonProperty("api-ver")
+    private String apiVer;
+    @JsonProperty("originator-id")
+    private String originatorId;
+    @JsonProperty("request-id")
+    private String requestID;
+    @JsonProperty("sub-request-id")
+    private String subRequestId;
+    @JsonProperty("flags")
+    private Map<String, String> flags;
+
+    private final DateFormat ZULU_FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'");
+
+    public CommonHeader() {
+    }
+
+    public CommonHeader(CommonHeader commonHeader) {
+        // changed to current system time
+        timeStamp = ZULU_FORMATTER.format(Time.utcDate());
+
+        apiVer = commonHeader.getApiVer();
+        originatorId = commonHeader.getOriginatorId();
+        requestID = commonHeader.getRequestID();
+        subRequestId = commonHeader.getSubRequestId();
+        flags = commonHeader.getFlags();
+    }
+
+
+
+    public String getTimeStamp() {
+        return timeStamp;
+    }
+
+    public void setTimeStamp(String timeStamp) {
+        this.timeStamp = timeStamp;
+    }
+
+    public String getApiVer() {
+        return apiVer;
+    }
+
+    public void setApiVer(String apiVer) {
+        this.apiVer = apiVer;
+    }
+
+    public String getRequestID() {
+        return requestID;
+    }
+
+    public void setRequestID(String requestID) {
+        this.requestID = requestID;
+    }
+
+    public String getOriginatorId() {
+        return originatorId;
+    }
+
+    public void setOriginatorId(String originatorId) {
+        this.originatorId = originatorId;
+    }
+
+    public String getSubRequestId() {
+        return subRequestId;
+    }
+
+    public void setSubRequestId(String subRequestId) {
+        this.subRequestId = subRequestId;
+    }
+
+    public Map<String, String> getFlags() {
+        return flags;
+    }
+
+    public void setFlags(Map<String, String> flags) {
+        this.flags = flags;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.json.JSONObject;
+import org.onap.appc.listener.util.Mapper;
+
+/**
+ * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request
+ *
+ */
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class DmaapIncomingMessage extends DmaapMessage{
+    private final static String defaultCambriaPartition = "APP-C";
+
+    public DmaapIncomingMessage() {
+        super();
+        setCambriaPartition(defaultCambriaPartition);
+    }
+
+
+    @Override
+    public String toString() {
+        return "DmaapIncomingMessage{"+super.toString()+"}";
+    }
+}
+
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class DmaapMessage {
+
+    @JsonProperty("version")
+    private String version;
+
+    @JsonProperty("type")
+    private String type;
+
+    @JsonProperty("correlation-id")
+    private String correlationID;
+
+    @JsonProperty("cambria.partition")
+    private String cambriaPartition;
+
+    @JsonProperty("rpc-name")
+    private String rpcName;
+
+    @JsonProperty("body")
+    private JsonNode body;
+
+    public String getVersion() {
+        return version;
+    }
+
+
+    public String getType() {
+        return type;
+    }
+
+    public String getCorrelationID() {
+        return correlationID;
+    }
+
+    public String getCambriaPartition() {
+        return cambriaPartition;
+    }
+
+    public String getRpcName() {
+        return rpcName;
+    }
+
+    public JsonNode getBody() {
+        return body;
+    }
+
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public void setCorrelationID(String correlationID) {
+        this.correlationID = correlationID;
+    }
+
+    public void setCambriaPartition(String cambriaPartition) {
+        this.cambriaPartition = cambriaPartition;
+    }
+
+    public void setRpcName(String rpcName) {
+        this.rpcName = rpcName;
+    }
+
+    public void setBody(JsonNode body) {
+        this.body = body;
+    }
+
+    @Override
+    public String toString() {
+        return "DmaapMessage{" +
+            "version='" + version + '\'' +
+            ", type='" + type + '\'' +
+            ", correlationId='" + correlationID + '\'' +
+            ", cambriaPartition='" + cambriaPartition + '\'' +
+            ", rpcName='" + rpcName + '\'' +
+            ", body=" + body +
+            '}';
+    }
+}
+
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.json.JSONObject;
+import org.onap.appc.listener.util.Mapper;
+
+/**
+ * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request
+ *
+ */
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class DmaapOutgoingMessage extends DmaapMessage{
+    private final static String defaultCambriaPartition = "MSO";
+
+    public DmaapOutgoingMessage() {
+        super();
+        setCambriaPartition(defaultCambriaPartition);
+    }
+
+
+    @Override
+    public String toString() {
+        return "DmaapOutgoingMessage{"+super.toString()+"}";
+    }
+}
+
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class InputBody {
+
+    @JsonProperty("common-header")
+    private CommonHeader commonHeader;
+
+    @JsonProperty("action-identifiers")
+    private ActionIdentifiers actionIdentifiers;
+
+    @JsonProperty("action")
+    private String action;
+
+    @JsonProperty("payload")
+    private Object payload;
+
+
+    public Object getPayload() {
+        return payload;
+    }
+
+    public String getAction() {
+        return action;
+    }
+
+    public ActionIdentifiers getActionIdentifiers() {
+        return actionIdentifiers;
+    }
+
+    public CommonHeader getCommonHeader() {
+        return commonHeader;
+    }
+
+    @JsonIgnore
+    public void setPayloadAsString(String payload) {
+        this.payload = payload;
+    }
+
+    public void setPayload(Object payload) {
+        this.payload = payload;
+    }
+
+    public void setAction(String action) {
+        this.action = action;
+    }
+
+    public void setActionIdentifiers(ActionIdentifiers actionIdentifiers) {
+        this.actionIdentifiers = actionIdentifiers;
+    }
+
+    public void setCommonHeader(CommonHeader commonHeader) {
+        this.commonHeader = commonHeader;
+    }
+
+    @JsonIgnore
+    public boolean isValid() {
+        return getCommonHeader() != null;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.json.JSONObject;
+import org.onap.appc.listener.util.Mapper;
+
+/**
+ * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request
+ */
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class OutputBody {
+
+    @JsonProperty("common-header")
+    private CommonHeader header;
+
+    @JsonProperty("status")
+    private ResponseStatus status;
+
+    @JsonProperty("payload")
+    private String payload;
+
+    @JsonProperty("locked")
+    private String locked;
+
+    public OutputBody() {
+    }
+
+    public OutputBody(InputBody msg) {
+        this.header = new CommonHeader(msg.getCommonHeader());
+    }
+
+
+    public JSONObject toResponse() {
+        return Mapper.toJsonObject(this);
+    }
+
+    public String getLocked() {
+        return locked;
+    }
+
+    public String getPayload() {
+        return payload;
+    }
+
+    public CommonHeader getHeader() {
+        return header;
+    }
+
+    public ResponseStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(ResponseStatus status) {
+        this.status = status;
+    }
+
+    public void setLocked(String locked) {
+        this.locked = locked;
+    }
+
+    public void setHeader(CommonHeader header) {
+        this.header = header;
+    }
+
+    public void setPayload(String payload) {
+        this.payload = payload;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s - %s(%s)", getHeader().getRequestID(), getStatus().getCode(), getStatus().getValue());
+    }
+}
+
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ResponseStatus {
+
+    @JsonProperty("code")
+    private Integer code;
+    @JsonProperty("message")
+    private String value;
+
+    public ResponseStatus() {
+    }
+
+    public ResponseStatus(Integer code, String value) {
+        this.code = code;
+        this.value = value;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return "ResponseStatus{" +
+            "code=" + code +
+            ", value='" + value + '\'' +
+            '}';
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.operation;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.json.JSONObject;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.LCM.model.InputBody;
+import org.onap.appc.listener.LCM.model.ResponseStatus;
+import org.onap.appc.listener.util.Mapper;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.net.URL;
+
+public class GenericProviderOperationRequestFormatter implements ProviderOperationRequestFormatter {
+
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(GenericProviderOperationRequestFormatter.class);
+
+    //@formatter:off
+    @SuppressWarnings("nls")
+    private final static String TEMPLATE = "{\"input\": %s}";
+    //@formatter:on
+
+    @Override
+    public String buildPath(URL url, String rpcName) {
+        return url.getPath() + ":" + rpcName;
+    }
+
+    @Override
+    public String buildRequest(InputBody msg) {
+        JSONObject jsonObject = Mapper.toJsonObject(msg);
+        return String.format(TEMPLATE, jsonObject.toString());
+    }
+
+    @Override
+    public ResponseStatus getResponseStatus(JsonNode responseBody)throws APPCException{
+        try {
+            JsonNode status = responseBody.get("output").get("status");
+            return new ResponseStatus(status.get("code").asInt(), status.get("message").asText());
+        } catch (Exception e) {
+            LOG.error("Unknown error processing failed response from provider. Json not in expected format", e);
+            throw new APPCException("APPC has an unknown RPC error");
+        }
+    }
+
+    @Override
+    public String getLocked(JSONObject responseBody) throws APPCException {
+        try {
+            JSONObject outputObject=responseBody.getJSONObject("output");
+            if(outputObject.has("locked")){
+                return outputObject.getString("locked");
+            }else{
+                return null;
+            }
+        } catch (Exception e) {
+            LOG.error("Unknown error processing failed response from provider. Json not in expected format", e);
+            throw new APPCException("APPC has an unknown RPC error");
+        }
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.operation;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.json.JSONObject;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.LCM.model.InputBody;
+import org.onap.appc.listener.LCM.model.ResponseStatus;
+
+import java.net.URL;
+
+
+public interface ProviderOperationRequestFormatter {
+
+    String buildPath(URL url, String rpcName);
+
+    String buildRequest(InputBody msg);
+
+    ResponseStatus getResponseStatus(JsonNode json)throws APPCException;
+
+    String getLocked(JSONObject json)throws APPCException;
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.operation;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.databind.JsonNode;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.Socket;
+import java.net.URL;
+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 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.HttpHeaders;
+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.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.LCM.model.ResponseStatus;
+import org.onap.appc.listener.util.Mapper;
+
+public class ProviderOperations {
+
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class);
+
+    private URL url;
+    private String basicAuth;
+
+    private static ProviderOperationRequestFormatter requestFormatter = new GenericProviderOperationRequestFormatter();
+
+
+    public ProviderOperations(String url, String username, String password){
+        setAuthentication(username, password);
+        try {
+            this.url = new URL(url);
+        } catch (MalformedURLException e) {
+            LOG.error("An error occurred while building url", e);
+        }
+    }
+
+    /**
+     * Calls the AppcProvider to run a topology directed graph
+     *
+     * @param message The incoming message to be run
+     * @return True if the result is success. Never returns false and throws an exception instead.
+     * @throws UnsupportedEncodingException
+     * @throws Exception                    if there was a failure processing the request. The exception message is the failure reason.
+     */
+    @SuppressWarnings("nls")
+    public JsonNode topologyDG(String rpcName, JsonNode message) throws APPCException {
+        if (message == null) {
+            throw new APPCException("Provided message was null");
+        }
+
+        HttpPost postRequest = buildPostRequest(rpcName, message);
+        return getJsonNode(message, postRequest);
+    }
+
+    private HttpPost buildPostRequest(String rpcName, JsonNode message) throws APPCException {
+        HttpPost post;
+        try {
+
+            // Concatenate the "action" on the end of the URL
+            String path = requestFormatter.buildPath(url, rpcName);
+            URL serviceUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
+
+            post = new HttpPost(serviceUrl.toExternalForm());
+            post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
+            post.setHeader(HttpHeaders.ACCEPT, "application/json");
+
+            // Set Auth
+            if (basicAuth != null) {
+                post.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
+            }
+
+            String body = Mapper.toJsonString(message);
+            StringEntity entity = new StringEntity(body);
+            entity.setContentType("application/json");
+            post.setEntity(entity);
+        } catch (UnsupportedEncodingException | MalformedURLException e) {
+            throw new APPCException(e);
+        }
+        return post;
+    }
+
+    private JsonNode getJsonNode(JsonNode message, HttpPost post) throws APPCException {
+        HttpClient client = getHttpClient();
+
+        int httpCode;
+        String respBody;
+        try {
+            HttpResponse response = client.execute(post);
+            httpCode = response.getStatusLine().getStatusCode();
+            respBody = IOUtils.toString(response.getEntity().getContent());
+        } catch (IOException e) {
+            throw new APPCException(e);
+        }
+
+        if (httpCode >= 200 && httpCode < 300 && respBody != null) {
+            JsonNode json;
+            try {
+                json = Mapper.toJsonNodeFromJsonString(respBody);
+            } catch (Exception e) {
+                LOG.error("Error processing response from provider. Could not map response to json", e);
+                throw new APPCException("APPC has an unknown RPC error");
+            }
+            ResponseStatus responseStatus = requestFormatter.getResponseStatus(json);
+            if (!isSucceeded(responseStatus.getCode())) {
+                LOG.warn(String.format("Operation failed [%s]", message.toString()));
+            }
+            return json;
+        }
+        throw new APPCException(String.format("Unexpected response from endpoint: [%d] - %s ", httpCode, respBody));
+    }
+
+    /**
+     * Updates the static var URL and returns the value;
+     *
+     * @return The new value of URL
+     */
+    public String getUrl() {
+        return url.toExternalForm();
+    }
+
+    public void setUrl(String newUrl) {
+        try {
+            url = new URL(newUrl);
+        } catch (MalformedURLException e) {
+            LOG.error("An error occurred while building url", 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
+     * @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 String setAuthentication(String user, String password) {
+        if (user != null && password != null) {
+            String authStr = user + ":" + password;
+            basicAuth = new String(Base64.encodeBase64(authStr.getBytes()));
+        } else {
+            basicAuth = null;
+        }
+        return basicAuth;
+    }
+
+    @SuppressWarnings("deprecation")
+    protected HttpClient getHttpClient() throws APPCException {
+        HttpClient client;
+        switch (url.getProtocol()) {
+            case "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) {
+                    LOG.error("Error getting HTTP Client", e);
+                    client = new DefaultHttpClient();
+                }
+                break;
+            case "http":
+                client = new DefaultHttpClient();
+                break;
+            default:
+                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("TLS");
+
+        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 {
+            return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
+        }
+
+        @Override
+        public Socket createSocket() throws IOException {
+            return sslContext.getSocketFactory().createSocket();
+        }
+    }
+
+    public static boolean isSucceeded(Integer code) {
+
+        //FIXME is it working as intended?
+        return code != null && ((code == 100) || (code == 400));
+    }
+}
\ No newline at end of file
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener;
+
+/**
+ * This interface defines a listener that subscribes to a DMaaP topic and continually polls for messages. The
+ * listener does all operations in the run() method and long running operations should be created in a separate worker
+ * thread.
+ *
+ */
+public interface Listener extends Runnable {
+
+    /**
+     * Should start a continuous poll to get messages from the message bus only ending when stop() or stopNow() are
+     * called.
+     * 
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run();
+
+    /**
+     * Signals the listener to stop accepting new messages to the queue and to cleanly finish processing all remaining
+     * messages in the queue. This can take a significant amount of time to complete depending on the thread pool
+     * characteristics. Similar to {@link #stopNow()}
+     */
+    public void stop();
+
+    /**
+     * Signals the listener to stop accepting new messages to the queue and to destroy all remaining messages in the
+     * queue. This will complete quicker than {@link #stop()} at the cost of discarded requests. Recovery of these
+     * requests would have to be caught downstream. Similar to {@link #stop()}
+     */
+    public void stopNow();
+
+    /**
+     * @return A string that shows various benchmarking data. Can be used by humans to tune the thread pool.
+     */
+    public String getBenchmark();
+
+    /**
+     * @return The listener's id when requesting messages from DMaaP. Also known as the group id.
+     */
+    public String getListenerId();
+
+    /**
+     * Sets the listener's id to use when requesting messages from DMaaP. Also known as the group id.
+     * 
+     * @param idString
+     *            The new listener id
+     */
+    public void setListenerId(String idString);
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener;
+
+import java.util.Properties;
+
+/**
+ * A class for instantiating Listener objects. It is primarily used to hold properties that start with the given prefix.
+ * It also holds a class that implements {@see Listener} and will be used by the controller to spawn a new listener
+ * object.
+ *
+ * @since Apr 25, 2016
+ * @version $Id$
+ */
+public class ListenerProperties {
+
+    private String prefix;
+
+    private Class<? extends Listener> listenerClass;
+
+    private Properties props;
+
+    /**
+     * Creates a new listener object with the given prefix and properties. Any property starting with the prefix is
+     * added to the internal properties object with the prefix removed. All other properties are ignored.
+     * ListenerProperties constructor
+     *
+     * @param prefix
+     *            The prefix of the properties to load
+     * @param allProps
+     *            The properties object to load from.
+     */
+    public ListenerProperties(String prefix, Properties allProps) {
+        this.prefix = prefix;
+        props = new Properties();
+
+        String dottedPrefix = String.format("%s.", prefix);
+        for (String key : allProps.stringPropertyNames()) {
+            if (key.startsWith(dottedPrefix) && key.length() > dottedPrefix.length()) {
+                props.put(key.substring(dottedPrefix.length()), allProps.get(key));
+            }
+        }
+    }
+
+    /**
+     * @return The prefix of these properties
+     */
+    public String getPrefix() {
+        return prefix;
+    }
+
+    /**
+     * Sets the listener class. Will be used by {@see Controller} to instantiate the Listener thread for this object
+     *
+     * @param cls
+     *            The class to be created. Implements {@see Listener}
+     */
+    public void setListenerClass(Class<? extends Listener> cls) {
+        this.listenerClass = cls;
+    }
+
+    /**
+     * @return The class that will be used by {@see Controller} to instantiate the Listener thread for this object
+     */
+    public Class<? extends Listener> getListenerClass() {
+        return listenerClass;
+    }
+
+    /**
+     * Returns a property matching a given KEYS
+     *
+     * @param key
+     *            The KEYS object who's value to return.
+     * @return The value of the property or null if none exists
+     */
+    public String getProperty(KEYS key) {
+        return getProperty(key, null);
+    }
+
+    /**
+     * Returns a property matching a given string.
+     *
+     * @param key
+     *            The key who's value to return.
+     * @return The value of the property or null if none exists
+     */
+    public String getProperty(String key) {
+        return getProperty(key, null);
+    }
+
+    /**
+     * Returns a property matching a given KEYS
+     *
+     * @param key
+     *            The KEYS object who's value to return.
+     * @param defaultValue
+     *            The value to return if the property is not found
+     * @return The value of the property or null if none exists
+     */
+    public String getProperty(KEYS key, String defaultValue) {
+        return getProperty(key.getPropertySuffix(), defaultValue);
+    }
+
+    /**
+     * Returns a property matching a given string.
+     *
+     * @param key
+     *            The key who's value to return.
+     * @param defaultValue
+     *            The value to return if the property is not found
+     * @return The value of the property or null if none exists
+     */
+    public String getProperty(String key, String defaultValue) {
+        return props.getProperty(key, defaultValue);
+    }
+
+    /**
+     * @return The properties object containing all properties
+     */
+    public Properties getProperties() {
+        return props;
+    }
+
+    /**
+     * Reads the <i>prefix</i>.disabled property to determine if the listener is disabled and should not be run by the
+     * controller. Defaults to false if property not set or value cannot be parsed.
+     *
+     * @return true if the listener is disabled and should not be started. false if the listener should be start
+     *         normally (default).
+     */
+    public boolean isDisabled() {
+        return Boolean.valueOf(getProperty(KEYS.DISABLED, "false"));
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s", prefix);
+    }
+
+
+    /**
+     * Set of common properties that will be used by most systems. Primarily relating to DMaaP and ThreadPools
+     *
+     * @since Apr 25, 2016
+     * @version $Id$
+     */
+    public enum KEYS {
+        /**
+         * Property to determine if the listener should be disabled. If not set, defaults to false
+         */
+        DISABLED("disabled"),
+
+        /**
+         * Property for the message service type. Should be a lower case string. See MessageService.
+         */
+        MESSAGE_SERVICE("service"),
+
+        /**
+         * A hostname or comma separated list (no spaces) of hostnames of servers in a cluster. Can have ports included
+         * as well.<br>
+         * Examples:
+         * <ul>
+         * <li>server1.appc.onap.org</li>
+         * <li>server1.appc.onap.org:3904</li>
+         * <li>server1.appc.onap.org,server2.appc.onap.org</li>
+         * </ul>
+         */
+        HOSTS("poolMembers"),
+
+        /**
+         * The topic that will be used for DMaaP read operations. Can only support a single topic.
+         */
+        TOPIC_READ("topic.read"),
+
+        /**
+         * The topic or topics that will be used to write to. If multiple topics are provided, should be in a comma
+         * seperated list with no spaces.<br>
+         * Examples:
+         * <ul>
+         * <li>TOPIC-1</li>
+         * <li>TOPIC-1,TOPIC-2,ANOTHER-TOPIC</li>
+         * </ul>
+         */
+        TOPIC_WRITE("topic.write"),
+
+        /**
+         * The highland park filter to use on read requests. If you are reading and writing to the same topic this must
+         * be provided. Filter should be in JSON format (not url escaped).
+         */
+        TOPIC_READ_FILTER("topic.read.filter"),
+
+        /**
+         * The amount of time in seconds that the DMaaP polling connection should stay open for. Recommended to be set
+         * high (around 60 seconds) as most clients will return immediately and not wait until the timeout is up to
+         * return if they have data.
+         */
+        TOPIC_READ_TIMEOUT("topic.read.timeout"),
+
+        /**
+         *  Blacklist time for a server with response problem in seconds
+         */
+
+        PROBLEM_WITH_RESPONSE_BLACKLIST_TIME("topic.responseProblem.blacklistTime"),
+        /**
+         *  Blacklist time for a server with server problem in seconds
+         */
+
+        PROBLEM_SERVERSIDE_ERROR_BLACKLIST_TIME("topic.serverError.blacklistTime"),
+        /**
+         *  Blacklist time for a server with DNS problem in seconds
+         */
+
+        PROBLEM_DNS_BLACKLIST_TIME("topic.dnsIssue.blacklistTime"),
+        /**
+         *  Blacklist time for a server with IO Exception problem in seconds
+         */
+
+        PROBLEM_IO_EXCEPTION_BLACKLIST_TIME("topic.ioException.blacklistTime"),
+
+        /**
+         * The name of the client to use. Should be unique to the application.
+         */
+        CLIENT_NAME("client.name"),
+
+        /**
+         * The id of the client to use. Should be unique for each instance of the application in an environment.
+         */
+        CLIENT_ID("client.name.id"),
+
+        /**
+         * The User (DMaaP) to use for authentication. If a user is provided, you must include the
+         * domain name (e.g. example<b>@example.com</b>).
+         */
+        AUTH_USER_KEY("client.key"),
+
+        /**
+         * The password (DMaaP) to use for authentication.
+         */
+        AUTH_SECRET_KEY("client.secret"),
+
+        /**
+         * The minimum amount of size of the queue. A client should request new messages once the queue has dropped
+         * below this size.
+         */
+        THREADS_MIN_QUEUE("threads.queuesize.min"),
+
+        /**
+         * The maximum size of the queue. A client will request no new messages once this maximum size has been reached.
+         */
+        THREADS_MAX_QUEUE("threads.queuesize.max"),
+
+        /**
+         * The minimum size of the worker threads pool. This is the pool each listener will use to launch longer running
+         * operations.
+         */
+        THREADS_MIN_POOL("threads.poolsize.min"),
+
+        /**
+         * The maximum size of the worker threads pool. This is the pool each listener will use to launch longer running
+         * operations.
+         */
+        THREADS_MAX_POOL("threads.poolsize.max");
+
+        private String suffix;
+
+        private KEYS(String val) {
+            this.suffix = val;
+        }
+
+        /**
+         * @param prefix
+         *            The prefix to prepend
+         * @return a fully property name that corroponds to what is used in the properties file. Format is PREFIX.KEY
+         */
+        public String getFullProp(String prefix) {
+            return String.format("%s.%s", prefix, suffix);
+        }
+
+        public String getPropertySuffix() {
+            return suffix;
+        }
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.impl;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.onap.appc.listener.AbstractListener;
+import org.onap.appc.listener.ListenerProperties;
+import org.onap.appc.listener.demo.model.IncomingMessage;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+
+public class ListenerImpl extends AbstractListener {
+
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(ListenerImpl.class);
+
+    private long startTime = 0;
+
+    public ListenerImpl(ListenerProperties props) {
+        super(props);
+        String url = props.getProperty("provider.url");        
+        LOG.info("DMaaP Provider Endpoint: " + url);
+        ProviderOperations.setUrl(url);
+
+        // Set Basic Auth
+        String user = props.getProperty("provider.user");
+        String pass = props.getProperty("provider.pass");
+        ProviderOperations.setAuthentication(user, pass);
+    }
+
+    @Override
+    public void run() {
+        // Some vars for benchmarking
+        startTime = System.currentTimeMillis();
+
+        LOG.info("Running DMaaP Listener");
+
+        while (run.get()) {
+            // Only update if the queue is low. otherwise we read in more
+            // messages than we need
+            try {
+                if (executor.getQueue().size() <= QUEUED_MIN) {
+                    LOG.debug("DMaaP queue running low. Querying for more jobs");
+                    List<IncomingMessage> messages = dmaap.getIncomingEvents(IncomingMessage.class, QUEUED_MAX);
+                    LOG.debug(String.format("Read %d messages from dmaap", messages.size()));
+                    for (IncomingMessage incoming : messages) {
+                        // Acknowledge that we read the event
+                        LOG.info("Acknowledging Message: " + incoming.getHeader().getRequestID());
+                        
+                        //TODO: Should we post a pending status for 1607
+                        //dmaap.postStatus(incoming.toOutgoing(Status.PENDING, null).toString());
+                    }
+                    for (IncomingMessage incoming : messages) {
+                        // Add to pool if still running
+                        if (run.get()) {
+                            LOG.info(String.format("Adding DMaaP message to pool queue [%s]", incoming.getHeader().getRequestID()));
+                            if (incoming.isValid()) {
+                                try {
+                                    executor.execute(new WorkerImpl(incoming, dmaap));
+                                } catch (RejectedExecutionException rejectEx) {
+                                    LOG.error("Task Rejected: ", rejectEx);
+                                }
+                            } else {
+                                // Badly formed message
+                                LOG.error("Message was not valid. Rejecting");
+                            }
+                        } else {
+                            LOG.info("Run stopped. Orphaning Message: " + incoming.getHeader().getRequestID());
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                LOG.error("Exception " + e.getClass().getSimpleName() + " caught in DMaaP listener");
+                LOG.error(EELFResourceManager.format(e));
+                LOG.error("DMaaP Listener logging and ignoring the exception, continue...");
+            }
+        }
+
+        LOG.info("Stopping DMaaP Listener thread");
+
+        // We've told the listener to stop
+        // TODO - Should we:
+        // 1) Put a message back on the queue indicating that APP-C never got to
+        // the message
+        // or
+        // 2) Let downstream figure it out after timeout between PENDING and
+        // ACTIVE messages
+    }
+
+    @Override
+    public String getBenchmark() {
+        long time = System.currentTimeMillis();
+        DateFormat df = new SimpleDateFormat("HH:mm:ss");
+        df.setTimeZone(TimeZone.getTimeZone("UTC"));
+        String runningTime = df.format(new Date(time - startTime));
+
+        String out = String.format("Running for %s and completed %d jobs using %d threads.", runningTime,
+            executor.getCompletedTaskCount(), executor.getPoolSize());
+        LOG.info("***BENCHMARK*** " + out);
+        return out;
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * Modifications Copyright (C) 2019 IBM
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.impl;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.json.JSONObject;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.demo.model.IncomingMessage;
+import org.onap.appc.listener.util.HttpClientUtil;
+import org.onap.appc.listener.util.Mapper;
+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 URL url;
+
+    private static String basic_auth;
+
+    //@formatter:off
+    @SuppressWarnings("nls")
+    private final static String TEMPLATE = "{\"input\": {\"common-request-header\": {\"service-request-id\": \"%s\"},\"config-payload\": {\"config-url\": \"%s\",\"config-json\":\"%s\"}}}";
+    //@formatter:on 
+
+    /**
+     * Calls the AppcProvider to run a topology directed graph
+     * 
+     * @param msg
+     *            The incoming message to be run
+     * @return True if the result is success. Never returns false and throws an exception instead.
+     * @throws UnsupportedEncodingException
+     * @throws Exception
+     *             if there was a failure processing the request. The exception message is the failure reason.
+     */
+    @SuppressWarnings("nls")
+    public static boolean topologyDG(IncomingMessage msg) throws APPCException {
+        if (msg == null) {
+            throw new APPCException("Provided message was null");
+        }
+
+        HttpPost post = null;
+        try {
+            // Concatenate the "action" on the end of the URL
+            String path = url.getPath() + ":" + msg.getAction().getValue();
+            URL serviceUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
+
+            post = new HttpPost(serviceUrl.toExternalForm());
+            post.setHeader("Content-Type", "application/json");
+            post.setHeader("Accept", "application/json");
+
+            // Set Auth
+            if (basic_auth != null) {
+                post.setHeader("Authorization", "Basic " + basic_auth);
+            }
+
+            //String body = buildReqest(msg.getId(), msg.getUrl(), msg.getIdentityUrl());
+            String body = buildReqest(msg.getHeader().getRequestID(), msg.getPayload().getGenericVnfId(), msg.getPayload().getStreams());
+            StringEntity entity = new StringEntity(body);
+            entity.setContentType("application/json");
+            post.setEntity(new StringEntity(body));
+        } catch (UnsupportedEncodingException | MalformedURLException e) {
+            throw new APPCException(e);
+        }
+
+        HttpClient client = HttpClientUtil.getHttpClient(url.getProtocol());
+
+        int httpCode = 0;
+        String respBody = null;
+        try {
+            HttpResponse response = client.execute(post);
+            httpCode = response.getStatusLine().getStatusCode();
+            respBody = IOUtils.toString(response.getEntity().getContent());
+        } catch (IOException e) {
+            throw new APPCException(e);
+        }
+
+        if (httpCode == 200 && respBody != null) {
+            JSONObject json;
+            try {
+                json = Mapper.toJsonObject(respBody);
+            } catch (Exception e) {
+                LOG.error("Error prcoessing response from provider. Could not map response to json", e);
+                throw new APPCException("APPC has an unknown RPC error");
+            }
+            boolean success;
+            String reason;
+            try {
+                JSONObject header = json.getJSONObject("output").getJSONObject("common-response-header");
+                success = header.getBoolean("success");
+                reason = header.getString("reason");
+            } catch (Exception e) {
+                LOG.error("Unknown error prcoessing failed response from provider. Json not in expected format", e);
+                throw new APPCException("APPC has an unknown RPC error");
+            }
+            if (success) {
+                return true;
+            }
+            String reasonStr = reason == null ? "Unknown" : reason;
+            LOG.warn(String.format("Topology Operation [%s] failed. Reason: %s", msg.getHeader().getRequestID(), reasonStr));
+            throw new APPCException(reasonStr);
+
+        }
+        throw new APPCException(String.format("Unexpected response from endpoint: [%d] - %s ", httpCode, respBody));
+    }
+
+    /**
+     * Updates the static var URL and returns the value;
+     * 
+     * @return The new value of URL
+     */
+    public static String getUrl() {
+        return url.toExternalForm();
+    }
+
+    public static void setUrl(String newUrl) {
+        try {
+            url = new URL(newUrl);
+        } catch (MalformedURLException e) {
+            LOG.error("Malformed URL", 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
+     * @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(org.apache.commons.codec.binary.Base64.encodeBase64(authStr.getBytes()));
+        } else {
+            basic_auth = null;
+        }
+        return basic_auth;
+    }
+
+    /**
+     * Builds the request body for a topology operation
+     * 
+     * @param id
+     *            The request id
+     * @param url
+     *            The vm's url
+     *            
+     * @param pgstreams 
+     *           The streams to send to the traffic generator
+     *
+     * @return A String containing the request body
+     */
+    private static String buildReqest(String id, String url, String pgstreams) {
+
+        return String.format(TEMPLATE, id, url, pgstreams);
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.impl;
+
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.EventHandler;
+import org.onap.appc.listener.demo.model.IncomingMessage;
+import org.onap.appc.listener.demo.model.Status;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class WorkerImpl implements Runnable {
+
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(WorkerImpl.class);
+
+    // Should have all of the data we need for processing
+    private IncomingMessage event;
+
+    // So we can post messages from inside the worker.
+    private EventHandler dmaap;
+
+    public WorkerImpl(IncomingMessage message, EventHandler dmaap) {
+        this.event = message;
+        this.dmaap = dmaap;
+    }
+
+    @Override
+    public void run() {
+        LOG.debug(String.format("Started working on %s",  event.getHeader().getRequestID()));
+    
+        dmaap.postStatus(event.toOutgoing(Status.ACCEPTED));
+        // Run the dg in a try catch to handle all exceptions and update the
+        // message at the end
+        try {
+            if (doDG(event)) {
+                dmaap.postStatus(event.toOutgoing(Status.SUCCESS));
+                LOG.debug(String.format("Event %s finished successfully",  event.getHeader().getRequestID()));
+            } else {
+                // Should never happen. Exception with message should be thrown instead.
+                LOG.error(String.format(
+                    "We somehow returned false from doDG() instead of throwing exception. Incoming event [%s]",
+                    event.toJson().toString()));
+                dmaap.postStatus(event.toOutgoing(Status.FAILURE));
+            }
+
+        } catch (Exception e) {
+            // Unknown exception from DG method. Fail and pass the exception
+            // along
+            String msg = "Exception: " + e.getMessage();
+            LOG.warn(String.format("Event %s finished with failure. %s", event.getHeader().getRequestID(), msg));
+            //TODO: should a message be included? there is nothing in the API spec for a msg?            
+            //dmaap.postStatus(event.toOutgoing(Status.FAILURE, msg));
+            dmaap.postStatus(event.toOutgoing(Status.FAILURE));
+        }
+
+        LOG.debug("Done working on " + event.getHeader().getRequestID());
+    }
+
+    private boolean doDG(IncomingMessage msg) throws APPCException {
+        return ProviderOperations.topologyDG(msg);
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+public enum Action {
+    Restart("Restart"), Rebuild("Rebuild"), Migrate("Migrate"), Evacuate("Evacuate"), Snapshot("Snapshot"),modifyconfig("ModifyConfig");
+
+    /**
+     * Converts the string to an Action
+     * 
+     * @param value
+     *            The string to try and convert. Is case insensitive
+     * @return The action matching the string or null if no match was found.
+     */
+    public static Action toAction(String value) {
+        if (value != null) {
+            for (Action e : values()) {
+                if (e.getValue().toUpperCase().equals(value.toUpperCase())) {
+                    return e;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private String value;
+
+    private Action(String valueToUse) {
+        value = valueToUse;
+    }
+
+    public final String getValue() {
+        return value;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+import org.json.JSONObject;
+import org.onap.appc.listener.util.Mapper;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion;
+
+/**
+ * This class holds attributes that are common to DMaaP messages both coming in from DCAE and being sent out by APPC
+ *
+ */
+@JsonSerialize(include = Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CommonMessage implements Serializable {
+    /*
+     * { "CommonHeader": { "TimeStamp": "0000-00-00T00:00:00.000Z", "APIver": "1.01", "OriginatorID": "policy.pdp01",
+     * "RequestID": "b74d13c5-bb26-4b04-992c-4679dfc8280e", "SubrequestID": "1" }, "Action": "RESTART", "Payload": {
+     * "VServerSelfLink":
+     * "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345",
+     * "VNF_NAME": "test", "VMID": "abc12345-1234-5678-890a-abcdefg12345", "TenantID":
+     * "abcde12345fghijk6789lmnopq123rst", "LOC_ID": "Test", "in-maint": "false", "Identity":
+     * "http://example.com:5000/v2.0", "Prov_status": "ACTIVE", "OAM_IPV4": "192.168.1.2",
+     * "is-closed-loop-disabled": "false", "VM_NAME": "basx0001vm034", "OAM_IPV6": "aaaa::bbbb:cccc:dddd:eeee/64" } }
+     */
+
+    private static final long serialVersionUID = 1L;
+
+    /*
+     * The common header
+     */
+    @JsonProperty("CommonHeader")
+    private CommonHeader header;
+
+    /*
+     * The payload
+     */
+    @JsonProperty("Payload")    
+    private Payload payload;
+
+    @JsonIgnore
+    private long startTime = System.currentTimeMillis();
+
+    /*
+     * Getters and Setters
+     */
+
+    public long getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(long startTime) {
+        this.startTime = startTime;
+    }
+
+    /**
+     * @return the header
+     */
+    public CommonHeader getHeader() {
+        return header;
+    }
+
+    /**
+     * @param header
+     *            the header to set
+     */
+    public void setHeader(CommonHeader header) {
+        this.header = header;
+    }
+
+    /**
+     * @return the payload
+     */
+    public Payload getPayload() {
+        return payload;
+    }
+
+    /**
+     * @param payload
+     *            the payload to set
+     */
+    public void setPayload(Payload payload) {
+        this.payload = payload;
+    }
+
+    /**
+     * Convenience method to return a json representation of this object.
+     * 
+     * @return The json representation of this object
+     */
+    public JSONObject toJson() {
+        return Mapper.toJsonObject(this);
+    }
+
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class CommonHeader {
+        /*
+         * "CommonHeader": { "TimeStamp": "2016-05-11T13:53:53.146Z", "APIver": "1.01", "OriginatorID": "policy.pdp01",
+         * "RequestID": "b74d13c5-bb26-4b04-992c-4679dfc8280e", "SubrequestID": "1" }
+         */
+
+        /*
+         * The timestamp of the message
+         */
+        @JsonProperty("TimeStamp")
+        private String timeStamp;
+
+        /*
+         * The API version of the message
+         */
+        @JsonProperty("APIver")
+        private String apiVer;
+
+        /*
+         * The Originator ID of the message
+         */
+        @JsonProperty("OriginatorID")
+        private String originatorId;
+
+        /*
+         * The Request Id of the message
+         */
+        @JsonProperty("RequestID")
+        private String requestID;
+
+        /*
+         * The Subrequest Id of the message
+         */
+        @JsonProperty("SubRequestID")
+        private String subRequestId;
+
+        /**
+         * @return the timeStamp
+         */
+        public String getTimeStamp() {
+            return timeStamp;
+        }
+
+        /**
+         * @param timeStamp
+         *            the timeStamp to set
+         */
+        public void setTimeStamp(String timeStamp) {
+            this.timeStamp = timeStamp;
+        }
+
+        /**
+         * @return the apiVer
+         */
+        public String getApiVer() {
+            return apiVer;
+        }
+
+        /**
+         * @param apiVer
+         *            the apiVer to set
+         */
+        public void setApiVer(String apiVer) {
+            this.apiVer = apiVer;
+        }
+
+        /**
+         * @return the originatorId
+         */
+        public String getOriginatorId() {
+            return originatorId;
+        }
+
+        /**
+         * @param originatorId
+         *            the originatorId to set
+         */
+        public void setOriginatorId(String originatorId) {
+            this.originatorId = originatorId;
+        }
+
+        /**
+         * @return the requestID
+         */
+        public String getRequestID() {
+            return requestID;
+        }
+
+        /**
+         * @param requestID
+         *            the requestID to set
+         */
+        public void setRequestID(String requestID) {
+            this.requestID = requestID;
+        }
+
+        /**
+         * @return the subRequestId
+         */
+        public String getSubRequestId() {
+            return subRequestId;
+        }
+
+        /**
+         * @param subRequestId
+         *            the subRequestId to set
+         */
+        public void setSubRequestId(String subRequestId) {
+            this.subRequestId = subRequestId;
+        }
+    };
+
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class Payload {
+        /*
+         * "Payload": { "VServerSelfLink":
+         * "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345",
+         * "VNF_NAME": "test", "VMID": "abc12345-1234-5678-890a-abcdefg12345", "TenantID":
+         * "abcde12345fghijk6789lmnopq123rst", "LOC_ID": "Test", "in-maint": "false", "Identity":
+         * "http://example.com:5000/v2.0", "Prov_status": "ACTIVE", "OAM_IPV4": "192.168.1.2",
+         * "is-closed-loop-disabled": "false", "VM_NAME": "test", "OAM_IPV6": "aaaa::bbbb:cccc:dddd:eeee/64" }
+         */
+
+        /*
+         * The TenantID of the message
+         */
+        @JsonProperty("generic-vnf.vnf-id")
+        private String genericVnfId;
+
+        /**
+         * @return the TenantID
+         */
+        public String getGenericVnfId() {
+            return genericVnfId;
+        }
+
+        /**
+         * @param TenantID
+         *            the TenantID to set
+         */
+        public void setGenericVnfId(String genericVnfId) {
+            this.genericVnfId = genericVnfId;
+        }
+
+        @JsonProperty("streams")
+        private Streams streams;
+
+        /**
+         * @return the TenantID
+         */
+
+        public String getStreams() {
+            String r = "{\\\"streams\\\": {\\\"active-streams\\\": " + streams.getActiveStreams() +
+                    "}}";
+            return r;
+        }
+
+        /**
+         * @param TenantID
+         *            the TenantID to set
+         */
+        public void setStreams(Streams streams) {
+            this.streams = streams;
+        }
+
+
+
+
+
+    };
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class Streams {
+        
+        @JsonProperty("active-streams")
+        private int activeStreams;
+        
+        public int getActiveStreams() {
+            return this.activeStreams;
+        }
+
+        public void setActiveStreams(int activeStreams) {
+            this.activeStreams = activeStreams;
+        }
+        
+    };
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion;
+
+/**
+ * This class represents a message coming in from DCAE.
+ *
+ */
+@JsonSerialize(include = Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class IncomingMessage extends CommonMessage {
+
+    private static final long serialVersionUID = 1L;
+
+    /*
+     * The action being requested. Its presence signals that it is an incoming message and it is not present on outgoing
+     * messages
+     */
+    //TODO; use enum
+    @JsonProperty("Action")
+    private String action;
+
+
+    public String getRequest() {
+        return action;
+    }
+
+    @JsonIgnore
+    public Action getAction() {
+        return Action.toAction(action);
+    }
+
+    public void setRequest(String request) {
+        this.action = request;
+    }
+
+//    @Override
+//    public String toString() {
+//        String time = getRequestTime() != null ? getRequestTime() : "N/A";
+//        // String req = request != null ? request : "N/A";
+//        return String.format("[%s - %s]", time, getId());
+//    }
+
+//    public String toOutgoing(Status status) {
+//        return toOutgoing(status);
+//    }
+
+    public String toOutgoing(Status status) {
+        OutgoingMessage out = new OutgoingMessage(this);
+        out.setResponse(status);
+        return out.toResponse().toString();
+    }
+
+    /**
+     * Determines if this message should be parsed parsed. Will eventually check that the message is well formed, has
+     * all required fields, and had not exceeded any timing restrictions.
+     *
+     * @return True if the message should be parsed. False otherwise
+     */
+    public boolean isValid() {
+        return true;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.SecureRandom;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.json.JSONObject;
+import org.onap.appc.listener.util.Mapper;
+import org.onap.appc.util.Time;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion;
+
+/**
+ * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request
+ *
+ */
+@JsonSerialize(include = Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class OutgoingMessage extends CommonMessage {
+
+    public OutgoingMessage() {
+
+    }
+
+    public OutgoingMessage(IncomingMessage msg) {
+        setHeader(msg.getHeader());
+        setPayload(msg.getPayload());
+        //        setId(msg.getId());
+        //        setOriginalRequest(msg.getRequest());
+        //        setRequestClient(msg.getRequestClient());
+        //        setRequestTime(msg.getRequestTime());
+        //        setVmName(msg.getVmName());
+        //        setFromSystem(generateFrom());
+        //        setResponse(Status.PENDING);
+        //        setPolicyName(msg.getPolicyName());
+        //        setPolicyVersion(msg.getPolicyVersion());
+        //        setStartTime(msg.getStartTime());
+    }
+
+    private static final long serialVersionUID = -5447940920271469613L;
+    /*
+     * The status of the response
+     */
+    @JsonProperty("Status")
+    private OutStatus status;
+
+    /**
+     * @return the status
+     */
+    public OutStatus getStatus() {
+        return status;
+    }
+
+    /**
+     * @param status the status to set
+     */
+    public void setStatus(OutStatus status) {
+        this.status = status;
+    }
+
+    public void updateResponseTime() {
+        SecureRandom rand = new SecureRandom();
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.SSS");
+        df.setTimeZone(TimeZone.getTimeZone("UTC"));
+        String date = df.format(new Date(Time.utcTime()));
+        //this.responseTime = String.format("%s%03d", date, rand.nextInt(1000));
+    }
+
+    public String generateFrom() {
+        String name;
+        try {
+            InetAddress iAddress = getLocalHost();
+            name = iAddress.getCanonicalHostName();
+        } catch (Exception e) {
+            // Could not get anything from the InetAddress
+            name = "UnknownHost";
+        }
+        return "appc@" + name;
+    }
+
+    public JSONObject toResponse() {
+        updateResponseTime();
+        JSONObject json = Mapper.toJsonObject(this);
+
+        if (!json.has("message")) {
+            // If there is no message, parrot the status (response field)
+            // TODO - Can this be removed for 1602 making message truely optional?
+            //json.put("message", this.getResponse().toString());
+        }
+
+        // Removed duplication of status from message for 1602
+        // json.put("message", String.format("%s: %s", request, json.get("message")));
+
+        return json;
+    }
+
+    //    @Override
+    //    public String toString() {
+    //        return String.format("%s - %s", getId(), getResponse());
+    //    }
+
+    public static class OutStatus{
+        @JsonProperty("Code")
+        private String code;
+
+        @JsonProperty("Value")
+        private String value;
+
+        /**
+         * @return the code
+         */
+        public String getCode() {
+            return code;
+        }
+
+        /**
+         * @param code the code to set
+         */
+        public void setCode(String code) {
+            this.code = code;
+        }
+
+        /**
+         * @return the value
+         */
+        public String getValue() {
+            return value;
+        }
+
+        /**
+         * @param value the value to set
+         */
+        public void setValue(String value) {
+            this.value = value;
+        }
+
+    }
+
+    public void setResponse(Status newStatus) {
+        if(this.status == null){
+            this.status = new OutStatus();
+        }
+        if(newStatus == null) {
+            return;
+        }
+
+        switch (newStatus){
+            case ACCEPTED:
+                this.status.setValue(newStatus.getValue());
+                this.status.setCode("100");
+                break;
+
+            case FAILURE:
+                this.status.setValue(newStatus.getValue());
+                this.status.setCode("500");
+                break;
+
+            case SUCCESS:
+                this.status.setValue(newStatus.getValue());
+                this.status.setCode("400");
+                break;
+            default:
+                break;
+
+        }
+    }
+
+    protected InetAddress getLocalHost() throws UnknownHostException {
+        return InetAddress.getLocalHost();
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+public enum Status {
+    /*
+     * APP-C acknowledges that it has read the event off of the wire. This is the initial status of an OutgoingEvent
+     */
+    ACCEPTED("ACCEPTED"),
+
+    /*
+     * APP-C has finished processing the event without errors
+     */
+    SUCCESS("SUCCESS"),
+
+    /*
+     * APP-C has finished processing the event with errors
+     */
+    FAILURE("FAILURE");
+
+    /**
+     * Converts the string to an Status
+     * 
+     * @param value
+     *            The string to try and convert. Is case insensitive
+     * @return The status matching the string or null if no match was found.
+     */
+    public static Status toStatus(String value) {
+        if (value != null) {
+            for (Status e : values()) {
+                if (e.getValue().toUpperCase().equals(value.toUpperCase())) {
+                    return e;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private String value;
+
+    private Status(String valueToUse) {
+        value = valueToUse;
+    }
+
+    public final String getValue() {
+        return value;
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.onap.appc.listener.Controller;
+import org.onap.appc.listener.Listener;
+import org.onap.appc.listener.ListenerProperties;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+
+/**
+ * A common implementation of a controller. This controller should not need to be modified to implement new listeners
+ *
+ */
+public class ControllerImpl implements Controller {
+
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(ControllerImpl.class);
+
+    private int LISTENER_COUNT = 1;
+
+    private Map<ListenerProperties, Listener> listeners = null;
+
+    private ThreadPoolExecutor executor;
+
+    /**
+     * Creates a Controller with the set of listener properties which will be used to start listener threads.
+     *
+     * @param properties
+     *            A non null Set of ListenerProperties
+     */
+    public ControllerImpl(Set<ListenerProperties> properties) {
+        listeners = new HashMap<ListenerProperties, Listener>();
+        for (ListenerProperties props : properties) {
+            if (props.getListenerClass() != null) {
+                listeners.put(props, null);
+            } else {
+                LOG.error(String.format(
+                    "The ListenerProperties %s has no Listener class associated with it and will not run.", props));
+                properties.remove(props);
+            }
+        }
+
+        LISTENER_COUNT = properties.size();
+
+        // Only create executor if listeners are configured
+        if (LISTENER_COUNT > 0) {
+        executor = new ThreadPoolExecutor(LISTENER_COUNT, LISTENER_COUNT, 1, TimeUnit.SECONDS,
+            new ArrayBlockingQueue<Runnable>(LISTENER_COUNT));
+
+        // Custom Named thread factory
+        BasicThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("Appc-Listener-%d").build();
+        executor.setThreadFactory(threadFactory);
+        }
+    }
+
+    @Override
+    public void start() {
+        LOG.info("Starting DMaaP Controller.");
+        for (ListenerProperties props : listeners.keySet()) {
+            try {
+                if (props.isDisabled()) {
+                    LOG.warn(String.format("The listener %s is disabled and will not be run", props.getPrefix()));
+                } else {
+                    Listener l = props.getListenerClass().getConstructor(ListenerProperties.class).newInstance(props);
+                    l.setListenerId(props.getPrefix());
+                    listeners.put(props, l);
+                    executor.execute(l);
+                }
+            } catch (Exception e) {
+                LOG.error(String.format("Exception while starting listener %s.", props), e);
+            }
+        }
+    }
+
+    @Override
+    public void stop(boolean stopNow) {
+        LOG.info("Stopping DMaaP Controller.");
+        Iterator<Listener> itr = listeners.values().iterator();
+        while (itr.hasNext()) {
+            Listener l = itr.next();
+            if (stopNow && l != null) {
+                l.stopNow();
+            } else if(l != null){
+                l.stop();
+            }
+            itr.remove();
+        }
+        // disable new tasks from being submitted
+        if(executor != null) {
+            executor.shutdown();
+            int timeout = 300;
+            try {
+                if (!executor.awaitTermination(timeout, TimeUnit.SECONDS)) {
+                    LOG.error("Not all tasks completed execution after " + timeout + " seconds. " +
+                            "Attempting to stop all actively executing tasks.");
+                    executor.shutdownNow();
+                }
+                if (!executor.awaitTermination(timeout, TimeUnit.SECONDS)) {
+                    LOG.error("Could not terminate all tasks after " + (timeout * 2) + " seconds.");
+                }
+            } catch (InterruptedException e) {
+                executor.shutdownNow();
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
+    @Override
+    public Map<ListenerProperties, Listener> getListeners() {
+        return listeners;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.impl;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import org.onap.appc.adapter.factory.MessageService;
+import org.onap.appc.adapter.message.Consumer;
+import org.onap.appc.adapter.message.Producer;
+import org.onap.appc.adapter.messaging.dmaap.http.HttpDmaapConsumerImpl;
+import org.onap.appc.adapter.messaging.dmaap.http.HttpDmaapProducerImpl;
+import org.onap.appc.listener.EventHandler;
+import org.onap.appc.listener.ListenerProperties;
+import org.onap.appc.listener.util.Mapper;
+import org.onap.appc.logging.LoggingConstants;
+import org.slf4j.MDC;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * This class is a wrapper for the DMaaP client provided in appc-dmaap-adapter. Its aim is to ensure
+ * that only well formed messages are sent and received on DMaaP.
+ */
+public class EventHandlerImpl implements EventHandler {
+
+    private final EELFLogger LOG = EELFManager.getInstance().getLogger(EventHandlerImpl.class);
+
+    /*
+     * The amount of time in seconds to keep a connection to a topic open while waiting for data
+     */
+    private int READ_TIMEOUT = 60;
+
+    /*
+     * The pool of hosts to query against
+     */
+    private Collection<String> pool;
+
+    /*
+     * The topic to read messages from
+     */
+    private String readTopic;
+
+    /*
+     * The topic to write messages to
+     */
+    private String writeTopic;
+
+    /*
+     * The client (group) name to use for reading messages
+     */
+    private String clientName;
+
+    /*
+     * The id of the client (group) that is reading messages
+     */
+    private String clientId;
+
+    /*
+     * The api public key to use for authentication
+     */
+    private String apiKey;
+
+    /*
+     * The api secret key to use for authentication
+     */
+    private String apiSecret;
+
+    /*
+     * A json object containing filter arguments.
+     */
+    private String filter_json;
+
+
+    /*
+     * Blacklist time for a server with response problem in seconds
+     */
+    private String responseProblemBlacklistTime;
+
+    /*
+     *  Blacklist time for a server with server problem in seconds
+     */
+    private String serverProblemBlacklistTime;
+
+    /*
+     * Blacklist time for a server with DNS problem in seconds
+     */
+    private String dnsIssueBlacklistTime;
+
+    /*
+     * Blacklist time for a server with IO Exception problem in seconds
+     */
+    private String ioExceptionBlacklistTime;
+
+    private MessageService messageService;
+
+    private Consumer reader = null;
+    private Producer producer = null;
+
+    public EventHandlerImpl(ListenerProperties props) {
+        pool = new HashSet<>();
+
+        if (props != null) {
+            readTopic = props.getProperty(ListenerProperties.KEYS.TOPIC_READ);
+            clientName = props.getProperty(ListenerProperties.KEYS.CLIENT_NAME, "APP-C");
+            clientId = props.getProperty(ListenerProperties.KEYS.CLIENT_ID, "0");
+            apiKey = props.getProperty(ListenerProperties.KEYS.AUTH_USER_KEY);
+            apiSecret = props.getProperty(ListenerProperties.KEYS.AUTH_SECRET_KEY);
+            responseProblemBlacklistTime = props.getProperty(ListenerProperties.KEYS.PROBLEM_WITH_RESPONSE_BLACKLIST_TIME);
+            serverProblemBlacklistTime = props.getProperty(ListenerProperties.KEYS.PROBLEM_SERVERSIDE_ERROR_BLACKLIST_TIME);
+            dnsIssueBlacklistTime = props.getProperty(ListenerProperties.KEYS.PROBLEM_DNS_BLACKLIST_TIME);
+            ioExceptionBlacklistTime = props.getProperty(ListenerProperties.KEYS.PROBLEM_IO_EXCEPTION_BLACKLIST_TIME);
+
+            filter_json = props.getProperty(ListenerProperties.KEYS.TOPIC_READ_FILTER);
+
+            READ_TIMEOUT = Integer
+                    .valueOf(props.getProperty(ListenerProperties.KEYS.TOPIC_READ_TIMEOUT, String.valueOf(READ_TIMEOUT)));
+
+            String hostnames = props.getProperty(ListenerProperties.KEYS.HOSTS);
+            if (hostnames != null && !hostnames.isEmpty()) {
+                for (String name : hostnames.split(",")) {
+                    pool.add(name);
+                }
+            }
+
+            String writeTopicStr = props.getProperty(ListenerProperties.KEYS.TOPIC_WRITE);
+            if (writeTopicStr != null) {
+                for (String topic : writeTopicStr.split(",")) {
+                    writeTopic = topic;
+                }
+            }
+
+            messageService = MessageService.parse(props.getProperty(ListenerProperties.KEYS.MESSAGE_SERVICE));
+
+            LOG.info(String.format(
+                    "Configured to use %s client on host pool [%s]. Reading from [%s] filtered by %s. Writing to [%s]. Authenticated using %s",
+                    messageService, hostnames, readTopic, filter_json, writeTopic, apiKey));
+        }
+    }
+
+    @Override
+    public List<String> getIncomingEvents() {
+        return getIncomingEvents(1000);
+    }
+
+    @Override
+    public List<String> getIncomingEvents(int limit) {
+        List<String> out = new ArrayList<>();
+        LOG.info(String.format("Getting up to %d incoming events", limit));
+        // reuse the consumer object instead of creating a new one every time
+        if (reader == null) {
+            LOG.info("Getting Consumer...");
+            reader = getConsumer();
+        }
+        if (reader != null) {
+            List<String> items = reader.fetch(READ_TIMEOUT * 1000, limit);
+            for (String item : items) {
+                out.add(item);
+            }
+        }
+        LOG.info(String.format("Read %d messages from %s as %s/%s.", out.size(), readTopic, clientName, clientId));
+        return out;
+    }
+
+    @Override
+    public <T> List<T> getIncomingEvents(Class<T> cls) {
+        return getIncomingEvents(cls, 1000);
+    }
+
+    @Override
+    public <T> List<T> getIncomingEvents(Class<T> cls, int limit) {
+        List<String> incomingStrings = getIncomingEvents(limit);
+        return Mapper.mapList(incomingStrings, cls);
+    }
+
+    @Override
+    public void postStatus(String event) {
+        postStatus(null, event);
+    }
+
+    @Override
+    public void postStatus(String partition, String event) {
+        LOG.debug(String.format("Posting Message [%s]", event));
+        if (producer == null) {
+            LOG.info("Getting Producer...");
+            producer = getProducer();
+        }
+        producer.post(partition, event);
+    }
+
+    /**
+     * Returns a consumer object for direct access to our Cambria consumer interface
+     *
+     * @return An instance of the consumer interface
+     */
+    protected Consumer getConsumer() {
+        LOG.debug(String.format("Getting Consumer: %s  %s/%s/%s", pool, readTopic, clientName, clientId));
+        if (filter_json == null && writeTopic.equals(readTopic)) {
+            LOG.error(
+                    "*****We will be writing and reading to the same topic without a filter. This will cause an infinite loop.*****");
+        }
+
+        Consumer out = null;
+        out = new HttpDmaapConsumerImpl(pool, readTopic, clientName, clientId, filter_json, apiKey, apiSecret);
+
+                    if (out != null && responseProblemBlacklistTime != null && responseProblemBlacklistTime.length() > 0)
+                    {
+                        out.setResponseProblemBlacklistTime(responseProblemBlacklistTime);
+                    }
+
+                    if (out != null && serverProblemBlacklistTime != null && serverProblemBlacklistTime.length() > 0)
+                    {
+                        out.setServerProblemBlacklistTime(serverProblemBlacklistTime);
+                    }
+
+                    if (out != null && dnsIssueBlacklistTime != null && dnsIssueBlacklistTime.length() > 0)
+                    {
+                        out.setDnsIssueBlacklistTime(dnsIssueBlacklistTime);
+                    }
+
+                    if (out != null && ioExceptionBlacklistTime != null && ioExceptionBlacklistTime.length() > 0)
+                    {
+                        out.setIOExceptionBlacklistTime(ioExceptionBlacklistTime);
+                    }
+                if (out != null) {
+                    for (String url : pool) {
+                        if (url.contains("3905") || url.contains("https")) {
+                            out.useHttps(true);
+                            break;
+                        }
+                    }
+                }
+        return out;
+    }
+
+    /**
+     * Returns a consumer object for direct access to our Cambria producer interface
+     *
+     * @return An instance of the producer interface
+     */
+    protected Producer getProducer() {
+        LOG.debug(String.format("Getting Producer: %s  %s", pool, readTopic));
+
+        Producer out = null;
+        out = new HttpDmaapProducerImpl(pool, writeTopic, apiKey, apiSecret);
+                if (out != null && responseProblemBlacklistTime != null && responseProblemBlacklistTime.length() > 0)
+                {
+                    out.setResponseProblemBlacklistTime(responseProblemBlacklistTime);
+                }
+
+                if (out != null && serverProblemBlacklistTime != null && serverProblemBlacklistTime.length() > 0)
+                {
+                    out.setServerProblemBlacklistTime(serverProblemBlacklistTime);
+                }
+
+                if (out != null && dnsIssueBlacklistTime != null && dnsIssueBlacklistTime.length() > 0)
+                {
+                    out.setDnsIssueBlacklistTime(dnsIssueBlacklistTime);
+                }
+
+                if (out != null && ioExceptionBlacklistTime != null && ioExceptionBlacklistTime.length() > 0)
+                {
+                    out.setIOExceptionBlacklistTime(ioExceptionBlacklistTime);
+                }
+                if (out != null) {
+                    for (String url : pool) {
+                        if (url.contains("3905") || url.contains("https")) {
+                            out.useHttps(true);
+                            break;
+                        }
+                    }
+                }
+        return out;
+    }
+
+    @Override
+    public void closeClients() {
+        LOG.debug("Closing Consumer and Producer DMaaP clients");
+        if (reader != null) {
+            reader.close();
+        }
+        if (producer != null) {
+            producer.close();
+        }
+    }
+
+    @Override
+    public String getClientId() {
+        return clientId;
+    }
+
+    @Override
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    @Override
+    public String getClientName() {
+        return clientName;
+    }
+
+    @Override
+    public void setClientName(String clientName) {
+        this.clientName = clientName;
+        MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, clientName);
+    }
+
+    @Override
+    public void addToPool(String hostname) {
+        pool.add(hostname);
+    }
+
+    @Override
+    public Collection<String> getPool() {
+        return pool;
+    }
+
+    @Override
+    public void removeFromPool(String hostname) {
+        pool.remove(hostname);
+    }
+
+    @Override
+    public String getReadTopic() {
+        return readTopic;
+    }
+
+    @Override
+    public void setReadTopic(String readTopic) {
+        this.readTopic = readTopic;
+    }
+
+    @Override
+    public String getWriteTopic() {
+        return writeTopic;
+    }
+
+    @Override
+    public void setWriteTopic(String writeTopic) {
+        this.writeTopic = writeTopic;
+    }
+
+    @Override
+    public void setResponseProblemBlacklistTime(String duration){
+        this.responseProblemBlacklistTime = duration;
+    }
+
+    @Override
+    public void setServerProblemBlacklistTime(String duration){
+        this.serverProblemBlacklistTime = duration;
+    }
+
+    @Override
+    public void setDnsIssueBlacklistTime(String duration){
+        this.dnsIssueBlacklistTime = duration;
+    }
+
+    @Override
+    public void setIOExceptionBlacklistTime(String duration){
+        this.ioExceptionBlacklistTime = duration;
+    }
+
+    @Override
+    public void clearCredentials() {
+        apiKey = null;
+        apiSecret = null;
+    }
+
+    @Override
+    public void setCredentials(String key, String secret) {
+        apiKey = key;
+        apiSecret = secret;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.util;
+
+import java.io.IOException;
+import java.net.Socket;
+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 javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import org.apache.http.HttpVersion;
+import org.apache.http.client.HttpClient;
+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.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.onap.appc.exceptions.APPCException;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+@SuppressWarnings("deprecation")
+public class HttpClientUtil {
+  
+  private static final EELFLogger log = EELFManager.getInstance().getLogger(HttpClientUtil.class);
+
+  public static HttpClient getHttpClient(String protocol) throws APPCException {
+    HttpClient client;
+    if ("https".equals(protocol)) {
+      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) {
+        log.info("Creating Default Http Client with no params " + e.getMessage(), e);
+        client = new DefaultHttpClient();
+      }
+    } else if ("http".equals(protocol)) {
+      client = new DefaultHttpClient();
+    } else {
+      throw new APPCException(
+          "The provider.topology.url property is invalid. The url did not start with http[s]");
+    }
+    return client;
+  }
+
+  private static class MySSLSocketFactory extends SSLSocketFactory {
+    private SSLContext sslContext = SSLContext.getInstance("TLS");
+
+    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();
+    }
+  }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.util;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.json.JSONObject;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class Mapper {
+
+    private static final EELFLogger LOG = EELFManager.getInstance().getLogger(Mapper.class);
+
+    private static ObjectMapper mapper = new ObjectMapper();
+
+    /**
+     * @return The object mapper that we are using.
+     */
+    public static ObjectMapper getMapper() {
+        return mapper;
+    }
+
+    /**
+     * Convert a String to a DcaeMessage
+     * 
+     * @param data
+     *            The json string to try and parse
+     * @return A DcaeMessage from the json string or null if it could not
+     */
+    public static <T> T mapOne(String data, Class<T> cls) {
+        try {
+            return mapper.readValue(data, cls);
+        } catch (Exception e) {
+            LOG.warn(String.format("Could not map [ %s ] to %s", data, cls.getName()), e);
+            return null;
+        }
+    }
+
+    public static <T> List<T> mapList(List<String> data, Class<T> cls) {
+        List<T> out = new ArrayList<T>();
+        for (String s : data) {
+            T tmp = Mapper.mapOne(s, cls);
+            if (tmp != null) {
+                out.add(tmp);
+            }
+        }
+        return out;
+    }
+
+    /**
+     * Convenience method to try and convert objects to json String
+     * 
+     * @param obj
+     *            The object to try and convert
+     * @return A json string representing the object or null if it could not be converted
+     */
+    public static String toJsonString(Object obj) {
+        String jsonStr;
+        try {
+            if (obj instanceof JSONObject) {
+                jsonStr = obj.toString();
+            }else {
+                jsonStr = mapper.writeValueAsString(obj);
+            }
+            return jsonStr;
+        } catch (Exception e) {
+            LOG.warn(String.format("Could not map %s to JSONObject.", obj), e);
+            return null;
+        }
+    }
+
+    public static JSONObject toJsonObject(Object obj) {
+        String jsonStr;
+        try {
+            if (obj.getClass().equals(String.class)) {
+                jsonStr = (String) obj;
+            } else {
+                jsonStr = mapper.writeValueAsString(obj);
+            }
+            return new JSONObject(jsonStr);
+        } catch (Exception e) {
+            LOG.warn(String.format("Could not map %s to JSONObject.", obj), e);
+            return null;
+        }
+    }
+    public static JsonNode toJsonNodeFromJsonString(String jsonStr) {
+        JsonNode jsonNode = null;
+        if(jsonStr != null) {
+            try {
+                jsonNode = mapper.readTree(jsonStr);
+            } catch (IOException e) {
+                LOG.warn(String.format("Could not map %s to jsonNode.", jsonStr), e);
+            }
+        }
+        return jsonNode;
+    }
+    public static JsonNode toJsonNode(Object obj) {
+        JsonNode jsonNode = null;
+        String jsonStr = toJsonString(obj);
+        if(jsonStr != null) {
+            try {
+                jsonNode = mapper.readTree(jsonStr);
+            } catch (IOException e) {
+                LOG.warn(String.format("Could not map %s to JSONObject.", obj), e);
+            }
+        }
+        return jsonNode;
+    }
+}
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+# ${user.home} usually goes to /root if instantiation uses the appc-docker approach
+
+###                                                                                                                                                                     ###
+###                                                                                                                                                                     ###
+###Properties below that are commented out are/need to be provided in appc.properties###
+###                                                                                                                                                                     ###
+###                                                                                                                                                                     ###
+
+
+
+
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options
+org.onap.appc.bootstrap.file=appc.properties
+org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},.
+
+
+
+
+
+###                                                    ###
+###Closed Loop - properties ###
+###                                                    ###
+appc.ClosedLoop.poolMembers=192.168.1.2:3904
+appc.ClosedLoop.topic.read=APPC-TEST2
+appc.ClosedLoop.topic.write=APPC-TEST2
+appc.ClosedLoop.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]}
+appc.ClosedLoop.client.name=APPC-TEST-CLIENT-EVT-LST-MAIN
+appc.ClosedLoop.client.name.id=0
+
+# KEY AND SECRET BELOW NEED TO BE MODIFIED TO APPROPRIATE VALUES WHEN THE TOPIC IS API-KEY-BASED AUTH
+#dmaap.client.key=random
+#dmaap.client.secret=random
+
+appc.ClosedLoop.threads.queuesize.min=1
+appc.ClosedLoop.threads.queuesize.max=1000
+appc.ClosedLoop.threads.poolsize.min=1
+appc.ClosedLoop.threads.poolsize.max=2
+appc.ClosedLoop.provider.url=http://localhost:8181/restconf/operations/appc-provider
+appc.ClosedLoop.provider.url.user=ODL_USER
+appc.ClosedLoop.provider.url.pass=ODL_PASS
+
+
+
+
+
+###                                                          ###
+###Closed Loop - 1607 properties  ###
+###                                                              ###
+appc.ClosedLoop1607.poolMembers=192.168.1.2:3904
+appc.ClosedLoop1607.topic.read=MY_DMAAP_TOPIC
+appc.ClosedLoop1607.topic.write=MY_DMAAP_TOPIC
+appc.ClosedLoop1607.topic.read.filter={"class":"Unassigned","field":"Status"}
+appc.ClosedLoop1607.client.name=MY_DMAAP_CLIENT_NAME
+appc.ClosedLoop1607.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+appc.ClosedLoop1607.threads.queuesize.min=1
+appc.ClosedLoop1607.threads.queuesize.max=1000
+appc.ClosedLoop1607.threads.poolsize.min=1
+appc.ClosedLoop1607.threads.poolsize.max=2
+appc.ClosedLoop.provider.user=ODL_USER
+appc.ClosedLoop.provider.pass=ODL_PASS
+appc.ClosedLoop1607.provider.url=http://localhost:8181/restconf/operations/appc-provider
+
+
+
+
+
+###                                                                                                                                                                               ###
+### This needs to be changed so that the action can be appended to the end of the URL path ###
+###                                                                                                                                                                               ###
+appc.LCM.provider.url=http://localhost:8181/restconf/operations/appc-provider
+appc.LCM.poolMembers=127.0.0.1:3001
+appc.LCM.topic.read=DMAAP_TOPIC
+appc.LCM.topic.write=DMAAP_TOPIC
+appc.LCM.client.name=DMAAP_CLIENT_NAME
+appc.LCM.provider.user=ODL_USER
+appc.LCM.provider.pass=ODL_URL
+
+appc.demo.poolMembers=127.0.0.1:3002
+appc.demo.topic.read=APPC-CL
+appc.demo.topic.write=APPC-CL
+appc.demo.client.name=appcDemoEventListener
+appc.demo.threads.queuesize.min=1
+appc.demo.threads.queuesize.max=1000
+appc.demo.threads.poolsize.min=1
+appc.demo.threads.poolsize.max=2
+appc.demo.provider.user=admin
+appc.demo.provider.pass=Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U
+appc.demo.provider.url=http://192.168.55.12:8282/restconf/operations/appc-provider
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Properties;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import java.util.concurrent.TimeUnit;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.appc.listener.AbstractListener;
+import org.onap.appc.listener.ListenerProperties;
+
+public class AbstractListenerTest {
+
+    private DummyListener listener;
+    private ListenerProperties props;
+
+    @Before
+    public void setup() throws Exception {
+        Properties regularProps = new Properties();
+        regularProps.load(getClass().getResourceAsStream("/org/onap/appc/default.properties"));
+        props = new ListenerProperties("", regularProps);
+        listener = new DummyListener(props);
+    }
+
+    @Test
+    public void stop_should_shutdown_executor() {
+
+        EventHandler mockEventHandler = mock(EventHandler.class);
+        listener.setEventHandler(mockEventHandler);
+
+        Thread thread = new Thread(listener);
+        thread.start();
+
+        assertTrue(thread.isAlive());
+        assertTrue(listener.getRun());
+        assertFalse(listener.getExecutor().isShutdown());
+        assertFalse(listener.getExecutor().isTerminated());
+
+        listener.stop();
+
+        assertFalse(listener.getRun());
+        assertTrue(listener.getExecutor().isShutdown());
+        assertTrue(listener.getExecutor().isTerminated());
+
+        verify(mockEventHandler).closeClients();
+
+    }
+
+    @Test
+    public void stopNow_should_clear_executors_queue_and_call_stop() throws InterruptedException {
+        EventHandler mockEventHandler = mock(EventHandler.class);
+        listener.setEventHandler(mockEventHandler);
+
+        ThreadPoolExecutor mockExecutor = mock(ThreadPoolExecutor.class);
+        BlockingQueue<Runnable> mockBlockingQueue = mock(BlockingQueue.class);
+        listener.setExecutor(mockExecutor);
+        when(mockExecutor.getQueue()).thenReturn(mockBlockingQueue);
+
+        Thread thread = new Thread(listener);
+        thread.start();
+
+        assertTrue(thread.isAlive());
+        assertTrue(listener.getRun());
+
+        listener.stopNow();
+
+        assertFalse(listener.getRun());
+        verify(mockExecutor).shutdown();
+        verify(mockExecutor).awaitTermination(anyLong(), any(TimeUnit.class));
+        verify(mockBlockingQueue).clear();
+        verify(mockEventHandler).closeClients();
+    }
+
+    @Test
+    public void getBenchmark_result_should_contain_listenerId() {
+        String out = listener.getBenchmark();
+        assertNotNull(out);
+        assertTrue(out.contains(listener.getListenerId()));
+    }
+
+    @Test
+    public void getListenerId_should_return_properties_prefix_by_default() {
+        assertEquals(props.getPrefix(), listener.getListenerId());
+        listener.setListenerId("newId");
+        assertEquals("newId", listener.getListenerId());
+    }
+
+
+    private class DummyListener extends AbstractListener {
+
+        DummyListener(ListenerProperties props) {
+            super(props);
+        }
+
+        boolean getRun() {
+            return run.get();
+        }
+
+        public ThreadPoolExecutor getExecutor() {
+            return executor;
+        }
+
+        void setEventHandler(EventHandler eventHandler){
+            dmaap = eventHandler;
+        }
+
+        void setExecutor(ThreadPoolExecutor executor){
+            this.executor = executor;
+        }
+
+        @Override
+        public void run() {
+
+            while (run.get()) {
+            }
+        }
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static org.mockito.Mockito.doReturn;
+
+import org.onap.appc.listener.AppcEventListenerActivator;
+
+public class AppcEventListenerActivatorTest {
+
+    @Test
+    public void testStartStopDefaultProperties() {
+        AppcEventListenerActivator appc = new AppcEventListenerActivator();
+        try {
+            appc.start();
+            Thread.sleep(1000);
+            appc.stop();
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+        assertNotNull(appc.getName());
+    }
+
+    @Test
+    public void testStartStopEmptyProperties() {
+        InputStream input = getClass().getResourceAsStream("/org/onap/appc/empty.properties");
+        Properties props = new Properties();
+        try {
+            props.load(input);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        AppcEventListenerActivator appc = new AppcEventListenerActivator();
+        AppcEventListenerActivator spyAppc = Mockito.spy(appc);
+        doReturn(props).when(spyAppc).getProperties();
+
+        try {
+            spyAppc.start();
+            Thread.sleep(1000);
+            spyAppc.stop();
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+        assertNotNull(spyAppc.getName());
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.conv;
+
+import static org.junit.Assert.assertEquals;
+import static org.onap.appc.listener.TestUtil.JSON_INPUT_BODY_STR;
+import static org.onap.appc.listener.TestUtil.JSON_OUTPUT_BODY_STR;
+import static org.onap.appc.listener.TestUtil.buildDmaapIncomingMessage;
+import static org.onap.appc.listener.TestUtil.buildDmaapOutgoingMessage;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import org.junit.Test;
+import org.onap.appc.listener.LCM.model.DmaapIncomingMessage;
+import org.onap.appc.listener.LCM.model.DmaapOutgoingMessage;
+import org.onap.appc.listener.util.Mapper;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+public class ConverterTest {
+
+    private static final String EXPECTED_DMAAP_OUTGOING_MESSAGE_AS_JSON_STRING =
+        "{\"body\":{\"output\":{\"common-header\":"
+            + "{\"timestamp\":\"2016-08-03T08:50:18.97Z\",\"api-ver\":\"1\",\"flags\":{\"force\":\"TRUE\",\"ttl\":\"9900\"},"
+            + "\"sub-request-id\":\"1\",\"request-id\":\"123\",\"originator-id\":\"1\"},\"locked\":\"test-locked\",\""
+            + "status\":{\"message\":\"test message\",\"code\":200}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"test\"}";
+
+    @Test(expected = IllegalArgumentException.class)
+    public void convertJsonNodeToDmaapOutgoingMessage_should_throw_when_given_null_arguments() {
+
+        Converter.convertJsonNodeToDmaapOutgoingMessage(null, null);
+    }
+
+    @Test
+    public void convertJsonNodeToDmaapOutgoingMessage_should_convert_to_outgoing_message() {
+
+        DmaapIncomingMessage message = new DmaapIncomingMessage();
+        message.setRpcName("test");
+        message.setCorrelationID("test-1");
+        message.setVersion("v1");
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_INPUT_BODY_STR);
+        message.setBody(jsonNode);
+
+        DmaapOutgoingMessage result = Converter.convertJsonNodeToDmaapOutgoingMessage(message, jsonNode);
+
+        assertEquals("test", result.getRpcName());
+        assertEquals("test-1", result.getCorrelationID());
+        assertEquals("v1", result.getVersion());
+        assertEquals(jsonNode, result.getBody());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void convertDmaapOutgoingMessageToJsonString_should_throw_when_given_null_arguments()
+        throws JsonProcessingException {
+
+        Converter.convertDmaapOutgoingMessageToJsonString(null);
+    }
+
+    @Test
+    public void convertDmaapOutgoingMessageToJsonString_should_return_converted_json_string()
+        throws JsonProcessingException {
+
+        DmaapOutgoingMessage message = new DmaapOutgoingMessage();
+        message.setRpcName("test");
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_OUTPUT_BODY_STR);
+        message.setBody(jsonNode);
+
+        assertEquals(EXPECTED_DMAAP_OUTGOING_MESSAGE_AS_JSON_STRING,
+            Converter.convertDmaapOutgoingMessageToJsonString(message));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void buildDmaapOutgoingMessageWithUnexpectedErrorTest_should_throw_given_null_arguments()
+        throws JsonProcessingException {
+
+        Converter.buildDmaapOutgoingMessageWithUnexpectedError(null, null);
+    }
+
+    @Test
+    public void buildDmaapOutgoingMessageWithUnexpectedErrorTest_should_build_valid_outgoing_message()
+        throws JsonProcessingException {
+
+        DmaapIncomingMessage dmaapIncomingMessage = buildDmaapIncomingMessage();
+        String errMsg = "TestException";
+        DmaapOutgoingMessage dmaapOutgoingMessage = Converter
+            .buildDmaapOutgoingMessageWithUnexpectedError(dmaapIncomingMessage, new Exception(errMsg));
+        int code = dmaapOutgoingMessage.getBody().get("output").get("status").get("code").asInt();
+        String value = dmaapOutgoingMessage.getBody().get("output").get("status").get("value").asText();
+        assertEquals(200, code);
+        assertEquals(errMsg, value);
+    }
+
+
+    @Test(expected = IllegalArgumentException.class)
+    public void extractRequestIdWithSubId_should_throw_given_null_argument() throws SvcLogicException {
+
+        Converter.extractRequestIdWithSubId(null);
+    }
+
+    @Test
+    public void extractRequestIdWithSubIdTest_should_extract_id_with_subDd() throws SvcLogicException {
+        DmaapIncomingMessage dmaapIncomingMessage = buildDmaapIncomingMessage();
+
+        String requestIdWithSubId = Converter.extractRequestIdWithSubId(dmaapIncomingMessage.getBody());
+        assertEquals("123-1", requestIdWithSubId);
+    }
+
+
+    @Test(expected = IllegalArgumentException.class)
+    public void extractStatusCode_should_throw_given_null_argument() {
+        Converter.extractStatusCode(null);
+    }
+
+
+    @Test
+    public void extractStatusCode_should_extract_valid_status_code() {
+        DmaapOutgoingMessage dmaapOutgoingMessage = buildDmaapOutgoingMessage();
+        Integer statusCode = Converter.extractStatusCode(dmaapOutgoingMessage.getBody());
+        assertEquals(200L, statusCode.longValue());
+    }
+
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM.impl;
+
+import static org.junit.Assert.fail;
+
+import java.util.Properties;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onap.appc.listener.Listener;
+import org.onap.appc.listener.ListenerProperties;
+import org.onap.appc.listener.demo.impl.ListenerImpl;
+
+@Ignore
+public class ListenerImplTest {
+
+    private static final String PROP_FILE = "/org/onap/appc/default.properties";
+
+    private Listener listener;
+    private Properties props;
+
+    @Before
+    public void setup() {
+        props = new Properties();
+        try {
+            props.load(getClass().getResourceAsStream(PROP_FILE));
+            props.setProperty("topic.read", "DCAE-CLOSED-LOOP-EVENTS-DEV1510SIM");
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail("Failed to setup test: " + e.getMessage());
+        }
+        listener = new ListenerImpl(new ListenerProperties("appc.ClosedLoop", props));
+    }
+
+    @Test
+    public void testRun() {
+        try {
+            Thread t = new Thread(listener);
+            t.start();
+
+            Thread.sleep(5000);
+
+            listener.stopNow();
+
+            System.out.println(listener.getBenchmark());
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void printSampleData() {
+        try {
+            props.setProperty("threads.queuesize.min", "1");
+            props.setProperty("threads.queuesize.max", "1");
+            props.setProperty("threads.poolsize.min", "1");
+            props.setProperty("threads.poolsize.max", "1");
+
+            Thread t = new Thread(listener);
+            t.start();
+
+            Thread.sleep(2000);
+
+            listener.stop();
+
+            System.out.println(listener.getBenchmark());
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.impl;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.onap.appc.listener.TestUtil.JSON_OUTPUT_BODY_STR;
+import static org.onap.appc.listener.TestUtil.buildDmaapMessage;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.junit.Test;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.EventHandler;
+import org.onap.appc.listener.LCM.operation.ProviderOperations;
+import org.onap.appc.listener.util.Mapper;
+
+public class WorkerImplTest {
+
+    private EventHandler mockEventHandler = mock(EventHandler.class);
+    private ProviderOperations mockProviderOperations = mock(ProviderOperations.class);
+
+
+    @Test(expected = IllegalStateException.class)
+    public void should_throw_when_one_of_worker_fields_is_null() {
+
+        WorkerImpl worker = new WorkerImpl(null, mockEventHandler, mockProviderOperations);
+        worker.run();
+    }
+
+    @Test
+    public void should_post_error_message_to_dmaap_on_exception() throws APPCException {
+
+        when(mockProviderOperations.topologyDG(anyString(), any(JsonNode.class)))
+            .thenThrow(new RuntimeException("test exception"));
+
+        WorkerImpl worker = new WorkerImpl(buildDmaapMessage(), mockEventHandler, mockProviderOperations);
+        worker.run();
+
+        verify(mockEventHandler).postStatus(anyString(), anyString());
+    }
+
+
+    @Test
+    public void should_post_message_to_dmaap_on_successful_run() throws APPCException {
+
+        JsonNode testOutputJsonNode = Mapper.toJsonNodeFromJsonString(JSON_OUTPUT_BODY_STR);
+        when(mockProviderOperations.topologyDG(anyString(), any(JsonNode.class)))
+            .thenReturn(testOutputJsonNode);
+
+        WorkerImpl worker = new WorkerImpl(buildDmaapMessage(), mockEventHandler, mockProviderOperations);
+        worker.run();
+
+        verify(mockEventHandler).postStatus(anyString(), anyString());
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.model;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class ActionIdentifiersTest {
+
+    private ActionIdentifiers actionIdentifiers;
+
+
+    @Before
+    public void setup(){
+        actionIdentifiers = new ActionIdentifiers();
+    }
+
+    @Test
+    public void should_set_properties(){
+
+        actionIdentifiers.setServiceInstanceId("test-instance-id");
+        actionIdentifiers.setVnfID("test-vnf-id");
+        actionIdentifiers.setVnfcName("test-name");
+        actionIdentifiers.setVserverId("test-vserver-id");
+
+
+        assertEquals("test-instance-id", actionIdentifiers.getServiceInstanceId());
+        assertEquals("test-vnf-id", actionIdentifiers.getVnfID());
+        assertEquals("test-name", actionIdentifiers.getVnfcName());
+        assertEquals("test-vserver-id", actionIdentifiers.getVserverId());
+    }
+
+    @Test
+    public void should_initialize_parameters_from_constructor(){
+
+        actionIdentifiers.setServiceInstanceId("test-instance-id");
+        actionIdentifiers.setVnfID("test-vnf-id");
+        actionIdentifiers.setVnfcName("test-name");
+        actionIdentifiers.setVserverId("test-vserver-id");
+
+        ActionIdentifiers testObject = new ActionIdentifiers(actionIdentifiers);
+
+        assertEquals("test-instance-id", testObject.getServiceInstanceId());
+        assertEquals("test-vnf-id",  testObject.getVnfID());
+        assertEquals("test-name",  testObject.getVnfcName());
+        assertEquals("test-vserver-id",  testObject.getVserverId());
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CommonHeaderTest {
+
+    private CommonHeader commonHeader;
+
+    @Before
+    public void setup() {
+        commonHeader = new CommonHeader();
+    }
+
+    @Test
+    public void should_set_properties() {
+
+        commonHeader.setTimeStamp("test-timestamp");
+        commonHeader.setApiVer("test-api-version");
+        commonHeader.setOriginatorId("test-originator-id");
+        commonHeader.setRequestID("test-request-id");
+        commonHeader.setSubRequestId("test-subrequest-id");
+
+        Map<String, String> flags = new HashMap<>();
+        flags.put("key1", "flag1");
+        flags.put("key2", "flag2");
+        flags.put("key3", "flag3");
+
+        commonHeader.setFlags(flags);
+
+        assertEquals("test-timestamp", commonHeader.getTimeStamp());
+        assertEquals("test-api-version", commonHeader.getApiVer());
+        assertEquals("test-originator-id", commonHeader.getOriginatorId());
+        assertEquals("test-request-id", commonHeader.getRequestID());
+        assertEquals("test-subrequest-id", commonHeader.getSubRequestId());
+        assertEquals(flags, commonHeader.getFlags());
+    }
+
+    @Test
+    public void should_initialize_parameters_from_constructor() {
+
+        commonHeader.setTimeStamp("test-timestamp");
+        commonHeader.setApiVer("test-api-version");
+        commonHeader.setOriginatorId("test-originator-id");
+        commonHeader.setRequestID("test-request-id");
+        commonHeader.setSubRequestId("test-subrequest-id");
+
+        Map<String, String> flags = new HashMap<>();
+        flags.put("key1", "flag1");
+        flags.put("key2", "flag2");
+        flags.put("key3", "flag3");
+
+        commonHeader.setFlags(flags);
+
+        CommonHeader testObject = new CommonHeader(commonHeader);
+
+        assertNotEquals(commonHeader.getTimeStamp(), testObject.getTimeStamp());
+        assertEquals(commonHeader.getApiVer(), testObject.getApiVer());
+        assertEquals(commonHeader.getOriginatorId(), testObject.getOriginatorId());
+        assertEquals(commonHeader.getRequestID(), testObject.getRequestID());
+        assertEquals(commonHeader.getSubRequestId(), testObject.getSubRequestId());
+        assertEquals(commonHeader.getFlags(), testObject.getFlags());
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.onap.appc.listener.TestUtil.JSON_INPUT_BODY_STR;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.appc.listener.util.Mapper;
+
+public class DmaapIncomingMessageTest {
+
+    private DmaapIncomingMessage dmaapIncomingMessage;
+
+    @Before
+    public void setup() {
+        dmaapIncomingMessage = new DmaapIncomingMessage();
+    }
+
+    @Test
+    public void should_set_default_cambria_partition_when_initialized() {
+
+        assertEquals("APP-C", dmaapIncomingMessage.getCambriaPartition());
+    }
+
+    @Test
+    public void toString_should_return_valid_string_representation() {
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_INPUT_BODY_STR);
+
+        dmaapIncomingMessage.setVersion("test-version");
+        dmaapIncomingMessage.setType("test-type");
+        dmaapIncomingMessage.setCorrelationID("test-correlation-id");
+        dmaapIncomingMessage.setCambriaPartition("test-cambria-partition");
+        dmaapIncomingMessage.setRpcName("test-rpc-name");
+        dmaapIncomingMessage.setBody(jsonNode);
+
+        assertEquals("DmaapIncomingMessage{DmaapMessage{" +
+            "version='" + dmaapIncomingMessage.getVersion() + '\'' +
+            ", type='" + dmaapIncomingMessage.getType() + '\'' +
+            ", correlationId='" + dmaapIncomingMessage.getCorrelationID() + '\'' +
+            ", cambriaPartition='" + dmaapIncomingMessage.getCambriaPartition() + '\'' +
+            ", rpcName='" + dmaapIncomingMessage.getRpcName() + '\'' +
+            ", body=" + dmaapIncomingMessage.getBody() +
+            "}}", dmaapIncomingMessage.toString());
+    }
+
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.onap.appc.listener.TestUtil.JSON_INPUT_BODY_STR;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.appc.listener.util.Mapper;
+
+public class DmaapMessageTest {
+
+    private DmaapMessage dmaapMessage;
+
+    @Before
+    public void setup() {
+        dmaapMessage = new DmaapMessage();
+    }
+
+    @Test
+    public void should_set_properties() {
+
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_INPUT_BODY_STR);
+
+        dmaapMessage.setVersion("test-version");
+        dmaapMessage.setType("test-type");
+        dmaapMessage.setCorrelationID("test-correlation-id");
+        dmaapMessage.setCambriaPartition("test-cambria-partition");
+        dmaapMessage.setRpcName("test-rpc-name");
+        dmaapMessage.setBody(jsonNode);
+
+        assertEquals("test-version", dmaapMessage.getVersion());
+        assertEquals("test-type", dmaapMessage.getType());
+        assertEquals("test-correlation-id", dmaapMessage.getCorrelationID());
+        assertEquals("test-cambria-partition", dmaapMessage.getCambriaPartition());
+        assertEquals("test-rpc-name", dmaapMessage.getRpcName());
+        assertEquals(jsonNode, dmaapMessage.getBody());
+    }
+
+    @Test
+    public void toString_should_return_valid_string_representation() {
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_INPUT_BODY_STR);
+
+        dmaapMessage.setVersion("test-version");
+        dmaapMessage.setType("test-type");
+        dmaapMessage.setCorrelationID("test-correlation-id");
+        dmaapMessage.setCambriaPartition("test-cambria-partition");
+        dmaapMessage.setRpcName("test-rpc-name");
+        dmaapMessage.setBody(jsonNode);
+
+        assertEquals("DmaapMessage{" +
+            "version='" + dmaapMessage.getVersion() + '\'' +
+            ", type='" + dmaapMessage.getType() + '\'' +
+            ", correlationId='" + dmaapMessage.getCorrelationID() + '\'' +
+            ", cambriaPartition='" + dmaapMessage.getCambriaPartition() + '\'' +
+            ", rpcName='" + dmaapMessage.getRpcName() + '\'' +
+            ", body=" + dmaapMessage.getBody() +
+            '}', dmaapMessage.toString());
+    }
+}
+
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.onap.appc.listener.TestUtil.JSON_INPUT_BODY_STR;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.appc.listener.util.Mapper;
+
+public class DmaapOutgoingMessageTest {
+
+    private DmaapOutgoingMessage dmaapOutgoingMessage;
+
+    @Before
+    public void setup() {
+        dmaapOutgoingMessage = new DmaapOutgoingMessage();
+    }
+
+    @Test
+    public void should_set_default_cambria_partition_when_initialized() {
+
+        assertEquals("MSO", dmaapOutgoingMessage.getCambriaPartition());
+    }
+
+    @Test
+    public void toString_should_return_valid_string_representation() {
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_INPUT_BODY_STR);
+
+        dmaapOutgoingMessage.setVersion("test-version");
+        dmaapOutgoingMessage.setType("test-type");
+        dmaapOutgoingMessage.setCorrelationID("test-correlation-id");
+        dmaapOutgoingMessage.setCambriaPartition("test-cambria-partition");
+        dmaapOutgoingMessage.setRpcName("test-rpc-name");
+        dmaapOutgoingMessage.setBody(jsonNode);
+
+        assertEquals("DmaapOutgoingMessage{DmaapMessage{" +
+            "version='" + dmaapOutgoingMessage.getVersion() + '\'' +
+            ", type='" + dmaapOutgoingMessage.getType() + '\'' +
+            ", correlationId='" + dmaapOutgoingMessage.getCorrelationID() + '\'' +
+            ", cambriaPartition='" + dmaapOutgoingMessage.getCambriaPartition() + '\'' +
+            ", rpcName='" + dmaapOutgoingMessage.getRpcName() + '\'' +
+            ", body=" + dmaapOutgoingMessage.getBody() +
+            "}}", dmaapOutgoingMessage.toString());
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Modifications Copyright (C) 2019 IBM.
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.onap.appc.listener.TestUtil.buildActionIdentifiers;
+import static org.onap.appc.listener.TestUtil.buildCommonHeader;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class InputBodyTest {
+
+    private InputBody inputBody;
+
+    @Before
+    public void setup() {
+        inputBody = new InputBody();
+    }
+
+    @Test
+    public void should_set_properties() {
+
+        CommonHeader testCommonHeader = buildCommonHeader();
+        ActionIdentifiers testActionIdentifiers = buildActionIdentifiers();
+
+        inputBody.setCommonHeader(testCommonHeader);
+        inputBody.setActionIdentifiers(testActionIdentifiers);
+        inputBody.setAction("test-action");
+        inputBody.setPayload("{\"payload\": \"value\"");
+
+        assertEquals(testCommonHeader, inputBody.getCommonHeader());
+        assertEquals(testActionIdentifiers, inputBody.getActionIdentifiers());
+        assertEquals("test-action", inputBody.getAction());
+        assertEquals("{\"payload\": \"value\"", inputBody.getPayload());
+    }
+
+    @Test
+    public void should_verify_if_is_valid() {
+
+        assertFalse(inputBody.isValid());
+        inputBody.setCommonHeader(buildCommonHeader());
+        assertTrue(inputBody.isValid());
+    }
+    
+    @Test
+    public void testPayLoadAsString()
+    {
+       inputBody.setPayloadAsString("payload");
+       assertEquals("payload", inputBody.getPayload());
+    }
+
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.model;
+
+import static junit.framework.TestCase.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.onap.appc.listener.TestUtil.buildCommonHeader;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+
+public class OutputBodyTest {
+
+    private OutputBody outputBody;
+
+    @Before
+    public void setup() {
+        outputBody = new OutputBody();
+    }
+
+    @Test
+    public void should_set_properties() {
+
+        CommonHeader testCommonHeader = buildCommonHeader();
+        ResponseStatus testResponseStatus = new ResponseStatus(200, "OK");
+
+        outputBody.setHeader(testCommonHeader);
+        outputBody.setStatus(testResponseStatus);
+        outputBody.setLocked("test-locked");
+        outputBody.setPayload("{\"payload\": \"value\"");
+
+        assertEquals(testCommonHeader, outputBody.getHeader());
+        assertEquals(testResponseStatus, outputBody.getStatus());
+        assertEquals("test-locked", outputBody.getLocked());
+        assertEquals("{\"payload\": \"value\"", outputBody.getPayload());
+    }
+
+
+    @Test
+    public void should_inherit_input_body_header_when_initialized_from_constructor() {
+
+        InputBody testInputBody = new InputBody();
+        CommonHeader testCommonHeader = buildCommonHeader();
+        testInputBody.setCommonHeader(testCommonHeader);
+
+        outputBody = new OutputBody(testInputBody);
+
+        assertNotNull(outputBody.getHeader());
+        assertEquals(testCommonHeader.getFlags(), outputBody.getHeader().getFlags());
+        assertEquals(testCommonHeader.getSubRequestId(), outputBody.getHeader().getSubRequestId());
+        assertEquals(testCommonHeader.getRequestID(), outputBody.getHeader().getRequestID());
+        assertEquals(testCommonHeader.getOriginatorId(), outputBody.getHeader().getOriginatorId());
+        assertEquals(testCommonHeader.getApiVer(), outputBody.getHeader().getApiVer());
+    }
+
+    @Test
+    public void toResponse_should_convert_to_json_object() {
+        CommonHeader testCommonHeader = buildCommonHeader();
+        ResponseStatus testResponseStatus = new ResponseStatus(200, "OK");
+
+        outputBody.setHeader(testCommonHeader);
+        outputBody.setStatus(testResponseStatus);
+        outputBody.setLocked("test-locked");
+        outputBody.setPayload("{\"payload\": \"value\"");
+
+        JSONObject response = outputBody.toResponse();
+        assertNotNull(response);
+
+        assertEquals("test-locked", response.get("locked"));
+        assertEquals("{\"payload\": \"value\"", response.get("payload"));
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.model;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class ResponseStatusTest {
+
+    private ResponseStatus responseStatus;
+
+    @Before
+    public void setup() {
+        responseStatus = new ResponseStatus();
+    }
+
+    @Test
+    public void should_set_properties() {
+
+        responseStatus.setCode(200);
+        responseStatus.setValue("OK");
+
+        assertEquals(Integer.valueOf(200), responseStatus.getCode());
+        assertEquals("OK", responseStatus.getValue());
+    }
+
+    @Test
+    public void should_initialize_parameters_from_constructor() {
+        responseStatus = new ResponseStatus(200, "OK");
+
+        assertEquals(Integer.valueOf(200), responseStatus.getCode());
+        assertEquals("OK", responseStatus.getValue());
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.operation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.onap.appc.listener.TestUtil.JSON_OUTPUT_BODY_STR;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.LCM.model.InputBody;
+import org.onap.appc.listener.LCM.model.ResponseStatus;
+import org.onap.appc.listener.util.Mapper;
+
+public class GenericProviderOperationsRequestFormatterTest {
+
+    private static final String INVALID_JSON_OUTPUT_BODY_STR =
+        "{\"output\":{\"common-header\":{\"timestamp\":\"2016-08-03T08:50:18.97Z\","
+            + "\"api-ver\":\"1\",\"flags\":{\"force\":\"TRUE\",\"ttl\":\"9900\"},\"sub-request-id\":\"1\","
+            + "\"request-id\":\"123\",\"originator-id\":\"1\"}}}";
+
+    private GenericProviderOperationRequestFormatter requestFormatter;
+
+
+    @Before
+    public void setup() {
+        requestFormatter = new GenericProviderOperationRequestFormatter();
+    }
+
+    @Test
+    public void should_build_path() throws MalformedURLException {
+        String result = requestFormatter.buildPath(new URL("http://127.0.0.1/abc/def"), "test");
+        assertEquals("/abc/def:test", result);
+    }
+
+    @Test
+    public void should_build_request_json() {
+        InputBody inputBody = new InputBody();
+        inputBody.setPayload("\"key1\": \"value1\", \"key2\": \"value2\"");
+
+        assertEquals("{\"input\": {\"payload\":\"\\\"key1\\\": \\\"value1\\\", \\\"key2\\\": \\\"value2\\\"\"}}",
+            requestFormatter.buildRequest(inputBody));
+    }
+
+    @Test(expected = APPCException.class)
+    public void should_throw_when_invalid_json() throws APPCException {
+
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(INVALID_JSON_OUTPUT_BODY_STR);
+        requestFormatter.getResponseStatus(jsonNode);
+    }
+
+    @Test
+    public void should_extract_response_status() throws APPCException {
+
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_OUTPUT_BODY_STR);
+        ResponseStatus status = requestFormatter.getResponseStatus(jsonNode);
+
+        assertEquals("test message", status.getValue());
+        assertEquals(Integer.valueOf(200), status.getCode());
+    }
+
+    @Test
+    public void should_return_extract_locked_field() throws APPCException {
+
+        assertNull(requestFormatter.getLocked(new JSONObject(INVALID_JSON_OUTPUT_BODY_STR)));
+        assertEquals("test-locked", requestFormatter.getLocked(new JSONObject(JSON_OUTPUT_BODY_STR)));
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Solutions and Networks
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.listener.LCM.operation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import org.apache.commons.codec.binary.Base64;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.net.SocketException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.StatusLine;
+import org.apache.http.client.HttpClient;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.LCM.operation.ProviderOperations.MySSLSocketFactory;
+
+public class ProviderOperationsTest {
+
+    private ProviderOperations providerOperations;
+    private MySSLSocketFactory socketFactory;
+
+    @Mock
+    private KeyStore mockKeyStore;
+
+
+    @Before
+    public void setup()
+        throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+
+        providerOperations =
+            new ProviderOperations("http://127.0.0.1", "test_user", "test_password");
+        socketFactory = new MySSLSocketFactory(mockKeyStore);
+    }
+
+    @Test
+    public void setAuthentication_should_return_null_given_null_arguments() {
+        String newAuthentication = providerOperations.setAuthentication(null, null);
+        assertNull(newAuthentication);
+    }
+
+    @Test
+    public void should_set_properties() {
+        providerOperations.setUrl("hp://123.1.2.3");
+        assertEquals("http://127.0.0.1", providerOperations.getUrl());
+        providerOperations.setUrl("http://123.1.2.3");
+        assertEquals("http://123.1.2.3", providerOperations.getUrl());
+
+        String newAuthentication = providerOperations.setAuthentication("new_user", "new_password");
+        String authStr = "new_user:new_password";
+        assertEquals(new String(Base64.encodeBase64(authStr.getBytes())), newAuthentication);
+    }
+
+    @Test
+    public void isSucceeded_should_resolve_status_codes() {
+
+        assertFalse(ProviderOperations.isSucceeded(null));
+        assertFalse(ProviderOperations.isSucceeded(200));
+        assertTrue(ProviderOperations.isSucceeded(100));
+        assertTrue(ProviderOperations.isSucceeded(400));
+    }
+
+    @Test(expected = APPCException.class)
+    public void topologyDG_should_throw_given_null_message() throws APPCException {
+
+        providerOperations.topologyDG("test-rpc-name", null);
+    }
+
+    @Test(expected = SocketException.class)
+    public void sslSocketFactory_should_throw_when_socket_not_connected() throws IOException {
+        Socket socket = socketFactory.createSocket();
+        assertNotNull(socket);
+
+        socketFactory.createSocket(socket, "127.0.0.1", 123, true);
+    }
+
+    //TODO write some test cases for topologyDG method
+    @Test
+    public void testBuildPostRequest() throws JsonProcessingException, IOException, APPCException {
+        String jsonString = "{\"output\":{\"status\":{\"code\":\"200\",\"message\":\"TEST_MESSAGE\"}}}";
+        providerOperations = Mockito.spy(
+                new ProviderOperations("http://127.0.0.1", "test_user", "test_password"));
+        HttpClient httpClient = Mockito.mock(HttpClient.class);
+        HttpResponse httpResponse = Mockito.mock(HttpResponse.class);
+        StatusLine statusLine = Mockito.mock(StatusLine.class);
+        Mockito.when(statusLine.getStatusCode()).thenReturn(200);
+        Mockito.when(httpResponse.getStatusLine()).thenReturn(statusLine);
+        HttpEntity httpEntity = Mockito.mock(HttpEntity.class);
+        InputStream inputStream = new ByteArrayInputStream(jsonString.getBytes());
+        Mockito.when(httpEntity.getContent()).thenReturn(inputStream);
+        Mockito.when(httpResponse.getEntity()).thenReturn(httpEntity);
+        Mockito.when(httpClient.execute(Mockito.any())).thenReturn(httpResponse);
+        Mockito.when(providerOperations.getHttpClient()).thenReturn(httpClient);
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode jsonNode = mapper.readTree(jsonString);
+        assertEquals(ObjectNode.class, providerOperations.topologyDG(null, jsonNode).getClass());
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.LCM1607.model;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.appc.listener.util.Mapper;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class TestJsonGenericMessages {/*
+
+    @Test
+    public void serializeIncomingMessage() {
+
+        final String expectedJson = "{\"CommonHeader\":{\"TimeStamp\":\"2016-05-02 19:50:37.09\",\"TransactionID\":\"1\",\"APIver\":\"1.01\",\"RequestTrack\":[\"1\",\"4\",\"12\",\"3\"],\"Flags\":null,\"SubrequestID\":null,\"OriginatorID\":\"2\"},\"Payload\":\"{ \\\"command\\\": \\\"start\\\", \\\"target-id\\\": \\\"111\\\", \\\"flag10\\\": {\\\"object-1\\\": {\\\"key-1\\\": \\\"key\\\", \\\"value-1\\\": \\\"value\\\" }} }\",\"Action\":\"CONFIGURE\",\"ObjectID\":\"200\",\"TargetID\":\"100\"}";
+        InputBody msg = createIncomingMessage();
+
+        String json = Mapper.toJsonObject(msg).toString();
+        //System.out.println(json);
+        Assert.assertEquals(expectedJson, json);
+    }
+
+    @Test
+    public void deserializeIncomingMessage() throws IOException {
+        final String originalJson = "{\"CommonHeader\":{\"TimeStamp\":\"2016-05-02 19:50:37.09\",\"TransactionID\":\"1\",\"Flags\":{\"FORCE\":\"Y\",\"TTL\":\"12\"},\"SubrequestID\":\"2345\",\"OriginatorID\":\"2\",\"APIver\":\"1.01\"},  \"Payload\": \" \\\"Graceful\\\" : \\\"Yes\\\" \",\"Action\":\"CONFIGURE\",\"ObjectID\":\"200\",\"TargetID\":\"100\"}";
+
+        ObjectMapper mapper = new ObjectMapper();
+        InputBody msg = mapper.readValue(originalJson, InputBody.class);
+
+        Assert.assertNotNull(msg);
+        Assert.assertEquals("2016-05-02 19:50:37.09", msg.getCommonHeader().getTimeStamp());
+        Assert.assertEquals("1", msg.getCommonHeader().getRequestID());
+        Assert.assertEquals("1.01", msg.getCommonHeader().getApiVer());
+        Assert.assertEquals("200", msg.getObjectId());
+        Assert.assertEquals("100", msg.getTargetId());
+        Assert.assertEquals(" \"Graceful\" : \"Yes\" ", msg.getPayload());
+        Assert.assertEquals("CONFIGURE", msg.getAction());
+
+    }
+
+    @Test
+    public void serializeResponseMessage() {
+        InputBody imsg = createIncomingMessage();
+        OutputBody omsg = new OutputBody(imsg);
+        omsg.setStatus(new ResponseStatus("200", "OK"));
+
+        String json = Mapper.toJsonObject(omsg).toString();
+        System.out.println(json);
+        //Assert.assertEquals(expectedJson, json);
+        Assert.assertNotEquals("", json);
+
+    }
+
+    private InputBody createIncomingMessage() {
+        InputBody msg = new InputBody();
+        CommonHeader rh = new CommonHeader();
+        rh.setTimeStamp("2016-05-02 19:50:37.09");
+        rh.setApiVer("1.01");
+        rh.setRequestID("1");
+        rh.setOriginatorId("2");
+
+
+        Map<String, String> flags = new HashMap<>();
+        flags.put("FORCE", "Y");
+        flags.put("TTL", "12");
+
+        msg.setCommonHeader(rh);
+        msg.setAction("CONFIGURE");
+        msg.setTargetId("100");
+        msg.setObjectId("200");
+        msg.setPayloadAsString("{ \"command\": \"start\", \"target-id\": \"111\", \"flag10\": {\"object-1\": {\"key-1\": \"key\", \"value-1\": \"value\" }} }");
+        return msg;
+    }
+*/
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Properties;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.appc.adapter.factory.MessageService;
+import org.onap.appc.listener.AbstractListener;
+import org.onap.appc.listener.ListenerProperties;
+import org.onap.appc.listener.ListenerProperties.KEYS;
+
+public class ListenerPropertiesTest {
+
+    private Properties good, bad, both;
+    private String prefix;
+
+    private ListenerProperties props;
+
+    @Before
+    public void setup() {
+        prefix = "test";
+        good = new Properties();
+        bad = new Properties();
+        both = new Properties();
+
+        good.setProperty(String.format("%s.%s", prefix, "a"), "1");
+        good.setProperty(String.format("%s.%s", prefix, "a.b"), "2");
+        good.setProperty(String.format("%s.%s", prefix, "a.b.c"), "3");
+
+        bad.setProperty(prefix, "NA");
+        bad.setProperty(prefix + ".", "NA");
+        bad.setProperty(String.format("%s.%s", prefix + "x", "bad"), "NA");
+        bad.setProperty(String.format("%s.%s", "x" + prefix, "bad"), "NA");
+
+        for (String key : good.stringPropertyNames()) {
+            both.put(key, good.getProperty(key));
+        }
+        for (String key : bad.stringPropertyNames()) {
+            both.put(key, bad.getProperty(key));
+        }
+
+        props = new ListenerProperties(prefix, both);
+    }
+
+    @Test
+    public void testConstructor() {
+        props = new ListenerProperties(prefix, good);
+        assertEquals(prefix, props.getPrefix());
+        assertEquals(good.size(), props.getProperties().size());
+
+        props = new ListenerProperties(prefix, bad);
+        assertEquals(prefix, props.getPrefix());
+        assertTrue(props.getProperties().isEmpty());
+
+        props = new ListenerProperties(prefix, both);
+        assertEquals(prefix, props.getPrefix());
+        assertEquals(good.size(), props.getProperties().size());
+
+        for (Object val : props.getProperties().values()) {
+            assertFalse("NA".equals(val.toString()));
+        }
+
+        assertTrue(props.toString().contains(prefix));
+    }
+
+    @Test
+    public void testGetClass() {
+        assertNull(props.getListenerClass());
+        props.setListenerClass(AbstractListener.class);
+        assertNotNull(props.getListenerClass());
+        assertEquals(AbstractListener.class, props.getListenerClass());
+    }
+
+    @Test
+    public void testMessageServices() {
+        // Hardcode count so tests must be updated when values are added
+        assertEquals(1, MessageService.values().length);
+
+        // Bad Input
+        MessageService def = MessageService.DMaaP;
+        assertEquals(def, MessageService.parse(null));
+        assertEquals(def, MessageService.parse(""));
+        assertEquals(def, MessageService.parse("NotDMaaP"));
+       
+        // DMaaP case sensitivity
+        assertEquals(MessageService.DMaaP, MessageService.parse("dmaap"));
+        assertEquals(MessageService.DMaaP, MessageService.parse("DMAAP"));
+        assertEquals(MessageService.DMaaP, MessageService.parse("DMaaP"));
+    }
+
+    @Test
+    public void testKeys() {
+        // Hardcode count so tests must be updated when values are added
+        assertEquals(19, ListenerProperties.KEYS.values().length);
+
+        Properties tmp = new Properties();
+        try {
+            tmp.load(getClass().getResourceAsStream("/org/onap/appc/default.properties"));
+        } catch (Exception e) {
+            fail("Could not load properties to test");
+        }
+        String realPrefix = tmp.getProperty("test.prefix");
+        assertNotNull(realPrefix);
+        props = new ListenerProperties(realPrefix, tmp);
+
+        for (KEYS key : ListenerProperties.KEYS.values()) {
+            assertNotNull(key.getFullProp(realPrefix));
+            assertNotNull(props.getProperty(key));
+            assertNotNull(props.getProperty(key.getPropertySuffix()));
+        }
+    }
+
+    @Test
+    public void testDisabled() throws Exception {
+        assertFalse(props.isDisabled());
+        props.getProperties().put(KEYS.DISABLED.getPropertySuffix(), "TRUE");
+        assertTrue(props.isDisabled());
+        props.getProperties().put(KEYS.DISABLED.getPropertySuffix(), "N/A");
+        assertFalse(props.isDisabled());
+        props.getProperties().put(KEYS.DISABLED.getPropertySuffix(), "fAlse");
+        assertFalse(props.isDisabled());
+        props.getProperties().remove(KEYS.DISABLED.getPropertySuffix());
+        assertFalse(props.isDisabled());
+    }
+
+}
 
--- /dev/null
+package org.onap.appc.listener;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.util.HashMap;
+import java.util.Map;
+import org.onap.appc.listener.LCM.model.ActionIdentifiers;
+import org.onap.appc.listener.LCM.model.CommonHeader;
+import org.onap.appc.listener.LCM.model.DmaapIncomingMessage;
+import org.onap.appc.listener.LCM.model.DmaapMessage;
+import org.onap.appc.listener.LCM.model.DmaapOutgoingMessage;
+import org.onap.appc.listener.util.Mapper;
+
+public class TestUtil {
+
+    public static final String JSON_INPUT_BODY_STR =
+        "{\"input\":{ \"common-header\": { \"timestamp\": \"2016-08-03T08:50:18.97Z\", "
+            + "\"api-ver\": \"1\", \"originator-id\": \"1\", \"request-id\": \"123\", \"sub-request-id\": \"1\", "
+            + "\"flags\": { \"force\":\"TRUE\", \"ttl\":\"9900\" } }, \"action\": \"Stop\", "
+            + "\"action-identifiers\": { \"vnf-id\": \"TEST\" } }}";
+
+    public static final String JSON_OUTPUT_BODY_STR =
+        "{\"output\":{\"common-header\":{\"timestamp\":\"2016-08-03T08:50:18.97Z\","
+            + "\"api-ver\":\"1\",\"flags\":{\"force\":\"TRUE\",\"ttl\":\"9900\"},\"sub-request-id\":\"1\","
+            + "\"request-id\":\"123\",\"originator-id\":\"1\"},\"locked\": \"test-locked\", "
+            + "\"status\":{\"message\":\"test message\",\"code\":200}}}";
+
+    public static DmaapMessage buildDmaapMessage() {
+
+        DmaapMessage dmaapMessage = new DmaapMessage();
+        dmaapMessage.setRpcName("test");
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_INPUT_BODY_STR);
+        dmaapMessage.setBody(jsonNode);
+        return dmaapMessage;
+    }
+
+    public static DmaapIncomingMessage buildDmaapIncomingMessage() {
+        DmaapIncomingMessage dmaapIncomingMessage = new DmaapIncomingMessage();
+        dmaapIncomingMessage.setRpcName("test");
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_INPUT_BODY_STR);
+        dmaapIncomingMessage.setBody(jsonNode);
+        return dmaapIncomingMessage;
+
+    }
+
+    public static DmaapOutgoingMessage buildDmaapOutgoingMessage() {
+        DmaapOutgoingMessage dmaapOutgoingMessage = new DmaapOutgoingMessage();
+        dmaapOutgoingMessage.setRpcName("test");
+        JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(JSON_OUTPUT_BODY_STR);
+        dmaapOutgoingMessage.setBody(jsonNode);
+        return dmaapOutgoingMessage;
+
+    }
+
+    public static CommonHeader buildCommonHeader() {
+
+        CommonHeader commonHeader = new CommonHeader();
+        commonHeader.setTimeStamp("test-timestamp");
+        commonHeader.setApiVer("test-api-version");
+        commonHeader.setOriginatorId("test-originator-id");
+        commonHeader.setRequestID("test-request-id");
+        commonHeader.setSubRequestId("test-subrequest-id");
+
+        Map<String, String> flags = new HashMap<>();
+        flags.put("key1", "flag1");
+        flags.put("key2", "flag2");
+        flags.put("key3", "flag3");
+
+        commonHeader.setFlags(flags);
+        return commonHeader;
+    }
+
+    public static ActionIdentifiers buildActionIdentifiers() {
+
+        ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
+        actionIdentifiers.setServiceInstanceId("test-instance-id");
+        actionIdentifiers.setVnfID("test-vnf-id");
+        actionIdentifiers.setVnfcName("test-name");
+        actionIdentifiers.setVserverId("test-vserver-id");
+
+        return actionIdentifiers;
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.impl;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.when;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.StatusLine;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.internal.util.reflection.Whitebox;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.demo.model.Action;
+import org.onap.appc.listener.demo.model.CommonMessage.CommonHeader;
+import org.onap.appc.listener.demo.model.CommonMessage.Payload;
+import org.onap.appc.listener.demo.model.IncomingMessage;
+import org.onap.appc.listener.util.HttpClientUtil;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(HttpClientUtil.class)
+public class TestProviderOperations {
+
+  private ProviderOperations providerOperations;
+  private IncomingMessage message;
+  private URL url;
+  private CommonHeader commonHeader;
+  private Payload payload;
+  private HttpClient httpClient;
+  private HttpResponse httpResponse;
+  private StatusLine statusLine;
+  private HttpEntity httpEntity;
+  private InputStream inputStream;
+  private String reponseMessage;
+
+  @Before
+  public void setUp() throws Exception {
+    reponseMessage = "{\"output\":{\"common-response-header\":{\"success\":true,\"reason\":\"\"}}}";
+    providerOperations = new ProviderOperations();
+    PowerMockito.mockStatic(HttpClientUtil.class);
+    httpClient = PowerMockito.mock(HttpClient.class);
+    httpResponse = PowerMockito.mock(HttpResponse.class);
+    statusLine = PowerMockito.mock(StatusLine.class);
+    httpEntity = PowerMockito.mock(HttpEntity.class);
+    inputStream = new ByteArrayInputStream(reponseMessage.getBytes(StandardCharsets.UTF_8));
+    message = Mockito.mock(IncomingMessage.class);
+    url = PowerMockito.mock(URL.class);
+    commonHeader = Mockito.mock(CommonHeader.class);
+    payload = Mockito.mock(Payload.class);
+    when(message.getAction()).thenReturn(Action.Evacuate);
+    when(message.getHeader()).thenReturn(commonHeader);
+    when(message.getPayload()).thenReturn(payload);
+    when(HttpClientUtil.getHttpClient("http")).thenReturn(httpClient);
+    when(httpClient.execute(anyObject())).thenReturn(httpResponse);
+    when(httpResponse.getStatusLine()).thenReturn(statusLine);
+    when(statusLine.getStatusCode()).thenReturn(200);
+    when(httpResponse.getEntity()).thenReturn(httpEntity);
+    when(httpEntity.getContent()).thenReturn(inputStream);
+    Whitebox.setInternalState(url, "protocol", "http");
+    Whitebox.setInternalState(providerOperations, "url", url);
+  }
+
+  @Test
+  public void testTopologyDG() throws APPCException, ClientProtocolException, IOException {
+    assertTrue(ProviderOperations.topologyDG(message));
+  }
+
+  @Test
+  public void testTopologyDGWithBaseAuth()
+      throws APPCException, ClientProtocolException, IOException {
+    ProviderOperations.setAuthentication("user", "password");
+    ProviderOperations.setUrl("http://localhost:8080");
+    assertTrue(ProviderOperations.topologyDG(message));
+  }
+
+  @Test(expected = APPCException.class)
+  public void testTopologyDGFail() throws APPCException, ClientProtocolException, IOException {
+    reponseMessage =
+        "{\"output\":{\"common-response-header\":{\"success\":false,\"reason\":\"\"}}}";
+    inputStream = new ByteArrayInputStream(reponseMessage.getBytes(StandardCharsets.UTF_8));
+    when(httpEntity.getContent()).thenReturn(inputStream);
+    ProviderOperations.topologyDG(message);
+  }
+
+  @Test(expected = APPCException.class)
+  public void testTopologyDGInvalidResponse()
+      throws APPCException, ClientProtocolException, IOException {
+    reponseMessage = "{\"output\":{\"common-response-header\":{\"succss\":false,\"reason\":\"\"}}}";
+    inputStream = new ByteArrayInputStream(reponseMessage.getBytes(StandardCharsets.UTF_8));
+    when(httpEntity.getContent()).thenReturn(inputStream);
+    ProviderOperations.topologyDG(message);
+  }
+
+  @Test(expected = APPCException.class)
+  public void testTopologyDGWithInvalidHttp()
+      throws APPCException, ClientProtocolException, IOException {
+    when(statusLine.getStatusCode()).thenReturn(500);
+    ProviderOperations.topologyDG(message);
+  }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.impl;
+
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
+
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.onap.appc.exceptions.APPCException;
+import org.onap.appc.listener.EventHandler;
+import org.onap.appc.listener.demo.model.CommonMessage.CommonHeader;
+import org.onap.appc.listener.demo.model.IncomingMessage;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(ProviderOperations.class)
+public class TestWorkerImpl {
+
+  private WorkerImpl workerImplSpy;
+  private IncomingMessage message;
+  private EventHandler dmaap;
+
+  @Before
+  public void setUp() {
+    message = Mockito.mock(IncomingMessage.class);
+    dmaap = Mockito.mock(EventHandler.class);
+    workerImplSpy = Mockito.spy(new WorkerImpl(message, dmaap));
+  }
+
+  @Test
+  public void testRun() throws APPCException {
+    CommonHeader commonHeader = Mockito.mock(CommonHeader.class);
+    when(message.getHeader()).thenReturn(commonHeader);
+    when(commonHeader.getRequestID()).thenReturn("requestId");
+    PowerMockito.mockStatic(ProviderOperations.class);
+    PowerMockito.when(ProviderOperations.topologyDG(anyObject())).thenReturn(true);
+    workerImplSpy.run();
+    verify(workerImplSpy, times(1)).run();
+  }
+
+  @Test
+  public void testRunElseCase() throws APPCException {
+    CommonHeader commonHeader = Mockito.mock(CommonHeader.class);
+    when(message.getHeader()).thenReturn(commonHeader);
+    when(commonHeader.getRequestID()).thenReturn("requestId");
+    when(message.toJson()).thenReturn(new JSONObject());
+    PowerMockito.mockStatic(ProviderOperations.class);
+    PowerMockito.when(ProviderOperations.topologyDG(anyObject())).thenReturn(false);
+    workerImplSpy.run();
+    verify(workerImplSpy, times(1)).run();
+  }
+
+  @Test
+  public void testRunWithException() throws APPCException {
+    CommonHeader commonHeader = Mockito.mock(CommonHeader.class);
+    when(message.getHeader()).thenReturn(commonHeader);
+    when(commonHeader.getRequestID()).thenReturn("requestId");
+    workerImplSpy.run();
+    verify(workerImplSpy, times(1)).run();
+  }
+}
 
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 Ericsson
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import org.apache.commons.io.IOUtils;
+import org.hamcrest.CoreMatchers;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.onap.appc.listener.util.Mapper;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(Mapper.class)
+public class OutgoingMessageTest {
+
+    private IncomingMessage incomingMessage;
+
+    @Before
+    public void setup() throws IOException {
+        String incomingStr = IOUtils.toString(getClass().getResourceAsStream("/IncomingMessagedemo.txt"), "UTF-8");
+        incomingMessage = Mapper.mapOne(incomingStr, IncomingMessage.class);
+    }
+
+    @Test
+    public void testOutgoingMessage() throws UnknownHostException {
+        InetAddress mockInetAddress = Mockito.mock(InetAddress.class);
+        Mockito.when(mockInetAddress.getCanonicalHostName()).thenReturn("TEST_CANONICAL_HOSTNAME");
+        OutgoingMessage outgoingMessage = Mockito.spy(new OutgoingMessage(incomingMessage));
+        PowerMockito.when(outgoingMessage.getLocalHost()).thenReturn(mockInetAddress);
+        outgoingMessage.updateResponseTime();
+        assertEquals("appc@TEST_CANONICAL_HOSTNAME", outgoingMessage.generateFrom());
+    }
+
+    @Test
+    public void testOutgoingMessageUnknowHost() throws UnknownHostException {
+        OutgoingMessage outgoingMessage = Mockito.spy(new OutgoingMessage(incomingMessage));
+        PowerMockito.when(outgoingMessage.getLocalHost()).thenThrow(new UnknownHostException());
+        assertEquals("appc@UnknownHost", outgoingMessage.generateFrom());
+    }
+
+    @Test
+    public void testJson() {
+        PowerMockito.mockStatic(Mapper.class);
+        JSONObject mockObject = Mockito.mock(JSONObject.class);
+        PowerMockito.when(Mapper.toJsonObject(Mockito.any())).thenReturn(mockObject);
+        OutgoingMessage outgoingMessage = Mockito.spy(new OutgoingMessage(incomingMessage));
+        assertEquals(mockObject, outgoingMessage.toResponse());
+    }
+
+    @Test
+    public void testSetResponse() {
+        OutgoingMessage outgoingMessage = new OutgoingMessage(incomingMessage);
+        outgoingMessage.setResponse(null);
+        assertEquals(new OutgoingMessage.OutStatus().getValue(), outgoingMessage.getStatus().getValue());
+        outgoingMessage.setResponse(Status.ACCEPTED);
+        assertEquals("100", outgoingMessage.getStatus().getCode());
+        outgoingMessage.setResponse(Status.FAILURE);
+        assertEquals("500", outgoingMessage.getStatus().getCode());
+        outgoingMessage.setResponse(Status.SUCCESS);
+        assertEquals("400", outgoingMessage.getStatus().getCode());
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommonMessage {
+
+    private CommonMessage commonMessage;
+    private CommonMessage.Payload payload;
+
+    @Before
+    public void setUp() {
+        commonMessage = new CommonMessage();
+        payload = new CommonMessage.Payload();
+    }
+
+    @Test
+    public void testToJson() {
+        assertTrue(commonMessage.toJson() instanceof JSONObject);
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.onap.appc.listener.demo.model.Action;
+import org.onap.appc.listener.demo.model.Status;
+
+public class TestEnums {
+
+    @Test
+    public void testAction() {
+        assertEquals(Action.Rebuild, Action.toAction("Rebuild"));
+        assertEquals(Action.Restart, Action.toAction("restart"));
+        assertEquals(Action.Migrate, Action.toAction("MIGRATE"));
+        assertEquals(Action.Evacuate, Action.toAction("Evacuate"));
+        assertNull(Action.toAction("Unknown"));
+        assertNull(Action.toAction(null));
+
+        assertEquals(6, Action.values().length);
+    }
+
+    @Test
+    public void testStatus() {
+
+        assertEquals(Status.ACCEPTED, Status.toStatus("accepted"));
+        assertEquals(Status.SUCCESS, Status.toStatus("SuCcEsS"));
+        assertEquals(Status.FAILURE, Status.toStatus("Failure"));
+        assertNull(Status.toStatus("Unknown"));
+        assertNull(Status.toStatus(null));
+
+        assertEquals(3, Status.values().length);
+
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestIncomingMessage {
+
+    private IncomingMessage incomingMessage;
+
+    @Before
+    public void setUp() {
+        incomingMessage = new IncomingMessage();
+    }
+
+    @Test
+    public void testToOutgoing() {
+        String expected = "{\"Status\":{\"Value\":null,\"Code\":null}}";
+        assertEquals(expected, incomingMessage.toOutgoing(null));
+        expected = "{\"Status\":{\"Value\":\""+Status.ACCEPTED.getValue()+"\",\"Code\":\"100\"}}";
+        assertEquals(expected, incomingMessage.toOutgoing(Status.ACCEPTED));
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modification Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.demo.model;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import java.util.ArrayList;
+import java.util.Collection;
+import org.apache.commons.io.IOUtils;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onap.appc.listener.demo.model.CommonMessage.Streams;
+import org.onap.appc.listener.demo.model.IncomingMessage;
+import org.onap.appc.listener.demo.model.OutgoingMessage;
+import org.onap.appc.listener.demo.model.Status;
+import org.onap.appc.listener.util.Mapper;
+
+public class TestMessages {
+    private IncomingMessage in;
+    private OutgoingMessage out;
+
+    private String incomingStr;
+    private String outgoingStr;
+
+    @Before
+    public void setup() {
+        try {
+            incomingStr = IOUtils.toString(getClass().getResourceAsStream("/IncomingMessagedemo.txt"), "UTF-8");
+            outgoingStr = IOUtils.toString(getClass().getResourceAsStream("/OutgoingMessagedemo.txt"), "UTF-8");
+            assertNotNull(incomingStr);
+            assertNotNull(outgoingStr);
+
+            in = Mapper.mapOne(incomingStr, IncomingMessage.class);
+
+            out = Mapper.mapOne(outgoingStr, OutgoingMessage.class);
+
+            assertNotNull(in);
+            assertNotNull(out);
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+    }
+
+    // NOTE Test Mapper will be used to test an event from dmaap.
+    @Test
+    public void testGetterSetter() {
+        assertNotNull(in);
+        assertNotNull(in.getAction());
+        assertNotNull(in.getHeader().getApiVer());
+        assertNotNull(in.getHeader().getOriginatorId());
+        assertNotNull(in.getHeader().getRequestID());
+        assertNotNull(in.getHeader().getSubRequestId());
+        assertNotNull(in.getHeader().getTimeStamp());
+
+        assertNotNull(out);
+        assertNotNull(out.getHeader().getApiVer());
+        assertNotNull(out.getHeader().getOriginatorId());
+        assertNotNull(out.getHeader().getRequestID());
+        assertNotNull(out.getHeader().getSubRequestId());
+        assertNotNull(out.getHeader().getTimeStamp());
+        assertNotNull(out.getStatus().getCode());
+        assertNotNull(out.getStatus().getValue());
+
+    }
+
+    @Test
+    public void testGetRequest()
+    {
+        String request="testRequest";
+        in.setRequest(request);
+        assertEquals(request, in.getRequest());
+    }
+
+    @Test
+    public void testIsValid()
+    {
+        assertEquals(true, in.isValid());
+    }
+
+    @Test
+    public void testTime() {
+        in.setStartTime(0);
+        assertEquals(0, in.getStartTime());
+    }
+
+    @Test
+    public void testPayload() {
+        CommonMessage.Payload payload = new CommonMessage.Payload();
+        payload.setGenericVnfId("VNF_ID");
+        CommonMessage.Streams streams = new CommonMessage.Streams();
+        streams.setActiveStreams(7);
+        payload.setStreams(streams);
+        in.setPayload(payload);
+        assertEquals("VNF_ID", in.getPayload().getGenericVnfId());
+        assertEquals("{\\\"streams\\\": {\\\"active-streams\\\": 7}}",
+                in.getPayload().getStreams());
+    }
+
+    @Test
+    @Ignore
+    public void testIncommingToOutgoing(){
+        OutgoingMessage newOut;
+        newOut = Mapper.mapOne(in.toOutgoing(Status.ACCEPTED), OutgoingMessage.class);
+        assertNotNull(newOut);
+        assertNotNull(newOut.getHeader().getApiVer());
+        assertNotNull(newOut.getHeader().getOriginatorId());
+        assertNotNull(newOut.getHeader().getRequestID());
+        assertNotNull(newOut.getHeader().getSubRequestId());
+        assertNotNull(newOut.getHeader().getTimeStamp());
+        assertNotNull(newOut.getStatus().getCode());
+        assertNotNull(newOut.getStatus().getValue());
+    }
+
+    @Test
+    @Ignore
+    public void testToString() {
+        in = new IncomingMessage();
+        assertNotNull(in.toString());
+        String id = "test";
+        //in.setId(id);
+        assertNotNull(in.toString());
+        assertTrue(in.toString().contains(id));
+    }
+
+    @Test
+    @Ignore
+    public void testOutgoingUpdateTime() {
+        //String old = out.getResponseTime();
+        out.updateResponseTime();
+        //assertFalse(old.equals(out.getResponseTime()));
+    }
+
+    // Testing for 1510
+    @Test
+    @Ignore
+    public void testOutgoingToJson() {
+        // Message Set
+        String message = "MSG";
+        //out.setMessage(message);
+        JSONObject json = out.toResponse();
+        assertNotNull(json);
+        String respStr = json.getString("response");
+        //assertTrue(respStr.contains(out.getResponse().getValue()));
+
+        String msgStr = json.getString("message");
+        assertNotNull(msgStr);
+        //assertFalse(msgStr.contains(out.getOriginalRequest())); // False for 1602
+        //assertTrue(msgStr.contains(out.getMessage()));
+
+        // Null Message
+        //out.setMessage(null);
+        json = out.toResponse();
+        assertNotNull(json);
+        msgStr = json.getString("message");
+        assertNotNull(msgStr);
+        //assertFalse(msgStr.contains(out.getOriginalRequest())); // False for 1602
+        //assertTrue(msgStr.contains(out.getResponse().getValue()));
+
+        // Echoing request
+        //assertNotNull(out.getOriginalRequest());
+    }
+
+    @Test
+    @Ignore
+    public void testOutgoingToString() {
+        String s = out.toString();
+        //assertTrue(s.contains(out.getId()));
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.impl;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.appc.adapter.message.Consumer;
+import org.onap.appc.adapter.message.Producer;
+import org.onap.appc.listener.ListenerProperties;
+import org.powermock.reflect.Whitebox;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+/**
+ * Test the ProviderAdapter implementation.
+ */
+
+@RunWith(MockitoJUnitRunner.class)
+public class EventHandlerImplTest {
+
+    private TestEventHandlerImpl adapter;
+    private ListenerProperties properties;
+
+    @Mock
+    private Producer mockProducer;
+    @Mock
+    private Consumer mockConsumer;
+
+    private static final String PROP_FILE = "/org/onap/appc/default.properties";
+
+    private static final String MESSAGE_FILE = "/DCAEResponse.txt";
+
+    /**
+     * Setup the test environment.
+     */
+    @Before
+    public void setup() {
+        Properties allProps = new Properties();
+        try {
+            allProps.load(getClass().getResourceAsStream(PROP_FILE));
+            allProps.remove("appc.ClosedLoop.topic.read.filter");
+            properties = new ListenerProperties("appc.ClosedLoop", allProps);
+        } catch (IOException e) {
+            System.out.println("WARNING: Failed to load properties file: " + PROP_FILE);
+        }
+        adapter = new TestEventHandlerImpl(properties);
+        adapter.setConsumer(mockConsumer);
+        adapter.setProducer(mockProducer);
+    }
+
+    @Test
+    public void testInitialProperties() {
+        assertEquals(properties.getProperty("topic.read"), adapter.getReadTopic());
+        assertTrue(adapter.getWriteTopic().equals(properties.getProperty("topic.write")));
+        assertEquals(properties.getProperty("client.name"), adapter.getClientName());
+        assertEquals(properties.getProperty("client.name.id"), adapter.getClientId());
+
+        String hostStr = properties.getProperty("poolMembers");
+        int hostCount = hostStr.length() > 0 ? hostStr.split(",").length : 0;
+        assertEquals(hostCount, adapter.getPool().size());
+    }
+
+    @Test
+    public void testGettersAndSetters() {
+        String readTopic = "read";
+        String writeTopic = "write";
+        String clientName = "APPC-TEST";
+        String clientId = "00";
+        String newHost = "google.com";
+
+        adapter.setReadTopic(readTopic);
+        assertEquals(readTopic, adapter.getReadTopic());
+
+        adapter.setWriteTopic(writeTopic);
+        assertEquals(writeTopic, adapter.getWriteTopic());
+
+        adapter.setClientName(clientName);
+        assertEquals(clientName, adapter.getClientName());
+
+        adapter.setClientId(clientId);
+        assertEquals(clientId, adapter.getClientId());
+
+        adapter.setCredentials("fake", "secret");
+        adapter.clearCredentials();
+
+        int oldSize = adapter.getPool().size();
+        adapter.addToPool(newHost);
+        assertEquals(oldSize + 1, adapter.getPool().size());
+        assertTrue(adapter.getPool().contains(newHost));
+
+        adapter.removeFromPool(newHost);
+        assertEquals(oldSize, adapter.getPool().size());
+        assertFalse(adapter.getPool().contains(newHost));
+
+    }
+
+    @Test
+    public void getIncomingEvents_should_success_when_no_errors_encountered() {
+
+        List<String> testResult = newArrayList("test-result1", "test-result2", "test-result3");
+        when(mockConsumer.fetch(anyInt(), anyInt())).thenReturn(testResult);
+
+        List<String> result = adapter.getIncomingEvents(5);
+
+        for (int i = 0; i < testResult.size(); i++) {
+            assertEquals(testResult.get(i), result.get(i));
+        }
+    }
+
+
+    @Test
+    public void postStatus_should_success_when_no_errors_encountered() {
+
+        adapter.postStatus("test-partition", "test-event");
+        verify(mockProducer).post("test-partition", "test-event");
+
+        adapter.postStatus("test-event");
+        verify(mockProducer).post(null, "test-event");
+    }
+
+
+    @Test
+    public void closeClients_should_close_producer_and_consumer() {
+        adapter.getIncomingEvents(5);
+        adapter.postStatus("test-partition", "test-event");
+
+        adapter.closeClients();
+        verify(mockConsumer).close();
+        verify(mockProducer).close();
+    }
+
+    @Test
+    public void testGetEvents() {
+        EventHandlerImpl adapter = new EventHandlerImpl(properties);
+        Consumer consumer = Mockito.mock(Consumer.class);
+        Mockito.when(consumer.fetch(Mockito.anyInt(), Mockito.anyInt()))
+            .thenReturn(new ArrayList<String>(Arrays.asList("TEST1")));
+        Whitebox.setInternalState(adapter, "reader", consumer);
+        assertEquals("TEST1", adapter.getIncomingEvents().get(0));
+    }
+
+    @Test
+    public void testGetEventsClass() {
+        EventHandlerImpl adapter = new EventHandlerImpl(properties);
+        Consumer consumer = Mockito.mock(Consumer.class);
+        Mockito.when(consumer.fetch(Mockito.anyInt(), Mockito.anyInt()))
+            .thenReturn(new ArrayList<String>(Arrays.asList("1")));
+        Whitebox.setInternalState(adapter, "reader", consumer);
+        assertEquals(Integer.valueOf(1), adapter.getIncomingEvents(Integer.class).get(0));
+    }
+
+    @Test
+    public void testSetters() {
+        EventHandlerImpl adapter = new EventHandlerImpl(properties);
+        adapter.setResponseProblemBlacklistTime("1");
+        assertEquals("1", Whitebox.getInternalState(adapter, "responseProblemBlacklistTime"));
+        adapter.setServerProblemBlacklistTime("1");
+        assertEquals("1", Whitebox.getInternalState(adapter, "serverProblemBlacklistTime"));
+        adapter.setDnsIssueBlacklistTime("1");
+        assertEquals("1", Whitebox.getInternalState(adapter, "dnsIssueBlacklistTime"));
+        adapter.setIOExceptionBlacklistTime("1");
+        assertEquals("1", Whitebox.getInternalState(adapter, "ioExceptionBlacklistTime"));
+    }
+
+//    @Test
+    public void testRun() {
+        EventHandlerImpl adapter = new EventHandlerImpl(properties);
+
+        // Runoff any old data
+        List<String> result = adapter.getIncomingEvents();
+        assertNotNull(result);
+
+        // Post new data
+        DummyObj data = new DummyObj();
+        data.key = "value";
+        adapter.postStatus(data.toJson());
+
+        // Wait to account for network delay
+        sleep(2000);
+
+        // Get data back
+        List<DummyObj> result2 = adapter.getIncomingEvents(DummyObj.class);
+        assertNotNull(result2);
+//        assertEquals(1, result2.size());
+        assertEquals(data.toJson(), result2.get(0).toJson());
+    }
+
+    private class TestEventHandlerImpl extends EventHandlerImpl {
+
+        private Consumer mockConsumer;
+        private Producer mockProducer;
+
+        private TestEventHandlerImpl(ListenerProperties props) {
+            super(props);
+        }
+
+        @Override
+        protected Consumer getConsumer() {
+            return mockConsumer;
+        }
+
+        @Override
+        protected Producer getProducer() {
+            return mockProducer;
+        }
+
+        private void setConsumer(Consumer consumer) {
+            mockConsumer = consumer;
+        }
+
+        private void setProducer(Producer producer) {
+            mockProducer = producer;
+        }
+    }
+
+    @JsonSerialize
+    public static class DummyObj implements Serializable {
+
+        @JsonProperty("request") // Call request for default filter
+        public String key;
+
+        public DummyObj() {
+        }
+
+        public String toJson() {
+            return String.format("{\"request\": \"%s\"}", key);
+        }
+    }
+
+    private void sleep(long ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (Exception e) {
+            return;
+        }
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Modifications Copyright (C) 2019 IBM
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.impl;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
+import org.onap.appc.listener.Controller;
+import org.onap.appc.listener.Listener;
+import org.onap.appc.listener.ListenerProperties;
+import org.onap.appc.listener.demo.impl.ListenerImpl;
+import org.powermock.reflect.Whitebox;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class TestController {
+
+    private ListenerProperties listenerProperties;
+    private Set<ListenerProperties> properties = Mockito.spy(new HashSet<>());
+    private EELFLogger log = Mockito.spy(EELFManager.getInstance().getLogger(ControllerImpl.class));
+
+    @Rule
+    public ExpectedException expectedEx = ExpectedException.none();
+
+    @Test
+    public void testExceptionConstructor() {
+        listenerProperties = Mockito.mock(ListenerProperties.class);
+        properties.add(listenerProperties);
+        new ControllerImpl(properties);
+        Mockito.verify(properties).remove(Mockito.any());
+    }
+    
+    @Test
+    public void testListeners() {
+        listenerProperties = Mockito.mock(ListenerProperties.class);
+        properties.add(listenerProperties);
+        assertTrue(new ControllerImpl(properties).getListeners() instanceof Map);
+        
+    }
+
+    @Test
+    public void testStartException() throws NoSuchMethodException, SecurityException {
+        Properties props = new Properties();
+        props.put("TEST", "TEST");
+        listenerProperties = Mockito.spy(new ListenerProperties("TEST", props));
+        listenerProperties.setListenerClass(Listener.class);
+        properties.add(listenerProperties);
+        ControllerImpl controllerImpl = new ControllerImpl(properties);
+        controllerImpl.start();
+        Mockito.verify(listenerProperties, Mockito.times(2)).getListenerClass();
+    }
+
+    @Test
+    public void testStopException() throws NoSuchMethodException, SecurityException, InterruptedException {
+        Properties props = new Properties();
+        props.put("TEST", "TEST");
+        listenerProperties = Mockito.spy(new ListenerProperties("TEST", props));
+        listenerProperties.setListenerClass(Listener.class);
+        properties.add(listenerProperties);
+        ControllerImpl controllerImpl = new ControllerImpl(properties);
+        //controllerImpl.start();
+        Map<String, Listener> map = Whitebox.getInternalState(controllerImpl, "listeners");
+        map.put("TEST", new ListenerImpl(listenerProperties));
+        ThreadPoolExecutor executor = Mockito.mock(ThreadPoolExecutor.class);
+        Mockito.when(executor.awaitTermination(300, TimeUnit.SECONDS)).thenReturn(false);
+        Whitebox.setInternalState(controllerImpl, "executor", executor);
+        controllerImpl.stop(false);
+        Mockito.verify(executor).shutdown();
+    }
+}
 
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 Ericsson
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.util;
+
+import static org.junit.Assert.assertTrue;
+import org.apache.http.client.HttpClient;
+import org.junit.Test;
+import org.onap.appc.exceptions.APPCException;
+
+public class HttpClientUtilTest {
+
+    @Test
+    public void testHttps() throws APPCException {
+        assertTrue(HttpClientUtil.getHttpClient("https") instanceof HttpClient);
+    }
+
+    @Test
+    public void testHttp() throws APPCException {
+        assertTrue(HttpClientUtil.getHttpClient("http") instanceof HttpClient);
+    }
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.listener.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.appc.listener.util.Mapper;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class TestMapper {
+
+    private String dummyJson = "{\"a\":\"%s\"}";
+    private DummyObj dummyObj = new DummyObj();
+
+    @JsonSerialize
+    public static class DummyObj implements Serializable {
+        @JsonProperty("a")
+        public String a;
+
+        public DummyObj() {
+        }
+    }
+
+    @Before
+    public void setup() {
+    }
+
+    @Test
+    public void testGetMapper() {
+        assertNotNull(Mapper.getMapper());
+    }
+
+    @Test
+    public void testToJsonObject() {
+        JSONObject out;
+        out = Mapper.toJsonObject(".");
+        assertNull(out);
+
+        String value = "b";
+        out = Mapper.toJsonObject(String.format(dummyJson, value));
+        assertNotNull(out);
+        assertEquals(value, out.get("a"));
+    }
+
+    @Test
+    public void testConstructor() {
+        // Only here for code coverage
+        Mapper m = new Mapper();
+        assertNotNull(m);
+    }
+
+    @Test
+    public void testMap() {
+        List<String> in = new ArrayList<String>();
+        in.add("");
+        in.add(null);
+
+        List<DummyObj> out = Mapper.mapList(in, DummyObj.class);
+        assertNotNull(out);
+        assertTrue(out.isEmpty());
+
+        in.add(String.format(dummyJson, "1"));
+        in.add("{\"invalid\":\"yes\"}");
+        in.add(String.format(dummyJson, "2"));
+
+        out = Mapper.mapList(in, DummyObj.class);
+        assertNotNull(out);
+        assertEquals(2, out.size());
+        assertEquals("1", out.get(0).a);
+        assertEquals("2", out.get(1).a);
+    }
+
+    @Test
+    public void testToJsonString() {
+        JSONObject jsonObject = Mockito.mock(JSONObject.class);
+        assertTrue(Mapper.toJsonString(jsonObject).startsWith("Mock for JSONObject"));
+    }
+
+    @Test
+    public void testToJsonStringNonJsonObject() {
+        assertEquals("\"TEST\"", Mapper.toJsonString("TEST"));
+    }
+
+    @Test
+    public void testToJsonStringException() {
+        assertNull(Mapper.toJsonString(new Mapper()));
+    }
+
+    @Test
+    public void testToJsonNodeFromJsonStringException() {
+        assertNull(Mapper.toJsonNodeFromJsonString("{{}"));
+    }
+
+    @Test
+    public void testToJsonNode() {
+        assertTrue(Mapper.toJsonNode(dummyObj) instanceof JsonNode);
+    }
+}
 
--- /dev/null
+{
+  "CommonHeader": {
+    "TimeStamp": "0000-00-00T00:00:00.000Z",
+    "APIver": "1.01",
+    "OriginatorID": "policy.pdp01",
+    "RequestID": "b74d13c5-bb26-4b04-992c-4679dfc8280e",
+    "SubRequestID": "1"
+  },
+  "Action": "RESTART",
+  "Payload": {
+    "VServerSelfLink": "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345",
+    "VNF_NAME": "test",
+    "VMID": "abc12345-1234-5678-890a-abcdefg12345",
+    "TenantID": "abcde12345fghijk6789lmnopq123rst",
+    "LOC_ID": "Test",
+    "in-maint": "false",
+    "Identity": "http://example.com:5000/v2.0",
+    "Prov_status": "ACTIVE",
+    "OAM_IPV4": "192.168.1.2",
+    "is-closed-loop-disabled": "false",
+    "VM_NAME": "test",
+    "OAM_IPV6": "0000::0000:0000:0000:0000/64"
+  }
+}
 
--- /dev/null
+{
+  "CommonHeader": {
+    "TimeStamp": "0000-00-00T00:00:00.000Z",
+    "APIver": "1.01",
+    "OriginatorID": "policy.pdp01",
+    "RequestID": "b74d13c5-bb26-4b04-992c-4679dfc8280e",
+    "SubRequestID": "1"
+  },
+  "Status": {
+    "Code": 100,
+    "Value": "ACCEPT"
+  },
+  "Payload": {
+    "VServerSelfLink": "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345",
+    "VNF_NAME": "test",
+    "VMID": "abc12345-1234-5678-890a-abcdefg12345",
+    "TenantID": "abcde12345fghijk6789lmnopq123rst",
+    "LOC_ID": "Test",
+    "in-maint": "false",
+    "Identity": "http://example.com:5000/v2.0",
+    "Prov_status": "ACTIVE",
+    "OAM_IPV4": "192.168.1.2",
+    "is-closed-loop-disabled": "false",
+    "VM_NAME": "test",
+    "OAM_IPV6": "0000::0000:0000:0000:0000/64"
+  }
+}
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+
+
+
+
+###                                                                                                                                                                        ###
+###                                                                                                                                                                        ###
+###Properties below are default values to be provided with real valuesin appc.properties###
+###                                                                                                                                                                        ###
+###                                                                                                                                                                        ###
+
+
+
+
+
+###                                                    ###
+###Closed Loop - properties ###
+###                                                    ###
+test.prefix=appc.ClosedLoop
+appc.ClosedLoop.disabled=false
+appc.ClosedLoop.service=dmaap
+appc.ClosedLoop.poolMembers=192.168.1.2:3904
+appc.ClosedLoop.topic.read=APPC-TEST1
+appc.ClosedLoop.topic.read.timeout=5
+appc.ClosedLoop.topic.write=APPC-TEST1
+appc.ClosedLoop.topic.read.filter={"class":"Assigned","field":"request"}
+appc.ClosedLoop.client.name=APPC-TEST1-CLOSED-LOOP
+appc.ClosedLoop.client.name.id=0
+
+# KEY AND SECRET BELOW NEED TO BE MODIFIED TO APPROPRIATE VALUES WHEN THE TOPIC IS API-KEY-BASED AUTH
+appc.ClosedLoop.client.key=MY_API_KEY
+appc.ClosedLoop.client.secret=MY_API_SECRET
+
+appc.ClosedLoop.threads.queuesize.min=1
+appc.ClosedLoop.threads.queuesize.max=1000
+appc.ClosedLoop.threads.poolsize.min=1
+appc.ClosedLoop.threads.poolsize.max=2
+appc.ClosedLoop.provider.url=https://admin:password@localhost:8443/restconf/operations/appc-provider:topology-operation
+appc.ClosedLoop.topic.responseProblem.blacklistTime=60
+appc.ClosedLoop.topic.serverError.blacklistTime=60
+appc.ClosedLoop.topic.dnsIssue.blacklistTime=60
+appc.ClosedLoop.topic.ioException.blacklistTime=60
+
+
+
+
+###                                                          ###
+###Closed Loop - 1607 properties  ###
+###                                                              ###
+appc.ClosedLoop1607.poolMembers=192.168.1.2:3904
+appc.ClosedLoop1607.topic.read=MY_DMAAP_TOPIC
+appc.ClosedLoop1607.topic.write=MY_DMAAP_TOPIC
+appc.ClosedLoop1607.topic.read.filter={"class":"Unassigned","field":"Status"}
+appc.ClosedLoop1607.client.name=DMAAP-CLIENT-NAME
+appc.ClosedLoop1607.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+appc.ClosedLoop1607.threads.queuesize.min=1
+appc.ClosedLoop1607.threads.queuesize.max=1000
+appc.ClosedLoop1607.threads.poolsize.min=1
+appc.ClosedLoop1607.threads.poolsize.max=2
+appc.ClosedLoop1607.provider.url=https://admin:password@localhost:8443/restconf/operations/appc-provider:topology-operation
+
+###                                                          ###
+### LCM properties                ###
+###                                                              ###
+appc.LCM.disabled=true
+appc.LCM.poolMembers=192.168.1.2:3904
+appc.LCM.topic.read=MY_DMAAP_TOPIC
+appc.LCM.topic.write=MY_DMAAP_TOPIC
+appc.LCM.topic.read.filter={"class":"Unassigned","field":"Status"}
+appc.LCM.client.name=DMAAP-CLIENT-NAME
+appc.LCM.client.name.id=0
+appc.LCM.threads.queuesize.min=1
+appc.LCM.threads.queuesize.max=1000
+appc.LCM.threads.poolsize.min=1
+appc.LCM.threads.poolsize.max=2
+appc.LCM.provider.url=https://admin:password@localhost:8443/restconf/operations/appc-provider:topology-operation
+
+###                                                          ###
+### DEMO properties               ###
+###                                                              ###
+appc.demo.poolMembers=192.168.1.2:3904
+appc.demo.topic.read=MY_DMAAP_TOPIC
+appc.demo.topic.write=MY_DMAAP_TOPIC
+appc.demo.topic.read.filter={"class":"Unassigned","field":"Status"}
+appc.demo.client.name=DMAAP-CLIENT-NAME
+appc.demo.client.name.id=0
+appc.demo.threads.queuesize.min=1
+appc.demo.threads.queuesize.max=1000
+appc.demo.threads.poolsize.min=1
+appc.demo.threads.poolsize.max=2
+
+# OAM Listener
+#########################
+appc.OAM.disabled=false
+appc.OAM.poolMembers=192.168.1.2:3904
+appc.OAM.topic.read=OAM_TOPIC
+appc.OAM.topic.write=OAM_TOPIC
+appc.OAM.client.name=OAM_CLIENT
+#appc.OAM.provider.url=
+#appc.OAM.provider.user=m97292@appc.att.com
+#appc.OAM.provider.pass=enc:DBE7PBN7EAN+Pwom
+
+appc.demo.provider.url=https://admin:password@localhost:8443/restconf/operations/appc-provider:topology-operation
\ No newline at end of file
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+
+
+
+
+###                                                                                                                                                                        ###
+###                                                                                                                                                                        ###
+###Properties below are default values to be provided with real valuesin appc.properties###
+###                                                                                                                                                                        ###
+###                                                                                                                                                                        ###
 
--- /dev/null
+/target-ide/
 
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+  Copyright (C) 2017 Amdocs
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.onap.appc.parent</groupId>
+               <artifactId>binding-parent</artifactId>
+               <version>2.6.2</version>
+                <relativePath />
+       </parent>
+
+        <groupId>org.onap.appc.services.dmaap</groupId>
+       <artifactId>appc-message-adapter-api</artifactId>
+       <packaging>jar</packaging>
+       <name>appc-message-adapter-api</name>
+
+       <dependencies>
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <scope>test</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-core</artifactId>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.osgi</groupId>
+                       <artifactId>org.osgi.core</artifactId>
+                       <scope>provided</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-api-mockito</artifactId>
+                       <scope>test</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-junit4</artifactId>
+                       <scope>test</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.onap.ccsdk.sli.core</groupId>
+                       <artifactId>sli-common</artifactId>
+                       <scope>compile</scope>
+                       <!-- Added exclusion to prevent missing dependency issue on dblib -->
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.onap.ccsdk.sli.core</groupId>
+                                       <artifactId>dblib-provider</artifactId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.onap.ccsdk.sli.core</groupId>
+                       <artifactId>sli-provider</artifactId>
+                       <scope>compile</scope>
+                       <!-- Added exclusion to prevent missing dependency issue on dblib -->
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.onap.ccsdk.sli.core</groupId>
+                                       <artifactId>dblib-provider</artifactId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+
+       </dependencies>
+
+       <version>1.7.0-SNAPSHOT</version>
+</project>
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.message;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class CallableConsumer implements Callable<List<String>> {
+
+    private Consumer consumer;
+
+    private int timeout = 15000;
+    private int limit = 1000;
+
+    public CallableConsumer(Consumer c) {
+        this.consumer = c;
+    }
+
+    public CallableConsumer(Consumer c, int waitMs, int fetchSize) {
+        this.consumer = c;
+        this.timeout = waitMs;
+        this.limit = fetchSize;
+    }
+
+    @Override
+    public List<String> call() {
+        return consumer.fetch(timeout, limit);
+    }
+
+    /**
+     * The maximum amount of time to keep a connection alive. Currently is set to waitMs + 10s
+     *
+     * @return An integer representing the maximum amount of time to keep this thread alive
+     */
+    public int getMaxLife() {
+        return 10000 + timeout;
+    }
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.message;
+
+import java.util.List;
+
+public interface Consumer {
+
+    /**
+     * Gets a batch of messages from the topic. Defaults to 1000 messages with 15s wait for messages if empty.
+     *
+     * @return A list of strings representing the messages pulled from the topic.
+     */
+    List<String> fetch();
+
+    /**
+     * Gets a batch of messages from the topic.
+     *
+     * @param waitMs
+     *            The amount of time to wait in milliseconds if the topic is empty for data to be written. Should be no
+     *            less than 15000ms to prevent too many requests
+     * @param limit
+     *            The amount of messages to fetch
+     * @return A list of strings representing the messages pulled from the topic.
+     */
+    List<String> fetch(int waitMs, int limit);
+
+    /**
+     * Updates the api credentials for making authenticated requests.
+     *
+     * @param apiKey
+     *            The public key to authenticate with
+     * @param apiSecret
+     *            The secret key to authenticate with
+     */
+    void updateCredentials(String apiKey, String apiSecret);
+
+    /**
+     * Creates a dmaap client using a https connection
+     *
+     * @param yes
+     *            True if https should be used, false otherwise.
+     */
+    default void useHttps(boolean yes) {}
+
+    /**
+     *  Sets Blacklist time for a server with response problem in seconds
+     */
+    default void setResponseProblemBlacklistTime(String duration) {}
+
+    /**
+     *  Sets Blacklist time for a server with server problem in seconds
+     */
+    default void setServerProblemBlacklistTime(String duration) {}
+
+    /**
+     *  Sets Blacklist time for a server with DNS problem in seconds
+     */
+    default void setDnsIssueBlacklistTime(String duration) {}
+
+    /**
+     *  Sets Blacklist time for a server with IO Exception problem in seconds
+     */
+    default void setIOExceptionBlacklistTime(String duration) {}
+
+    /**
+     * Closes the dmaap client https connection.
+     */
+    default void close() {}
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.message;
+
+import java.util.Set;
+
+public interface Manager {
+
+    /**
+     * Updates the api credentials for making authenticated requests
+     * 
+     * @param apiKey
+     *            The public key to authenticate with
+     * @param apiSecret
+     *            The secret key to authenticate with
+     */
+    public void updateCredentials(String apiKey, String apiSecret);
+
+    /**
+     * Return a set of strings representing topics that the user can see
+     *
+     * @return A set of strings with topic names or an empty set if no topics are visible
+     */
+    public Set<String> getTopics();
+
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.appc.adapter.message;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.onap.appc.adapter.message.Consumer;
+import org.onap.appc.adapter.message.Producer;
+
+public interface MessageAdapterFactory {
+       
+       // TODO: how do you configure the MessageService type?
+       
+       public Producer createProducer(Collection<String> pools, String writeTopic, String apiKey, String apiSecret);
+       
+       public Producer createProducer(Collection<String> pools, Set<String> writeTopics, String apiKey, String apiSecret);
+
+       public Consumer createConsumer(Collection<String> pool, String readTopic, 
+                                                     String clientName, String clientId, String filter_json, String apiKey, String apiSecret);
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.message;
+
+public enum MessageDestination {
+    DCAE
+}
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.message;
+
+public interface Producer {
+
+    boolean post(String partition, String data);
+
+    /**
+     * Updates the api credentials for making authenticated requests.
+     *
+     * @param apiKey
+     *            The public key to authenticate with
+     * @param apiSecret
+     *            The secret key to authenticate with
+     */
+    void updateCredentials(String apiKey, String apiSecret);
+
+    /**
+     * Creates a dmaap client using a https connection.
+     *
+     * @param yes
+     *            True if https should be used, false otherwise
+     */
+    default void useHttps(boolean yes) {}
+
+    /**
+     *  Sets Blacklist time for a server with response problem in seconds
+     */
+    default void setResponseProblemBlacklistTime(String duration) { }
+
+    /**
+     *  Sets Blacklist time for a server with server problem in seconds
+     */
+    default void setServerProblemBlacklistTime(String duration) {}
+
+    /**
+     *  Sets Blacklist time for a server with DNS problem in seconds
+     */
+    default void setDnsIssueBlacklistTime(String duration) {}
+
+    /**
+     *  Sets Blacklist time for a server with IO Exception problem in seconds
+     */
+    default void setIOExceptionBlacklistTime(String duration) {}
+
+
+    /**
+     * Closes the dmaap client https connection.
+     */
+    default void close() {}
+
+}
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+org.onap.appc.bootstrap.file=appc.properties
+org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},.
 
--- /dev/null
+/*
+ * ============LICENSE_START==========================================
+ *  org.onap.music
+ * ===================================================================
+ *  Copyright (c) 2019 IBM.
+ * ===================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * 
+ * ============LICENSE_END=============================================
+ * ====================================================================
+ */
+package org.onap.appc.adapter.message;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TestCallableConsumer {
+
+    CallableConsumer callableConsumer;
+
+    @Mock
+    private Consumer consumer;
+
+    private List<String> list;
+    private int waitMs = 15000;
+    private int limit = 1000;
+    private int maxLife = 25000;
+
+    @Before
+    public void setUp() {
+        list = new ArrayList<String>();
+        callableConsumer = new CallableConsumer(consumer, waitMs, limit);
+    }
+
+    @Test
+    public void testCallableConsumer() {
+        CallableConsumer callableConsumer = new CallableConsumer(consumer);
+        Mockito.when(consumer.fetch()).thenReturn(list);
+        assertEquals(list, callableConsumer.call());
+    }
+
+    @Test
+    public void testCall() {
+        Mockito.when(consumer.fetch()).thenReturn(list);
+        assertEquals(list, callableConsumer.call());
+    }
+
+    @Test
+    public void testGetMaxLife() {
+        assertEquals(maxLife, callableConsumer.getMaxLife());
+    }
+
+}
 
--- /dev/null
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ============LICENSE_END=========================================================
+*/
+package org.onap.appc.adapter.message;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestMessageDestination {
+
+    private MessageDestination messageDestination=MessageDestination.DCAE;
+
+    @Test
+    public void testName() {
+        Assert.assertEquals("DCAE", messageDestination.name());
+    }
+
+    @Test
+    public void testEqual() {
+        Assert.assertTrue(messageDestination.equals(MessageDestination.DCAE));
+        Assert.assertFalse(messageDestination.equals(null));
+    }
+}
 
--- /dev/null
+/target-ide/
 
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+  Copyright (C) 2017 Amdocs
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.onap.appc.parent</groupId>
+               <artifactId>binding-parent</artifactId>
+               <version>2.6.2</version>
+                <relativePath />
+       </parent>
+
+        <groupId>org.onap.appc.services.dmaap</groupId>
+       <artifactId>appc-message-adapter-factory</artifactId>
+       <packaging>jar</packaging>
+       <name>appc-message-adapter-factory</name>
+
+       <dependencies>
+
+               <dependency>
+                       <groupId>org.onap.appc.services.dmaap</groupId>
+                       <artifactId>appc-dmaap-adapter-bundle</artifactId>
+                       <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onap.appc.services.dmaap</groupId>
+            <artifactId>appc-message-adapter-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+               </dependency>
+               
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <scope>test</scope>
+               </dependency>
+
+
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-core</artifactId>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-api-mockito</artifactId>
+                       <scope>test</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-junit4</artifactId>
+                       <scope>test</scope>
+               </dependency>
+
+       </dependencies>
+
+       <version>1.7.0-SNAPSHOT</version>
+</project>
 
--- /dev/null
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * ONAP : APPC\r
+ * ================================================================================\r
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Copyright (C) 2017 Amdocs\r
+ * ================================================================================\r
+ * Modifications Copyright (C) 2019 Ericsson\r
+ * =============================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * \r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.appc.adapter.factory;\r
+\r
+import java.util.Collection;\r
+import java.util.Set;\r
+\r
+import org.onap.appc.adapter.message.Consumer;\r
+import org.onap.appc.adapter.message.MessageAdapterFactory;\r
+import org.onap.appc.adapter.message.Producer;\r
+import org.onap.appc.adapter.messaging.dmaap.http.HttpDmaapConsumerImpl;\r
+import org.onap.appc.adapter.messaging.dmaap.http.HttpDmaapProducerImpl;\r
+\r
+public class DmaapMessageAdapterFactoryImpl implements MessageAdapterFactory {\r
+\r
+\r
+    @Override\r
+    public Producer createProducer(Collection<String> pools, String writeTopic, String apiKey, String apiSecret) {\r
+        return  new  HttpDmaapProducerImpl(pools, writeTopic);\r
+    }\r
+\r
+    @Override\r
+    public Producer createProducer(Collection<String> pools, Set<String> writeTopics, String apiKey, String apiSecret) {\r
+        String topic = "";\r
+        for(String s : writeTopics){\r
+            topic = s;\r
+        }\r
+        return new HttpDmaapProducerImpl(pools, topic);\r
+    }\r
+\r
+    @Override\r
+    public Consumer createConsumer(Collection<String> pool, String readTopic, \r
+            String clientName, String clientId, String filterJson, String apiKey, String apiSecret) {\r
+        return new HttpDmaapConsumerImpl(pool, readTopic, clientName, clientId, apiKey, apiSecret, filterJson);\r
+    }\r
+}\r
 
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.factory;
+/**
+ * The message service types that are available. Only DMaaP available
+ **/
+public enum MessageService {
+    DMaaP("dmaap");
+
+    private String val;
+
+    private MessageService(String val) {
+        this.val = val;
+    }
+
+    public String getValue() {
+        return val;
+    }
+
+    /**
+     * Tries to match a string to a MessageService. If no match is found, returns the default (DMaaP)
+     *
+     * @param input
+     *            the string to try and match
+     * @return A MessasgeService
+     */
+    public static MessageService parse(String input) {
+        if (input != null) {
+            for (MessageService ms : MessageService.values()) {
+                if (input.equalsIgnoreCase(ms.getValue())) {
+                    return ms;
+                }
+            }
+        }
+        return MessageService.DMaaP; // Default
+    }
+}
 
--- /dev/null
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# ============LICENSE_END=========================================================
+###
+
+org.onap.appc.bootstrap.file=appc.properties
+org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},.
 
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 Ericsson
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.appc.adapter.factory;
+
+import static org.junit.Assert.assertTrue;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.appc.adapter.message.Consumer;
+import org.onap.appc.adapter.message.Producer;
+
+public class DmaapMessageAdapterFactoryImplTest {
+
+    private DmaapMessageAdapterFactoryImpl factory;
+    private Collection<String> pools;
+
+    @Before
+    public void setup() {
+        factory = new DmaapMessageAdapterFactoryImpl();
+        pools = new ArrayList<>();
+        pools.add("http://server:1");
+    }
+
+    @Test
+    public void testCreateProducer() {
+        Set<String> writeTopics = new HashSet<>();
+        assertTrue(factory.createProducer(pools, writeTopics, null, null) instanceof Producer);
+        assertTrue(factory.createProducer(pools, "TEST" , null, null) instanceof Producer);
+    }
+
+    @Test
+    public void testCreateConsumer() {
+        assertTrue(factory.createConsumer(pools, "TEST", null, null, null, null, null) instanceof Consumer);
+    }
+
+}
 
--- /dev/null
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ============LICENSE_END=========================================================
+*/
+package org.onap.appc.adapter.factory;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MessageServiceTest {
+
+    private MessageService messageService = MessageService.DMaaP;
+
+    @Test
+    public void testName() {
+        Assert.assertEquals("DMaaP", messageService.name());
+    }
+
+    @Test
+    public void testGetValue() {
+        Assert.assertEquals("dmaap", messageService.getValue());
+    }
+
+    @Test
+    public void testParse() {
+        Assert.assertEquals(messageService, MessageService.parse("DMAAP"));
+    }
+
+    @Test
+    public void testParse_Null() {
+        Assert.assertEquals(MessageService.DMaaP, MessageService.parse(null));
+    }
+
+}
 
--- /dev/null
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.onap.appc.services.dmaap</groupId>
+  <artifactId>dmaap-service</artifactId>
+  <packaging>pom</packaging>
+  <version>1.7.0-SNAPSHOT</version>
+  <name>appc-dmaap-service</name>
+  <url>http://maven.apache.org</url>
+  <modules>
+  <module>appc-dmaap-adapter-bundle</module>
+  <module>appc-message-adapter-api</module>
+  <module>appc-message-adapter-factory</module>
+  <module>appc-event-listener-bundle</module>
+  <module>appc-dmaap-event-service</module>
+  </modules>
+  
+  <properties>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+  </properties>
+
+</project>
 
--- /dev/null
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.onap.appc.services</groupId>
+  <artifactId>appc-services-root</artifactId>
+  <packaging>pom</packaging>
+  <version>1.7.0-SNAPSHOT</version>
+  <name>appc-services-root</name>
+  <modules>
+  <module>appc-dmaap-service</module>
+  </modules>
+
+  <properties>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+  </properties>
+
+  <parent>
+      <groupId>org.onap.appc</groupId>
+      <artifactId>appc</artifactId>
+      <version>1.7.0-SNAPSHOT</version>
+  </parent>
+</project>