a7e0ddd52fb06be807cb14d7b8e379293b34159c
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.plugins.event.carrier.restclient;
22
23 import java.util.EnumMap;
24 import java.util.Map;
25
26 import javax.ws.rs.client.Client;
27 import javax.ws.rs.client.ClientBuilder;
28 import javax.ws.rs.client.Entity;
29 import javax.ws.rs.core.Response;
30
31 import org.onap.policy.apex.service.engine.event.ApexEventException;
32 import org.onap.policy.apex.service.engine.event.ApexEventProducer;
33 import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
34 import org.onap.policy.apex.service.engine.event.PeeredReference;
35 import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
36 import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
37 import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 /**
42  * Concrete implementation of an Apex event producer that sends events using REST.
43  *
44  * @author Joss Armstrong (joss.armstrong@ericsson.com)
45  *
46  */
47 public class ApexRestClientProducer implements ApexEventProducer {
48     private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestClientProducer.class);
49
50     // The HTTP client that makes a REST call with an event from Apex
51     private Client client;
52
53     // The REST carrier properties
54     private RestClientCarrierTechnologyParameters restProducerProperties;
55
56     // The name for this producer
57     private String name = null;
58
59     // The peer references for this event handler
60     private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
61
62     /*
63      * (non-Javadoc)
64      *
65      * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#init(java.lang.String,
66      * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters)
67      */
68     @Override
69     public void init(final String producerName, final EventHandlerParameters producerParameters)
70         throws ApexEventException {
71         this.name = producerName;
72
73         // Check and get the REST Properties
74         if (!(producerParameters.getCarrierTechnologyParameters() instanceof RestClientCarrierTechnologyParameters)) {
75             final String errorMessage = "specified producer properties are not applicable to REST client producer ("
76                 + this.name + ")";
77             LOGGER.warn(errorMessage);
78             throw new ApexEventException(errorMessage);
79         }
80         restProducerProperties = (RestClientCarrierTechnologyParameters) producerParameters
81             .getCarrierTechnologyParameters();
82
83         // Check if the HTTP method has been set
84         if (restProducerProperties.getHttpMethod() == null) {
85             restProducerProperties.setHttpMethod(RestClientCarrierTechnologyParameters.HttpMethod.POST);
86         }
87
88         if (!RestClientCarrierTechnologyParameters.HttpMethod.POST.equals(restProducerProperties.getHttpMethod())
89             && !RestClientCarrierTechnologyParameters.HttpMethod.PUT.equals(restProducerProperties.getHttpMethod())) {
90             final String errorMessage = "specified HTTP method of \"" + restProducerProperties.getHttpMethod()
91                 + "\" is invalid, only HTTP methods \"POST\" and \"PUT\" are supproted "
92                 + "for event sending on REST client producer (" + this.name + ")";
93             LOGGER.warn(errorMessage);
94             throw new ApexEventException(errorMessage);
95         }
96
97         // Initialize the HTTP client
98         client = ClientBuilder.newClient();
99     }
100
101     /*
102      * (non-Javadoc)
103      *
104      * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName()
105      */
106     @Override
107     public String getName() {
108         return name;
109     }
110
111     /*
112      * (non-Javadoc)
113      *
114      * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap.policy.apex.service.
115      * parameters. eventhandler.EventHandlerPeeredMode)
116      */
117     @Override
118     public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
119         return peerReferenceMap.get(peeredMode);
120     }
121
122     /*
123      * (non-Javadoc)
124      *
125      * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap.policy.apex.service.
126      * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
127      */
128     @Override
129     public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
130         peerReferenceMap.put(peeredMode, peeredReference);
131     }
132
133     /*
134      * (non-Javadoc)
135      *
136      * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#sendEvent(long, java.lang. String,
137      * java.lang.Object)
138      */
139     @Override
140     public void sendEvent(final long executionId, final String eventName, final Object event) {
141         // Check if this is a synchronized event, if so we have received a reply
142         final SynchronousEventCache synchronousEventCache = (SynchronousEventCache) peerReferenceMap
143             .get(EventHandlerPeeredMode.SYNCHRONOUS);
144         if (synchronousEventCache != null) {
145             synchronousEventCache.removeCachedEventToApexIfExists(executionId);
146         }
147
148         // Send the event as a REST request
149         final Response response = sendEventAsRestRequest((String) event);
150
151         // Check that the request worked
152         if (response.getStatus() != Response.Status.OK.getStatusCode()) {
153             final String errorMessage = "send of event to URL \"" + restProducerProperties.getUrl() + "\" using HTTP \""
154                 + restProducerProperties.getHttpMethod() + "\" failed with status code " + response.getStatus()
155                 + " and message \"" + response.readEntity(String.class) + "\", event:\n" + event;
156             LOGGER.warn(errorMessage);
157             throw new ApexEventRuntimeException(errorMessage);
158         }
159
160         if (LOGGER.isTraceEnabled()) {
161             LOGGER.trace("event sent from engine using {} to URL {} with HTTP {} : {} and response {} ", this.name,
162                 restProducerProperties.getUrl(), restProducerProperties.getHttpMethod(), event, response);
163         }
164     }
165
166     /*
167      * (non-Javadoc)
168      *
169      * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#stop()
170      */
171     @Override
172     public void stop() {
173         // Close the HTTP session
174         client.close();
175     }
176
177     /**
178      * Send the event as a JSON string as a REST request.
179      *
180      * @param event the event to send
181      * @return the response to the JSON request
182      */
183     private Response sendEventAsRestRequest(final String event) {
184         // We have already checked that it is a PUT or POST request
185         if (RestClientCarrierTechnologyParameters.HttpMethod.POST.equals(restProducerProperties.getHttpMethod())) {
186             return client.target(restProducerProperties.getUrl()).request("application/json").post(Entity.json(event));
187         } else {
188             return client.target(restProducerProperties.getUrl()).request("application/json").put(Entity.json(event));
189         }
190     }
191
192     /**
193      * Hook for unit test mocking of HTTP client.
194      * 
195      * @param client the mocked client
196      */
197     protected void setClient(final Client client) {
198         this.client = client;
199     }
200 }