diff options
Diffstat (limited to 'services/appc-dmaap-service/appc-event-listener-bundle')
68 files changed, 7908 insertions, 0 deletions
diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/.gitignore b/services/appc-dmaap-service/appc-event-listener-bundle/.gitignore new file mode 100644 index 000000000..8d27d5a75 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/.gitignore @@ -0,0 +1,28 @@ +# ============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/ diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/pom.xml b/services/appc-dmaap-service/appc-event-listener-bundle/pom.xml new file mode 100644 index 000000000..0d02b2155 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/pom.xml @@ -0,0 +1,141 @@ +<?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> diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/AbstractListener.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/AbstractListener.java new file mode 100644 index 000000000..b9e8a6c84 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/AbstractListener.java @@ -0,0 +1,158 @@ +/*- + * ============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)); + } + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/AppcEventListenerActivator.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/AppcEventListenerActivator.java new file mode 100644 index 000000000..5c6fd4c67 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/AppcEventListenerActivator.java @@ -0,0 +1,196 @@ +/*- + * ============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(); + } + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/Controller.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/Controller.java new file mode 100644 index 000000000..25f4735a2 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/Controller.java @@ -0,0 +1,57 @@ +/*- + * ============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(); + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/EventHandler.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/EventHandler.java new file mode 100644 index 000000000..35052a085 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/EventHandler.java @@ -0,0 +1,208 @@ +/*- + * ============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(); + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/conv/Converter.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/conv/Converter.java new file mode 100644 index 000000000..8222af13f --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/conv/Converter.java @@ -0,0 +1,139 @@ +/*- + * ============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; + } + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/impl/ListenerImpl.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/impl/ListenerImpl.java new file mode 100644 index 000000000..761d65231 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/impl/ListenerImpl.java @@ -0,0 +1,156 @@ +/*- + * ============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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/impl/WorkerImpl.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/impl/WorkerImpl.java new file mode 100644 index 000000000..870871da3 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/impl/WorkerImpl.java @@ -0,0 +1,136 @@ +/*- + * ============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); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/ActionIdentifiers.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/ActionIdentifiers.java new file mode 100644 index 000000000..a7a2795d4 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/ActionIdentifiers.java @@ -0,0 +1,83 @@ +/*- + * ============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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/CommonHeader.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/CommonHeader.java new file mode 100644 index 000000000..b7933184c --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/CommonHeader.java @@ -0,0 +1,116 @@ +/*- + * ============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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/DmaapIncomingMessage.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/DmaapIncomingMessage.java new file mode 100644 index 000000000..3607fd719 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/DmaapIncomingMessage.java @@ -0,0 +1,52 @@ +/*- + * ============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()+"}"; + } +} + diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/DmaapMessage.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/DmaapMessage.java new file mode 100644 index 000000000..8703b0d75 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/DmaapMessage.java @@ -0,0 +1,116 @@ +/*- + * ============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 + + '}'; + } +} + diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/DmaapOutgoingMessage.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/DmaapOutgoingMessage.java new file mode 100644 index 000000000..b24043971 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/DmaapOutgoingMessage.java @@ -0,0 +1,51 @@ +/*- + * ============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()+"}"; + } +} + diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/InputBody.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/InputBody.java new file mode 100644 index 000000000..0c70d643c --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/InputBody.java @@ -0,0 +1,89 @@ +/*- + * ============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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/OutputBody.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/OutputBody.java new file mode 100644 index 000000000..a42174dc2 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/OutputBody.java @@ -0,0 +1,100 @@ +/*- + * ============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()); + } +} + diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/ResponseStatus.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/ResponseStatus.java new file mode 100644 index 000000000..6562bf9db --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/model/ResponseStatus.java @@ -0,0 +1,72 @@ +/*- + * ============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 + '\'' + + '}'; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/operation/GenericProviderOperationRequestFormatter.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/operation/GenericProviderOperationRequestFormatter.java new file mode 100644 index 000000000..ca0f52ac7 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/operation/GenericProviderOperationRequestFormatter.java @@ -0,0 +1,85 @@ +/*- + * ============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"); + } + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/operation/ProviderOperationRequestFormatter.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/operation/ProviderOperationRequestFormatter.java new file mode 100644 index 000000000..e8a6ecbeb --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/operation/ProviderOperationRequestFormatter.java @@ -0,0 +1,44 @@ +/*- + * ============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; +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/operation/ProviderOperations.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/operation/ProviderOperations.java new file mode 100644 index 000000000..42206ec2e --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/LCM/operation/ProviderOperations.java @@ -0,0 +1,281 @@ +/*- + * ============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 diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/Listener.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/Listener.java new file mode 100644 index 000000000..f4b87bd25 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/Listener.java @@ -0,0 +1,74 @@ +/*- + * ============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); +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/ListenerProperties.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/ListenerProperties.java new file mode 100644 index 000000000..74ead9485 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/ListenerProperties.java @@ -0,0 +1,305 @@ +/*- + * ============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; + } + } + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/impl/ListenerImpl.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/impl/ListenerImpl.java new file mode 100644 index 000000000..d6909abf3 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/impl/ListenerImpl.java @@ -0,0 +1,131 @@ +/*- + * ============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; + } + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/impl/ProviderOperations.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/impl/ProviderOperations.java new file mode 100644 index 000000000..6cd2f2d76 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/impl/ProviderOperations.java @@ -0,0 +1,195 @@ +/*- + * ============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); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/impl/WorkerImpl.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/impl/WorkerImpl.java new file mode 100644 index 000000000..d9bf6d358 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/impl/WorkerImpl.java @@ -0,0 +1,84 @@ +/*- + * ============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); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/Action.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/Action.java new file mode 100644 index 000000000..6fc8ca0bc --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/Action.java @@ -0,0 +1,57 @@ +/*- + * ============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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/CommonMessage.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/CommonMessage.java new file mode 100644 index 000000000..e0dbbab67 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/CommonMessage.java @@ -0,0 +1,313 @@ +/*- + * ============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; + } + + }; + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/IncomingMessage.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/IncomingMessage.java new file mode 100644 index 000000000..bff1f3bc7 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/IncomingMessage.java @@ -0,0 +1,90 @@ +/*- + * ============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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/OutgoingMessage.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/OutgoingMessage.java new file mode 100644 index 000000000..100d55bf2 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/OutgoingMessage.java @@ -0,0 +1,202 @@ +/*- + * ============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(); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/Status.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/Status.java new file mode 100644 index 000000000..a4abeac60 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/demo/model/Status.java @@ -0,0 +1,71 @@ +/*- + * ============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; + } + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/impl/ControllerImpl.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/impl/ControllerImpl.java new file mode 100644 index 000000000..d1c5d61c2 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/impl/ControllerImpl.java @@ -0,0 +1,146 @@ +/*- + * ============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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/impl/EventHandlerImpl.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/impl/EventHandlerImpl.java new file mode 100644 index 000000000..117901ca1 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/impl/EventHandlerImpl.java @@ -0,0 +1,400 @@ +/*- + * ============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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/util/HttpClientUtil.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/util/HttpClientUtil.java new file mode 100644 index 000000000..2b8e887bf --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/util/HttpClientUtil.java @@ -0,0 +1,126 @@ +/*- + * ============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(); + } + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/util/Mapper.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/util/Mapper.java new file mode 100644 index 000000000..b9a6a4cc8 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/java/org/onap/appc/listener/util/Mapper.java @@ -0,0 +1,136 @@ +/*- + * ============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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/main/resources/org/onap/appc/default.properties b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/resources/org/onap/appc/default.properties new file mode 100644 index 000000000..ba4c5239a --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/main/resources/org/onap/appc/default.properties @@ -0,0 +1,113 @@ +### +# ============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 diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/AbstractListenerTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/AbstractListenerTest.java new file mode 100644 index 000000000..a47175c02 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/AbstractListenerTest.java @@ -0,0 +1,152 @@ +/*- + * ============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()) { + } + } + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/AppcEventListenerActivatorTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/AppcEventListenerActivatorTest.java new file mode 100644 index 000000000..0dc1d4d3f --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/AppcEventListenerActivatorTest.java @@ -0,0 +1,80 @@ +/*- + * ============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()); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/conv/ConverterTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/conv/ConverterTest.java new file mode 100644 index 000000000..037f91a6e --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/conv/ConverterTest.java @@ -0,0 +1,143 @@ +/*- + * ============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()); + } + + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/impl/ListenerImplTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/impl/ListenerImplTest.java new file mode 100644 index 000000000..900e9c5fc --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/impl/ListenerImplTest.java @@ -0,0 +1,97 @@ +/*- + * ============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()); + } + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/impl/WorkerImplTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/impl/WorkerImplTest.java new file mode 100644 index 000000000..e6d08fba7 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/impl/WorkerImplTest.java @@ -0,0 +1,78 @@ +/*- + * ============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()); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/ActionIdentifiersTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/ActionIdentifiersTest.java new file mode 100644 index 000000000..4c826b2d2 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/ActionIdentifiersTest.java @@ -0,0 +1,70 @@ +/*- + * ============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()); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/CommonHeaderTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/CommonHeaderTest.java new file mode 100644 index 000000000..7e834b28e --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/CommonHeaderTest.java @@ -0,0 +1,91 @@ +/*- + * ============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()); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/DmaapIncomingMessageTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/DmaapIncomingMessageTest.java new file mode 100644 index 000000000..40b88e5df --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/DmaapIncomingMessageTest.java @@ -0,0 +1,70 @@ +/*- + * ============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()); + } + + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/DmaapMessageTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/DmaapMessageTest.java new file mode 100644 index 000000000..0c204df88 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/DmaapMessageTest.java @@ -0,0 +1,83 @@ +/*- + * ============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()); + } +} + diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/DmaapOutgoingMessageTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/DmaapOutgoingMessageTest.java new file mode 100644 index 000000000..d3f72ee50 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/DmaapOutgoingMessageTest.java @@ -0,0 +1,68 @@ +/*- + * ============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()); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/InputBodyTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/InputBodyTest.java new file mode 100644 index 000000000..21a95955c --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/InputBodyTest.java @@ -0,0 +1,78 @@ +/*- + * ============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()); + } + + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/OutputBodyTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/OutputBodyTest.java new file mode 100644 index 000000000..27913284b --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/OutputBodyTest.java @@ -0,0 +1,95 @@ +/*- + * ============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")); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/ResponseStatusTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/ResponseStatusTest.java new file mode 100644 index 000000000..1283643bf --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/model/ResponseStatusTest.java @@ -0,0 +1,56 @@ +/*- + * ============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()); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/operation/GenericProviderOperationsRequestFormatterTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/operation/GenericProviderOperationsRequestFormatterTest.java new file mode 100644 index 000000000..a6d1bb9d1 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/operation/GenericProviderOperationsRequestFormatterTest.java @@ -0,0 +1,93 @@ +/*- + * ============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))); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/operation/ProviderOperationsTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/operation/ProviderOperationsTest.java new file mode 100644 index 000000000..fc6c14d16 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM/operation/ProviderOperationsTest.java @@ -0,0 +1,136 @@ +/*- + * ============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()); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM1607/model/TestJsonGenericMessages.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM1607/model/TestJsonGenericMessages.java new file mode 100644 index 000000000..b17789115 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/LCM1607/model/TestJsonGenericMessages.java @@ -0,0 +1,101 @@ +/*- + * ============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; + } +*/ +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/ListenerPropertiesTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/ListenerPropertiesTest.java new file mode 100644 index 000000000..c83555c50 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/ListenerPropertiesTest.java @@ -0,0 +1,156 @@ +/*- + * ============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()); + } + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/TestUtil.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/TestUtil.java new file mode 100644 index 000000000..f28ad83b5 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/TestUtil.java @@ -0,0 +1,82 @@ +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; + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/impl/TestProviderOperations.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/impl/TestProviderOperations.java new file mode 100644 index 000000000..55b0f2cb6 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/impl/TestProviderOperations.java @@ -0,0 +1,129 @@ +/*- + * ============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); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/impl/TestWorkerImpl.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/impl/TestWorkerImpl.java new file mode 100644 index 000000000..e3f889c5e --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/impl/TestWorkerImpl.java @@ -0,0 +1,85 @@ +/*- + * ============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(); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/OutgoingMessageTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/OutgoingMessageTest.java new file mode 100644 index 000000000..b2838cb77 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/OutgoingMessageTest.java @@ -0,0 +1,91 @@ +/* + * ============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()); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestCommonMessage.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestCommonMessage.java new file mode 100644 index 000000000..341492f26 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestCommonMessage.java @@ -0,0 +1,50 @@ +/*- + * ============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); + } + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestEnums.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestEnums.java new file mode 100644 index 000000000..2dbbdd64d --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestEnums.java @@ -0,0 +1,60 @@ +/*- + * ============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); + + } + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestIncomingMessage.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestIncomingMessage.java new file mode 100644 index 000000000..d8d0986ce --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestIncomingMessage.java @@ -0,0 +1,46 @@ +/*- + * ============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)); + } + +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestMessages.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestMessages.java new file mode 100644 index 000000000..9cce23d95 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/demo/model/TestMessages.java @@ -0,0 +1,199 @@ +/*- + * ============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())); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/impl/EventHandlerImplTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/impl/EventHandlerImplTest.java new file mode 100644 index 000000000..8f5ed6d74 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/impl/EventHandlerImplTest.java @@ -0,0 +1,279 @@ +/*- + * ============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; + } + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/impl/TestController.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/impl/TestController.java new file mode 100644 index 000000000..ccea14cef --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/impl/TestController.java @@ -0,0 +1,104 @@ +/*- + * ============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(); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/util/HttpClientUtilTest.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/util/HttpClientUtilTest.java new file mode 100644 index 000000000..084d51ed0 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/util/HttpClientUtilTest.java @@ -0,0 +1,40 @@ +/* + * ============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); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/util/TestMapper.java b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/util/TestMapper.java new file mode 100644 index 000000000..2a9483364 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/java/org/onap/appc/listener/util/TestMapper.java @@ -0,0 +1,135 @@ +/*- + * ============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); + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/IncomingMessagedemo.txt b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/IncomingMessagedemo.txt new file mode 100644 index 000000000..bd56e003d --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/IncomingMessagedemo.txt @@ -0,0 +1,24 @@ +{ + "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" + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/OutgoingMessagedemo.txt b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/OutgoingMessagedemo.txt new file mode 100644 index 000000000..af79c5aad --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/OutgoingMessagedemo.txt @@ -0,0 +1,27 @@ +{ + "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" + } +} diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/org/onap/appc/default.properties b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/org/onap/appc/default.properties new file mode 100644 index 000000000..c729c7b0a --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/org/onap/appc/default.properties @@ -0,0 +1,127 @@ +### +# ============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 diff --git a/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/org/onap/appc/empty.properties b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/org/onap/appc/empty.properties new file mode 100644 index 000000000..4b70a23c0 --- /dev/null +++ b/services/appc-dmaap-service/appc-event-listener-bundle/src/test/resources/org/onap/appc/empty.properties @@ -0,0 +1,32 @@ +### +# ============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### +### ### +### ### |