c4354918fac2b3949e5dedb1b6ef5709cadecace
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.plugins.event.carrier.restserver;
23
24 import io.swagger.annotations.Api;
25 import io.swagger.annotations.ApiOperation;
26 import io.swagger.annotations.ApiResponse;
27 import io.swagger.annotations.ApiResponses;
28 import io.swagger.annotations.Authorization;
29 import io.swagger.annotations.BasicAuthDefinition;
30 import io.swagger.annotations.Info;
31 import io.swagger.annotations.SecurityDefinition;
32 import io.swagger.annotations.SwaggerDefinition;
33 import io.swagger.annotations.Tag;
34 import java.net.HttpURLConnection;
35 import java.util.LinkedHashMap;
36 import java.util.Map;
37 import javax.ws.rs.Consumes;
38 import javax.ws.rs.GET;
39 import javax.ws.rs.POST;
40 import javax.ws.rs.PUT;
41 import javax.ws.rs.Path;
42 import javax.ws.rs.PathParam;
43 import javax.ws.rs.Produces;
44 import javax.ws.rs.core.MediaType;
45 import javax.ws.rs.core.Response;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 /**
50  * The Class RestServerEndpoint is the end point servlet class for handling REST requests and responses to and from
51  * Apex.
52  *
53  * @author Liam Fallon (liam.fallon@ericsson.com)
54  */
55 @Path("/apex/{eventInput}")
56 @Api(value = "APEX REST SERVER API")
57 @Produces(
58     { MediaType.APPLICATION_JSON })
59 @Consumes(
60     { MediaType.APPLICATION_JSON })
61 @SwaggerDefinition(
62         info = @Info(description =
63                  "APEX RestServer that handles  REST requests and responses to and from Apex.", version = "v1.0",
64                      title = "APEX RESTSERVER"),
65         consumes = {MediaType.APPLICATION_JSON},
66         produces = {MediaType.APPLICATION_JSON},
67         schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS},
68         tags = {@Tag(name = "APEX RESTSERVER", description = "APEX RESTSERVER")},
69         securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")}))
70 public class RestServerEndpoint {
71     // Get a reference to the logger
72     private static final Logger LOGGER = LoggerFactory.getLogger(RestServerEndpoint.class);
73
74     public static final String AUTHORIZATION_TYPE = "basicAuth";
75
76     public static final int AUTHENTICATION_ERROR_CODE = HttpURLConnection.HTTP_UNAUTHORIZED;
77     public static final int AUTHORIZATION_ERROR_CODE = HttpURLConnection.HTTP_FORBIDDEN;
78     public static final int SERVER_ERROR_CODE = HttpURLConnection.HTTP_INTERNAL_ERROR;
79
80     public static final String AUTHENTICATION_ERROR_MESSAGE = "Authentication Error";
81     public static final String AUTHORIZATION_ERROR_MESSAGE = "Authorization Error";
82     public static final String SERVER_ERROR_MESSAGE = "Internal Server Error";
83
84     // Statistics on the amount of HTTP messages handled
85     private static int getMessagesReceived = 0;
86     private static int postEventMessagesReceived = 0;
87     private static int putEventMessagesReceived = 0;
88
89     // This map is used to hold all the REST server event inputs. This is used to determine which consumer to send input
90     // events to
91     private static Map<String, ApexRestServerConsumer> consumerMap = new LinkedHashMap<>();
92
93     // The ID of this event input. This gets injected from the URL.
94     @PathParam("eventInput")
95     private String eventInputId = null;
96
97     /**
98      * Register an Apex consumer with the REST server end point.
99      *
100      * @param consumerEventInputId The event input ID that indicates this consumer shoud be used
101      * @param consumer The consumer to register
102      */
103     public static void registerApexRestServerConsumer(final String consumerEventInputId,
104                     final ApexRestServerConsumer consumer) {
105         consumerMap.put(consumerEventInputId, consumer);
106     }
107
108     /**
109      * Get statistics on apex REST event handling.
110      *
111      * @return the response
112      */
113     @Path("/Status")
114     @GET
115     @ApiOperation(
116         value = "Get Statistics",
117         notes = "Get statistics on apex REST event handlin",
118         authorizations = @Authorization(value = AUTHORIZATION_TYPE))
119     @ApiResponses(
120         value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
121             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
122             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
123     public Response serviceGetStats() {
124         incrementGetMessages();
125         return Response.status(Response.Status.OK.getStatusCode())
126                         .entity("{\n" + "\"INPUTS\": \"" + consumerMap.keySet() + "\",\n" + "\"STAT\": "
127                                         + getMessagesReceived + ",\n" + "\"POST\": " + postEventMessagesReceived + ",\n"
128                                         + "\"PUT\":  " + putEventMessagesReceived + "\n}")
129                         .build();
130     }
131
132     /**
133      * Service post request, an incoming event over REST to Apex.
134      *
135      * @param jsonString the JSON string containing the data coming in on the REST call
136      * @return the response event to the request
137      */
138     @Path("/EventIn")
139     @POST
140     @ApiOperation(
141         value = "Post Event",
142         notes = "Service post request, an incoming event over REST to Apex",
143         authorizations = @Authorization(value = AUTHORIZATION_TYPE))
144     @ApiResponses(
145         value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
146             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
147             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
148     public Response servicePostRequest(final String jsonString) {
149         incrementPostEventMessages();
150
151         if (LOGGER.isDebugEnabled()) {
152             String message = "event input " + eventInputId + ", received POST of event \"" + jsonString + "\"";
153             LOGGER.debug(message);
154         }
155
156         // Common handler method for POST and PUT requests
157         return handleEvent(jsonString);
158     }
159
160     /**
161      * Service put request, an incoming event over REST to Apex.
162      *
163      * @param jsonString the JSON string containing the data coming in on the REST call
164      * @return the response event to the request
165      */
166     @Path("/EventIn")
167     @PUT
168     @ApiOperation(
169         value = "Put Event",
170         notes = "Service put request, an incoming event over REST to Apex",
171         authorizations = @Authorization(value = AUTHORIZATION_TYPE))
172     @ApiResponses(
173         value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE),
174             @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE),
175             @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)})
176     public Response servicePutRequest(final String jsonString) {
177         incrementPutEventMessages();
178
179         if (LOGGER.isDebugEnabled()) {
180             String message = "event input \"" + eventInputId + "\", received PUT of event \"" + jsonString + "\"";
181             LOGGER.debug(message);
182         }
183
184         // Common handler method for POST and PUT requests
185         return handleEvent(jsonString);
186     }
187
188     /**
189      * Common event handler for events received on POST and PUT messages.
190      *
191      * @param jsonString the JSON string containing the data coming in on the REST call
192      * @return the response event to the request
193      */
194     private Response handleEvent(final String jsonString) {
195         // Find the correct consumer for this REST message
196         final ApexRestServerConsumer eventConsumer = consumerMap.get(eventInputId);
197         if (eventConsumer == null) {
198             final String errorMessage = "event input " + eventInputId
199                             + " is not defined in the Apex configuration file";
200             LOGGER.warn(errorMessage);
201             return Response.status(Response.Status.BAD_REQUEST.getStatusCode())
202                             .entity("{'errorMessage', '" + errorMessage + "'}").build();
203         }
204
205         return eventConsumer.receiveEvent(jsonString);
206     }
207
208     /**
209      * Increment number of get messages received.
210      */
211     private static void incrementGetMessages() {
212         getMessagesReceived++;
213     }
214
215     /**
216      * Increment number of get messages received.
217      */
218     private static void incrementPutEventMessages() {
219         putEventMessagesReceived++;
220     }
221
222     /**
223      * Increment number of get messages received.
224      */
225     private static void incrementPostEventMessages() {
226         postEventMessagesReceived++;
227     }
228 }