diff options
Diffstat (limited to 'plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src')
4 files changed, 586 insertions, 0 deletions
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientConsumer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientConsumer.java new file mode 100644 index 000000000..b9348d494 --- /dev/null +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientConsumer.java @@ -0,0 +1,233 @@ +/*- + * ============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.restclient; + +import java.util.EnumMap; +import java.util.Map; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.core.Response; + +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.ApexEventRuntimeException; +import org.onap.policy.apex.service.engine.event.PeeredReference; +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 ApexRestClientConsumer implements ApexEventConsumer, Runnable { + // Get a reference to the logger + private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestClientConsumer.class); + + // The amount of time to wait in milliseconds between checks that the consumer thread has stopped + private static final long REST_CLIENT_WAIT_SLEEP_TIME = 50; + + // The REST parameters read from the parameter service + private RESTClientCarrierTechnologyParameters restConsumerProperties; + + // The event receiver that will receive events from this consumer + private ApexEventReceiver eventReceiver; + + // The HTTP client that makes a REST call to get an input event for Apex + private Client client; + + // 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; + + @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 RESTClientCarrierTechnologyParameters)) { + final String errorMessage = + "specified consumer properties are not applicable to REST client consumer (" + this.name + ")"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + restConsumerProperties = + (RESTClientCarrierTechnologyParameters) consumerParameters.getCarrierTechnologyParameters(); + + // Check if the HTTP method has been set + if (restConsumerProperties.getHttpMethod() == null) { + restConsumerProperties.setHttpMethod(RESTClientCarrierTechnologyParameters.CONSUMER_HTTP_METHOD); + } + + if (!restConsumerProperties.getHttpMethod() + .equalsIgnoreCase(RESTClientCarrierTechnologyParameters.CONSUMER_HTTP_METHOD)) { + final String errorMessage = "specified HTTP method of \"" + restConsumerProperties.getHttpMethod() + + "\" is invalid, only HTTP method \"GET\" is supported for event reception on REST client consumer (" + + this.name + ")"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + + // Initialize the HTTP client + client = ClientBuilder.newClient(); + } + + /* + * (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); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + // The RequestRunner thread runs the get request for the event + Thread requestRunnerThread = null; + + // The endless loop that receives events using REST calls + while (consumerThread.isAlive() && !stopOrderedFlag) { + // Create a new request if one is not in progress + if (requestRunnerThread == null || !requestRunnerThread.isAlive()) { + requestRunnerThread = new Thread(new RequestRunner()); + requestRunnerThread.start(); + } + + ThreadUtilities.sleep(REST_CLIENT_WAIT_SLEEP_TIME); + } + + client.close(); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.producer.ApexEventConsumer#stop() + */ + @Override + public void stop() { + stopOrderedFlag = true; + + while (consumerThread.isAlive()) { + ThreadUtilities.sleep(REST_CLIENT_WAIT_SLEEP_TIME); + } + } + + /** + * This class is used to start a thread for each request issued. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ + private class RequestRunner implements Runnable { + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + final Response response = + client.target(restConsumerProperties.getURL()).request("application/json").get(); + + // Check that the event request worked + if (response.getStatus() != Response.Status.OK.getStatusCode()) { + final String errorMessage = "reception of event from URL \"" + restConsumerProperties.getURL() + + "\" failed with status code " + response.getStatus() + " and message \"" + + response.readEntity(String.class) + "\""; + throw new ApexEventRuntimeException(errorMessage); + } + + // Get the event we received + final String eventJSONString = response.readEntity(String.class); + + // Check there is content + if (eventJSONString == null || eventJSONString.trim().length() == 0) { + final String errorMessage = + "received an empty event from URL \"" + restConsumerProperties.getURL() + "\""; + throw new ApexEventRuntimeException(errorMessage); + } + + // Send the event into Apex + eventReceiver.receiveEvent(eventJSONString); + } catch (final Exception e) { + LOGGER.warn("error receiving events on thread {}", consumerThread.getName(), e); + } + } + } +} diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java new file mode 100644 index 000000000..9d838f55e --- /dev/null +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java @@ -0,0 +1,191 @@ +/*- + * ============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.restclient; + +import java.util.EnumMap; +import java.util.Map; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Response; + +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.ApexEventRuntimeException; +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 Joss Armstrong (joss.armstrong@ericsson.com) + * + */ +public class ApexRestClientProducer implements ApexEventProducer { + private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestClientProducer.class); + + // The HTTP client that makes a REST call with an event from Apex + private Client client; + + // The REST carrier properties + private RESTClientCarrierTechnologyParameters 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 RESTClientCarrierTechnologyParameters)) { + final String errorMessage = + "specified consumer properties are not applicable to REST client producer (" + this.name + ")"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + restProducerProperties = + (RESTClientCarrierTechnologyParameters) producerParameters.getCarrierTechnologyParameters(); + + // Check if the HTTP method has been set + if (restProducerProperties.getHttpMethod() == null) { + restProducerProperties.setHttpMethod(RESTClientCarrierTechnologyParameters.DEFAULT_PRODUCER_HTTP_METHOD); + } + + if (!restProducerProperties.getHttpMethod().equalsIgnoreCase("POST") + && !restProducerProperties.getHttpMethod().equalsIgnoreCase("PUT")) { + final String errorMessage = "specified HTTP method of \"" + restProducerProperties.getHttpMethod() + + "\" is invalid, only HTTP methods \"POST\" and \"PUT\" are supproted for event sending on REST client producer (" + + this.name + ")"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + + // Initialize the HTTP client + client = ClientBuilder.newClient(); + } + + /* + * (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) { + // Check if this is a synchronized event, if so we have received a reply + final SynchronousEventCache synchronousEventCache = + (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS); + if (synchronousEventCache != null) { + synchronousEventCache.removeCachedEventToApexIfExists(executionId); + } + + // Send the event as a REST request + final Response response = sendEventAsRESTRequest((String) event); + + // Check that the request worked + if (response.getStatus() != Response.Status.OK.getStatusCode()) { + final String errorMessage = "send of event to URL \"" + restProducerProperties.getURL() + "\" using HTTP \"" + + restProducerProperties.getHttpMethod() + "\" failed with status code " + response.getStatus() + + " and message \"" + response.readEntity(String.class) + "\", event:\n" + event; + LOGGER.warn(errorMessage); + throw new ApexEventRuntimeException(errorMessage); + } + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("event sent from engine using {} to URL {} with HTTP {} : {} and response {} ", this.name, + restProducerProperties.getURL(), restProducerProperties.getHttpMethod(), event, response); + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#stop() + */ + @Override + public void stop() { + // Close the HTTP session + client.close(); + } + + /** + * Send the event as a JSON string as a REST request. + * + * @param event the event to send + * @return the response tot he JSON request + */ + public Response sendEventAsRESTRequest(final String event) { + // We have already checked that it is a PUT or POST request + if (restProducerProperties.getHttpMethod().equalsIgnoreCase("POST")) { + return client.target(restProducerProperties.getURL()).request("application/json").post(Entity.json(event)); + } else { + return client.target(restProducerProperties.getURL()).request("application/json").put(Entity.json(event)); + } + } +} diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RESTClientCarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RESTClientCarrierTechnologyParameters.java new file mode 100644 index 000000000..e07593c55 --- /dev/null +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RESTClientCarrierTechnologyParameters.java @@ -0,0 +1,134 @@ +/*- + * ============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.restclient; + +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>url: The URL that the Apex Rest client will connect to over REST for event reception or event sending. This + * parameter is mandatory. + * <li>httpMethod: The HTTP method to use when sending events over REST, legal values are POST (default) and PUT. When + * receiving events, the REST client plugin always uses the HTTP GET method. + * </ol> + * + * @author Joss Armstrong (joss.armstrong@ericsson.com) + */ +public class RESTClientCarrierTechnologyParameters extends CarrierTechnologyParameters { + + /** The label of this carrier technology. */ + public static final String RESTCLIENT_CARRIER_TECHNOLOGY_LABEL = "RESTCLIENT"; + + /** The producer plugin class for the REST carrier technology. */ + public static final String RESTCLIENT_EVENT_PRODUCER_PLUGIN_CLASS = ApexRestClientProducer.class.getCanonicalName(); + + /** The consumer plugin class for the REST carrier technology. */ + public static final String RESTCLIENT_EVENT_CONSUMER_PLUGIN_CLASS = ApexRestClientConsumer.class.getCanonicalName(); + + /** The default HTTP method for output of events. */ + public static final String DEFAULT_PRODUCER_HTTP_METHOD = "POST"; + + /** The HTTP method for input of events. */ + public static final String CONSUMER_HTTP_METHOD = "GET"; + + private String url = null; + private String httpMethod = null; + + /** + * Constructor to create a REST carrier technology parameters instance and register the instance with the parameter + * service. + */ + public RESTClientCarrierTechnologyParameters() { + super(RESTClientCarrierTechnologyParameters.class.getCanonicalName()); + + // Set the carrier technology properties for the web socket carrier technology + this.setLabel(RESTCLIENT_CARRIER_TECHNOLOGY_LABEL); + this.setEventProducerPluginClass(RESTCLIENT_EVENT_PRODUCER_PLUGIN_CLASS); + this.setEventConsumerPluginClass(RESTCLIENT_EVENT_CONSUMER_PLUGIN_CLASS); + + } + + /** + * Gets the URL for the REST request. + * + * @return the URL + */ + public String getURL() { + return url; + } + + /** + * Sets the URL for the REST request. + * + * @param incomingURL the URL + */ + public void setURL(final String incomingURL) { + this.url = incomingURL; + } + + /** + * Gets the HTTP method to use for the REST request. + * + * @return the HTTP method + */ + public String getHttpMethod() { + return httpMethod; + } + + /** + * Sets the HTTP method to use for the REST request. + * + * @param httpMethod the HTTP method + */ + public void setHttpMethod(final String httpMethod) { + this.httpMethod = httpMethod; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "RESTClientCarrierTechnologyParameters [url=" + url + ", httpMethod=" + httpMethod + "]"; + } + + + /* + * + * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + // Check if the URL has been set for event output + if (getURL() == null) { + errorMessageBuilder.append(" no URL has been set for event sending on REST client"); + } + + return errorMessageBuilder.toString(); + } +} diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/package-info.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/package-info.java new file mode 100644 index 000000000..e674beef6 --- /dev/null +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/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.restclient; |