aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver')
-rw-r--r--plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/pom.xml59
-rw-r--r--plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerConsumer.java281
-rw-r--r--plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerProducer.java167
-rw-r--r--plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RESTServerCarrierTechnologyParameters.java136
-rw-r--r--plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RestServerEndpoint.java150
-rw-r--r--plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/package-info.java28
-rw-r--r--plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/test/resources/logback-test.xml50
7 files changed, 871 insertions, 0 deletions
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/pom.xml b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/pom.xml
new file mode 100644
index 000000000..643908932
--- /dev/null
+++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/pom.xml
@@ -0,0 +1,59 @@
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2018 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=========================================================
+-->
+<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.policy.apex-pdp.plugins.plugins-event.plugins-event-carrier</groupId>
+ <artifactId>plugins-event-carrier</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>plugins-event-carrier-restserver</artifactId>
+ <name>${project.artifactId}</name>
+ <description>[${project.parent.artifactId}] Plugin for handling events being transported over REST where Apex acts as a REST server</description>
+
+ <properties>
+ <apex-plugins-event-carrier-restserver-dir>${project.basedir}/src</apex-plugins-event-carrier-restserver-dir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.policy.apex-pdp.services</groupId>
+ <artifactId>services-engine</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-client</artifactId>
+ <version>${version.jersey.core}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-grizzly2-http</artifactId>
+ <version>${version.grizzly2-http}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-servlet-core</artifactId>
+ <version>2.25.1</version>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerConsumer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerConsumer.java
new file mode 100644
index 000000000..71bf80f66
--- /dev/null
+++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerConsumer.java
@@ -0,0 +1,281 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 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.policy.apex.plugins.event.carrier.restserver;
+
+import java.net.URI;
+import java.util.EnumMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.ws.rs.core.Response;
+
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.service.engine.event.ApexEventConsumer;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventReceiver;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements an Apex event consumer that receives events from a REST server.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexRestServerConsumer implements ApexEventConsumer, Runnable {
+ // Get a reference to the logger
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestServerConsumer.class);
+
+ private static final String BASE_URI_TEMPLATE = "http://%s:%d/apex";
+
+ // The amount of time to wait in milliseconds between checks that the consumer thread has stopped
+ private static final long REST_SERVER_CONSUMER_WAIT_SLEEP_TIME = 50;
+
+ // The REST parameters read from the parameter service
+ private RESTServerCarrierTechnologyParameters restConsumerProperties;
+
+ // The event receiver that will receive events from this consumer
+ private ApexEventReceiver eventReceiver;
+
+ // The name for this consumer
+ private String name = null;
+
+ // The peer references for this event handler
+ private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+ // The consumer thread and stopping flag
+ private Thread consumerThread;
+ private boolean stopOrderedFlag = false;
+
+ // The local HTTP server to use for REST call reception if we are running a local Grizzly server
+ private HttpServer server;
+
+ // Holds the next identifier for event execution.
+ private static AtomicLong nextExecutionID = new AtomicLong(0L);
+
+ /**
+ * Private utility to get the next candidate value for a Execution ID. This value will always be unique in a single
+ * JVM
+ *
+ * @return the next candidate value for a Execution ID
+ */
+ private static synchronized long getNextExecutionID() {
+ return nextExecutionID.getAndIncrement();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#init(java.lang.String,
+ * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters,
+ * org.onap.policy.apex.service.engine.event.ApexEventReceiver)
+ */
+ @Override
+ public void init(final String consumerName, final EventHandlerParameters consumerParameters,
+ final ApexEventReceiver incomingEventReceiver) throws ApexEventException {
+ this.eventReceiver = incomingEventReceiver;
+ this.name = consumerName;
+
+ // Check and get the REST Properties
+ if (!(consumerParameters.getCarrierTechnologyParameters() instanceof RESTServerCarrierTechnologyParameters)) {
+ final String errorMessage =
+ "specified consumer properties are not applicable to REST Server consumer (" + this.name + ")";
+ LOGGER.warn(errorMessage);
+ throw new ApexEventException(errorMessage);
+ }
+ restConsumerProperties =
+ (RESTServerCarrierTechnologyParameters) consumerParameters.getCarrierTechnologyParameters();
+
+ // Check if we are in synchronous mode
+ if (!consumerParameters.isPeeredMode(EventHandlerPeeredMode.SYNCHRONOUS)) {
+ final String errorMessage =
+ "REST Server consumer (" + this.name + ") must run in synchronous mode with a REST Server producer";
+ LOGGER.warn(errorMessage);
+ throw new ApexEventException(errorMessage);
+ }
+
+ // Check if we're in standalone mode
+ if (restConsumerProperties.isStandalone()) {
+ // Check if host and port are defined
+ if (restConsumerProperties.getHost() == null || restConsumerProperties.getPort() == -1) {
+ final String errorMessage =
+ "the parameters \"host\" and \"port\" must be defined for REST Server consumer (" + this.name
+ + ") in standalone mode";
+ LOGGER.warn(errorMessage);
+ throw new ApexEventException(errorMessage);
+ }
+
+ // Compose the URI for the standalone server
+ final String baseURI = String.format(BASE_URI_TEMPLATE, restConsumerProperties.getHost(),
+ restConsumerProperties.getPort());
+
+ // Instantiate the standalone server
+ final ResourceConfig rc = new ResourceConfig(RestServerEndpoint.class);
+ server = GrizzlyHttpServerFactory.createHttpServer(URI.create(baseURI), rc);
+
+ while (!server.isStarted()) {
+ ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+ }
+ }
+
+ // Register this consumer with the REST server end point
+ RestServerEndpoint.registerApexRestServerConsumer(this.name, this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#start()
+ */
+ @Override
+ public void start() {
+ // Configure and start the event reception thread
+ final String threadName = this.getClass().getName() + ":" + this.name;
+ consumerThread = new ApplicationThreadFactory(threadName).newThread(this);
+ consumerThread.setDaemon(true);
+ consumerThread.start();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getName()
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap.policy.apex.service.
+ * parameters. eventhandler.EventHandlerPeeredMode)
+ */
+ @Override
+ public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+ return peerReferenceMap.get(peeredMode);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap.policy.apex.service.
+ * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+ */
+ @Override
+ public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+ peerReferenceMap.put(peeredMode, peeredReference);
+ }
+
+ /**
+ * Receive an event for processing in Apex.
+ *
+ * @param event the event to receive
+ * @return the response from Apex
+ */
+ public Response receiveEvent(final String event) {
+ // Get an execution ID for the event
+ final long executionId = getNextExecutionID();
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(name + ": sending event " + name + '_' + executionId + " to Apex, event=" + event);
+ }
+
+ try {
+ // Send the event into Apex
+ eventReceiver.receiveEvent(executionId, event);
+ } catch (final Exception e) {
+ final String errorMessage = "error receiving events on event consumer " + name + ", " + e.getMessage();
+ LOGGER.warn(errorMessage);
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())
+ .entity("{'errorMessage', '" + errorMessage + "'}").build();
+ }
+
+ final SynchronousEventCache synchronousEventCache =
+ (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS);
+ // Wait until the event is in the cache of events sent to apex
+ do {
+ ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+ } while (!synchronousEventCache.existsEventToApex(executionId));
+
+ // Now wait for the reply or for the event to time put
+ do {
+ ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+
+ // Check if we have received an answer from Apex
+ if (synchronousEventCache.existsEventFromApex(executionId)) {
+ // We have received a response event, read and remove the response event and remove the sent event from
+ // the cache
+ final Object responseEvent = synchronousEventCache.removeCachedEventFromApexIfExists(executionId);
+ synchronousEventCache.removeCachedEventToApexIfExists(executionId);
+
+ // Return the event as a response to the call
+ return Response.status(Response.Status.OK.getStatusCode()).entity(responseEvent.toString()).build();
+ }
+ } while (synchronousEventCache.existsEventToApex(executionId));
+
+ // The event timed out
+ final String errorMessage = "processing of event on event consumer " + name + " timed out, event=" + event;
+ LOGGER.warn(errorMessage);
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())
+ .entity("{'errorMessage', '" + errorMessage + "'}").build();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run() {
+ // Keep the consumer thread alive until it is shut down. We do not currently do anything in the thread but may
+ // do supervision in the future
+ while (consumerThread.isAlive() && !stopOrderedFlag) {
+ ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+ }
+
+ if (server != null) {
+ server.shutdown();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.apps.uservice.consumer.ApexEventConsumer#stop()
+ */
+ @Override
+ public void stop() {
+ stopOrderedFlag = true;
+
+ while (consumerThread.isAlive()) {
+ ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+ }
+ }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerProducer.java
new file mode 100644
index 000000000..e51482ce4
--- /dev/null
+++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerProducer.java
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 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.policy.apex.plugins.event.carrier.restserver;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventProducer;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Concrete implementation of an Apex event producer that sends events using REST.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ *
+ */
+public class ApexRestServerProducer implements ApexEventProducer {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestServerProducer.class);
+
+ // The REST carrier properties
+ private RESTServerCarrierTechnologyParameters restProducerProperties;
+
+ // The name for this producer
+ private String name = null;
+
+ // The peer references for this event handler
+ private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#init(java.lang.String,
+ * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters)
+ */
+ @Override
+ public void init(final String producerName, final EventHandlerParameters producerParameters)
+ throws ApexEventException {
+ this.name = producerName;
+
+ // Check and get the REST Properties
+ if (!(producerParameters.getCarrierTechnologyParameters() instanceof RESTServerCarrierTechnologyParameters)) {
+ final String errorMessage =
+ "specified producer properties are not applicable to REST Server producer (" + this.name + ")";
+ LOGGER.warn(errorMessage);
+ throw new ApexEventException(errorMessage);
+ }
+ restProducerProperties =
+ (RESTServerCarrierTechnologyParameters) producerParameters.getCarrierTechnologyParameters();
+
+ // Check if host and port are defined
+ if (restProducerProperties.getHost() != null || restProducerProperties.getPort() != -1
+ || restProducerProperties.isStandalone()) {
+ final String errorMessage =
+ "the parameters \"host\", \"port\", and \"standalone\" are illegal on REST Server producer ("
+ + this.name + ")";
+ LOGGER.warn(errorMessage);
+ throw new ApexEventException(errorMessage);
+ }
+
+ // Check if we are in synchronous mode
+ if (!producerParameters.isPeeredMode(EventHandlerPeeredMode.SYNCHRONOUS)) {
+ final String errorMessage =
+ "REST Server producer (" + this.name + ") must run in synchronous mode with a REST Server consumer";
+ LOGGER.warn(errorMessage);
+ throw new ApexEventException(errorMessage);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName()
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap.policy.apex.service.
+ * parameters. eventhandler.EventHandlerPeeredMode)
+ */
+ @Override
+ public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+ return peerReferenceMap.get(peeredMode);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap.policy.apex.service.
+ * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+ */
+ @Override
+ public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+ peerReferenceMap.put(peeredMode, peeredReference);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#sendEvent(long, java.lang. String,
+ * java.lang.Object)
+ */
+ @Override
+ public void sendEvent(final long executionId, final String eventName, final Object event) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(name + ": event " + executionId + ':' + eventName + " recevied from Apex, event=" + event);
+ }
+
+ // If we are not synchronized, then exit
+ final SynchronousEventCache synchronousEventCache =
+ (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS);
+ if (synchronousEventCache == null) {
+ return;
+ }
+
+ // We see all events on the receiver, even those that are not replies to events sent by the synchronized
+ // consumer of this producer, ignore those
+ // events
+ if (!synchronousEventCache.existsEventToApex(executionId)) {
+ return;
+ }
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(name + ": event " + executionId + ':' + eventName + " is a reply to a REST server call from "
+ + name);
+ }
+
+ // Add the event to the received event cache
+ synchronousEventCache.cacheSynchronizedEventFromApex(executionId, event);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#stop()
+ */
+ @Override
+ public void stop() {}
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RESTServerCarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RESTServerCarrierTechnologyParameters.java
new file mode 100644
index 000000000..47e31fffa
--- /dev/null
+++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RESTServerCarrierTechnologyParameters.java
@@ -0,0 +1,136 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 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.policy.apex.plugins.event.carrier.restserver;
+
+import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters;
+
+/**
+ * Apex parameters for REST as an event carrier technology with Apex as a REST client.
+ *
+ * The parameters for this plugin are:
+ * <ol>
+ * <li>standalone: A flag indicating if APEX should start a standalone HTTP server to process REST requests (true) or
+ * whether it should use an underlying servlet infrastructure such as Apache Tomcat (False). This parameter is legal
+ * only on REST server event inputs.
+ * <li>host: The host name to use when setting up a standalone HTTP server. This parameter is legal only on REST server
+ * event inputs in standalone mode.
+ * <li>port: The port to use when setting up a standalone HTTP server. This parameter is legal only on REST server event
+ * inputs in standalone mode.
+ * </ol>
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class RESTServerCarrierTechnologyParameters extends CarrierTechnologyParameters {
+ // @formatter:off
+ private static final int MIN_USER_PORT = 1024;
+ private static final int MAX_USER_PORT = 65535;
+
+ /** The label of this carrier technology. */
+ public static final String RESTSERVER_CARRIER_TECHNOLOGY_LABEL = "RESTSERVER";
+
+ /** The producer plugin class for the REST carrier technology. */
+ public static final String RESTSERVER_EVENT_PRODUCER_PLUGIN_CLASS = ApexRestServerProducer.class.getCanonicalName();
+
+ /** The consumer plugin class for the REST carrier technology. */
+ public static final String RESTSERVER_EVENT_CONSUMER_PLUGIN_CLASS = ApexRestServerConsumer.class.getCanonicalName();
+
+ // REST server parameters
+ private boolean standalone = false;
+ private String host = null;
+ private int port = -1;
+ // @formatter:on
+
+ /**
+ * Constructor to create a REST carrier technology parameters instance and register the instance with the parameter
+ * service.
+ */
+ public RESTServerCarrierTechnologyParameters() {
+ super(RESTServerCarrierTechnologyParameters.class.getCanonicalName());
+
+ // Set the carrier technology properties for the web socket carrier technology
+ this.setLabel(RESTSERVER_CARRIER_TECHNOLOGY_LABEL);
+ this.setEventProducerPluginClass(RESTSERVER_EVENT_PRODUCER_PLUGIN_CLASS);
+ this.setEventConsumerPluginClass(RESTSERVER_EVENT_CONSUMER_PLUGIN_CLASS);
+ }
+
+ /**
+ * Check if the REST server is running in standalone mode or is using an underlying servlet infrastructure to manage
+ * requests.
+ *
+ * @return true if in standalone mode
+ */
+ public boolean isStandalone() {
+ return standalone;
+ }
+
+ /**
+ * Gets the host.
+ *
+ * @return the host
+ */
+ public String getHost() {
+ return host;
+ }
+
+ /**
+ * Gets the port.
+ *
+ * @return the port
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate()
+ */
+ @Override
+ public String validate() {
+ final StringBuilder errorMessageBuilder = new StringBuilder();
+
+ errorMessageBuilder.append(super.validate());
+
+ // Check if host is defined, it is only defined on REST server consumers
+ if (standalone) {
+ if (host != null) {
+ if (host.trim().length() == 0) {
+ errorMessageBuilder.append(" host not specified, must be host as a string\n");
+ }
+ }
+
+ // Check if port is defined, it is only defined on REST server consumers
+ if (port != -1) {
+ if (port < MIN_USER_PORT || port > MAX_USER_PORT) {
+ errorMessageBuilder
+ .append(" port [" + port + "] invalid, must be specified as 1024 <= port <= 6535\n");
+ }
+ }
+ } else {
+ if (host != null || port != -1) {
+ errorMessageBuilder.append(" host and port are specified only in standalone mode\n");
+ }
+ }
+
+ return errorMessageBuilder.toString();
+ }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RestServerEndpoint.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RestServerEndpoint.java
new file mode 100644
index 000000000..beee10fd0
--- /dev/null
+++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RestServerEndpoint.java
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 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.policy.apex.plugins.event.carrier.restserver;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Class RestServerEndpoint is the end point servlet class for handling REST requests and responses to and from
+ * Apex.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+@Path("/{eventInput}")
+@Produces({ MediaType.APPLICATION_JSON })
+@Consumes({ MediaType.APPLICATION_JSON })
+public class RestServerEndpoint {
+ // Get a reference to the logger
+ private static final Logger LOGGER = LoggerFactory.getLogger(RestServerEndpoint.class);
+
+ // Statistics on the amount of HTTP messages handled
+ private static int getMessagesReceived = 0;
+ private static int postEventMessagesReceived = 0;
+ private static int putEventMessagesReceived = 0;
+
+ // This map is used to hold all the REST server event inputs. This is used to determine which consumer to send input
+ // events to
+ private static Map<String, ApexRestServerConsumer> consumerMap =
+ new LinkedHashMap<String, ApexRestServerConsumer>();
+
+ // The ID of this event input. This gets injected from the URL.
+ @PathParam("eventInput")
+ private String eventInputID = null;
+
+ /**
+ * Register an Apex consumer with the REST server end point.
+ *
+ * @param consumerEventInputID The event input ID that indicates this consumer shoud be used
+ * @param consumer The consumer to register
+ */
+ public static void registerApexRestServerConsumer(final String consumerEventInputID,
+ final ApexRestServerConsumer consumer) {
+ consumerMap.put(consumerEventInputID, consumer);
+ }
+
+ /**
+ * Get statistics on apex REST event handling.
+ *
+ * @return the response
+ */
+ @Path("/Status")
+ @GET
+ public Response serviceGetStats() {
+ getMessagesReceived++;
+ return Response.status(Response.Status.OK.getStatusCode())
+ .entity("{\n" + "\"INPUTS\": \"" + consumerMap.keySet() + "\",\n" + "\"STAT\": " + getMessagesReceived
+ + ",\n" + "\"POST\": " + postEventMessagesReceived + ",\n" + "\"PUT\": "
+ + putEventMessagesReceived + "\n}")
+ .build();
+ }
+
+ /**
+ * Service post request, an incoming event over RETS to Apex.
+ *
+ * @param jsonString the JSON string containing the data coming in on the REST call
+ * @return the response event to the request
+ */
+ @Path("/EventIn")
+ @POST
+ public Response servicePostRequest(final String jsonString) {
+ postEventMessagesReceived++;
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("event input " + eventInputID + ", received POST of event \"" + jsonString + "\"");
+ }
+
+ // Common handler method for POST and PUT requests
+ return handleEvent(jsonString);
+ }
+
+ /**
+ * Service put request, an incoming event over RETS to Apex.
+ *
+ * @param jsonString the JSON string containing the data coming in on the REST call
+ * @return the response event to the request
+ */
+ @Path("/EventIn")
+ @PUT
+ public Response servicePutRequest(final String jsonString) {
+ putEventMessagesReceived++;
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("event input \"" + eventInputID + "\", received PUT of event \"" + jsonString + "\"");
+ }
+
+ // Common handler method for POST and PUT requests
+ return handleEvent(jsonString);
+ }
+
+ /**
+ * Common event handler for events received on POST and PUT messages.
+ *
+ * @param jsonString the JSON string containing the data coming in on the REST call
+ * @return the response event to the request
+ */
+ private Response handleEvent(final String jsonString) {
+ // Find the correct consumer for this REST message
+ final ApexRestServerConsumer eventConsumer = consumerMap.get(eventInputID);
+ if (eventConsumer == null) {
+ final String errorMessage =
+ "event input " + eventInputID + " is not defined in the Apex configuration file";
+ LOGGER.warn(errorMessage);
+ return Response.status(Response.Status.BAD_REQUEST.getStatusCode())
+ .entity("{'errorMessage', '" + errorMessage + "'}").build();
+ }
+
+ return eventConsumer.receiveEvent(jsonString);
+ }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/package-info.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/package-info.java
new file mode 100644
index 000000000..98a1c4bd6
--- /dev/null
+++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 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=========================================================
+ */
+
+/**
+ * APEX REST consumer and producer plugins when APEX is acting as a REST client.
+ *
+ * @author Joss Armstrong (joss.armstrong@ericsson.com)
+ *
+ */
+
+package org.onap.policy.apex.plugins.event.carrier.restserver;
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/test/resources/logback-test.xml b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/test/resources/logback-test.xml
new file mode 100644
index 000000000..dc591b1f1
--- /dev/null
+++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/test/resources/logback-test.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 2016-2018 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=========================================================
+-->
+
+<configuration>
+
+ <contextName>Apex</contextName>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+ <property name="LOG_DIR" value="${java.io.tmpdir}/apex_logging/" />
+
+ <!-- USE FOR STD OUT ONLY -->
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <root level="info">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${LOG_DIR}/apex.log</file>
+ <encoder>
+ <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+ %logger{26} - %msg %n %ex{full}</pattern>
+ </encoder>
+ </appender>
+
+ <logger name="org.onap.policy.apex.plugins.event.carrier.restserver" level="trace" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+</configuration>