7bb646c30f079e329a6ff2f1850e3d484207d5b7
[integration.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * PNF-REGISTRATION-HANDLER
4  * ================================================================================ Copyright (C)
5  * 2018 NOKIA Intellectual Property. All rights reserved.
6  * ================================================================================ Licensed under
7  * the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
8  * with the License. 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 distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License. ============LICENSE_END=========================================================
16  */
17
18 package org.onap.pnfsimulator.rest;
19
20 import static org.onap.pnfsimulator.logging.MDCVariables.INSTANCE_UUID;
21 import static org.onap.pnfsimulator.logging.MDCVariables.INVOCATION_ID;
22 import static org.onap.pnfsimulator.logging.MDCVariables.REQUEST_ID;
23 import static org.onap.pnfsimulator.logging.MDCVariables.RESPONSE_CODE;
24 import static org.onap.pnfsimulator.logging.MDCVariables.SERVICE_NAME;
25 import static org.onap.pnfsimulator.logging.MDCVariables.X_INVOCATION_ID;
26 import static org.onap.pnfsimulator.logging.MDCVariables.AUTHORIZATION;
27 import static org.onap.pnfsimulator.logging.MDCVariables.X_ONAP_REQUEST_ID;
28 import static org.onap.pnfsimulator.message.MessageConstants.COMMON_EVENT_HEADER_PARAMS;
29 import static org.onap.pnfsimulator.message.MessageConstants.SIMULATOR_PARAMS;
30 import static org.onap.pnfsimulator.rest.util.ResponseBuilder.MESSAGE;
31 import static org.onap.pnfsimulator.rest.util.ResponseBuilder.REMAINING_TIME;
32 import static org.onap.pnfsimulator.rest.util.ResponseBuilder.SIMULATOR_STATUS;
33 import static org.onap.pnfsimulator.rest.util.ResponseBuilder.TIMESTAMP;
34 import static org.springframework.http.HttpStatus.BAD_REQUEST;
35 import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
36 import static org.springframework.http.HttpStatus.OK;
37 import com.github.fge.jsonschema.core.exceptions.ProcessingException;
38 import java.io.IOException;
39 import java.text.DateFormat;
40 import java.text.SimpleDateFormat;
41 import java.util.Optional;
42 import java.util.UUID;
43 import org.json.JSONException;
44 import org.json.JSONObject;
45 import org.onap.pnfsimulator.message.MessageConstants;
46 import org.onap.pnfsimulator.rest.util.DateUtil;
47 import org.onap.pnfsimulator.rest.util.ResponseBuilder;
48 import org.onap.pnfsimulator.simulator.Simulator;
49 import org.onap.pnfsimulator.simulator.SimulatorFactory;
50 import org.onap.pnfsimulator.simulator.validation.JSONValidator;
51 import org.onap.pnfsimulator.simulator.validation.ValidationException;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.slf4j.MDC;
55 import org.slf4j.Marker;
56 import org.slf4j.MarkerFactory;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.http.HttpHeaders;
59 import org.springframework.http.ResponseEntity;
60 import org.springframework.web.bind.annotation.GetMapping;
61 import org.springframework.web.bind.annotation.PostMapping;
62 import org.springframework.web.bind.annotation.RequestBody;
63 import org.springframework.web.bind.annotation.RequestHeader;
64 import org.springframework.web.bind.annotation.RequestMapping;
65 import org.springframework.web.bind.annotation.RestController;
66
67 @RestController
68 @RequestMapping("/simulator")
69 public class SimulatorController {
70
71     private static final Logger LOGGER = LoggerFactory.getLogger(Simulator.class);
72     private static final DateFormat RESPONSE_DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss,SSS");
73     private final Marker ENTRY = MarkerFactory.getMarker("ENTRY");
74     private Simulator simulator;
75     private JSONValidator validator;
76     private SimulatorFactory factory;
77
78     @Autowired
79     public SimulatorController(JSONValidator validator, SimulatorFactory factory) {
80         this.validator = validator;
81         this.factory = factory;
82     }
83
84     @PostMapping("start")
85     public ResponseEntity start(@RequestHeader HttpHeaders headers, @RequestBody String message) {
86         MDC.put(REQUEST_ID, headers.getFirst(X_ONAP_REQUEST_ID));
87         MDC.put(INVOCATION_ID, headers.getFirst(X_INVOCATION_ID));
88         MDC.put(AUTHORIZATION, headers.getFirst(AUTHORIZATION));
89         MDC.put(INSTANCE_UUID, UUID.randomUUID().toString());
90         MDC.put(SERVICE_NAME, "/simulator/start");
91         LOGGER.info(ENTRY, "Simulator starting");
92
93         if (isSimulatorRunning()) {
94             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
95             return ResponseBuilder.status(BAD_REQUEST).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
96                     .put(MESSAGE, "Cannot start simulator since it's already running").build();
97         }
98
99         try {
100             validator.validate(message, "json_schema/input_validator.json");
101             JSONObject root = new JSONObject(message);
102             JSONObject simulatorParams = root.getJSONObject(SIMULATOR_PARAMS);
103             JSONObject commonEventHeaderParams = root.getJSONObject(COMMON_EVENT_HEADER_PARAMS);
104             Optional<JSONObject> pnfRegistrationFields = root.has(MessageConstants.PNF_REGISTRATION_PARAMS)
105                     ? Optional.of(root.getJSONObject(MessageConstants.PNF_REGISTRATION_PARAMS))
106                     : Optional.empty();
107             Optional<JSONObject> notificationFields = root.has(MessageConstants.NOTIFICATION_PARAMS)
108                     ? Optional.of(root.getJSONObject(MessageConstants.NOTIFICATION_PARAMS))
109                     : Optional.empty();
110             simulator =
111                     factory.create(simulatorParams, commonEventHeaderParams, pnfRegistrationFields, notificationFields);
112             simulator.start();
113
114             MDC.put(RESPONSE_CODE, OK.toString());
115             return ResponseBuilder.status(OK).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
116                     .put(MESSAGE, "Simulator started").build();
117
118         } catch (JSONException e) {
119             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
120             LOGGER.warn("Cannot start simulator, invalid json format: {}", e.getMessage());
121             LOGGER.debug("Received json has invalid format", e);
122             return ResponseBuilder.status(BAD_REQUEST).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
123                     .put(MESSAGE, "Cannot start simulator, invalid json format").build();
124
125         } catch (ProcessingException | ValidationException | IOException e) {
126             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
127             LOGGER.warn("Json validation failed: {}", e.getMessage());
128             return ResponseBuilder.status(BAD_REQUEST).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
129                     .put(MESSAGE, "Cannot start simulator - Json format is not compatible with schema definitions")
130                     .build();
131
132         } catch (Exception e) {
133             MDC.put(RESPONSE_CODE, INTERNAL_SERVER_ERROR.toString());
134             LOGGER.error("Cannot start simulator - unexpected exception", e);
135             return ResponseBuilder.status(INTERNAL_SERVER_ERROR)
136                     .put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
137                     .put(MESSAGE, "Unexpected exception: " + e.getMessage()).build();
138         } finally {
139             MDC.clear();
140         }
141     }
142
143     @PostMapping("startmassmode")
144     public ResponseEntity startmassmode(@RequestHeader HttpHeaders headers, @RequestBody String message) {
145         MDC.put(REQUEST_ID, headers.getFirst(X_ONAP_REQUEST_ID));
146         MDC.put(INVOCATION_ID, headers.getFirst(X_INVOCATION_ID));
147         MDC.put(AUTHORIZATION, headers.getFirst(AUTHORIZATION));
148         MDC.put(INSTANCE_UUID, UUID.randomUUID().toString());
149         MDC.put(SERVICE_NAME, "/simulator/start");
150         LOGGER.info(ENTRY, "Simulator starting");
151
152         if (isSimulatorRunning()) {
153             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
154             return ResponseBuilder.status(BAD_REQUEST).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
155                     .put(MESSAGE, "Cannot start simulator since it's already running").build();
156         }
157
158         try {
159             validator.validate(message, "json_schema/input_validator.json");
160             JSONObject root = new JSONObject(message);
161             JSONObject simulatorParams = root.getJSONObject(SIMULATOR_PARAMS);
162             JSONObject commonEventHeaderParams = root.getJSONObject(COMMON_EVENT_HEADER_PARAMS);
163             Optional<JSONObject> pnfRegistrationFields = root.has(MessageConstants.PNF_REGISTRATION_PARAMS)
164                     ? Optional.of(root.getJSONObject(MessageConstants.PNF_REGISTRATION_PARAMS))
165                     : Optional.empty();
166             Optional<JSONObject> notificationFields = root.has(MessageConstants.NOTIFICATION_PARAMS)
167                     ? Optional.of(root.getJSONObject(MessageConstants.NOTIFICATION_PARAMS))
168                     : Optional.empty();
169             simulator =
170                     factory.create(simulatorParams, commonEventHeaderParams, pnfRegistrationFields, notificationFields);
171             simulator.start();
172
173             MDC.put(RESPONSE_CODE, OK.toString());
174             return ResponseBuilder.status(OK).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
175                     .put(MESSAGE, "Simulator started").build();
176
177         } catch (JSONException e) {
178             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
179             LOGGER.warn("Cannot start simulator, invalid json format: {}", e.getMessage());
180             LOGGER.debug("Received json has invalid format", e);
181             return ResponseBuilder.status(BAD_REQUEST).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
182                     .put(MESSAGE, "Cannot start simulator, invalid json format").build();
183
184         } catch (ProcessingException | ValidationException | IOException e) {
185             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
186             LOGGER.warn("Json validation failed: {}", e.getMessage());
187             return ResponseBuilder.status(BAD_REQUEST).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
188                     .put(MESSAGE, "Cannot start simulator - Json format is not compatible with schema definitions")
189                     .build();
190
191         } catch (Exception e) {
192             MDC.put(RESPONSE_CODE, INTERNAL_SERVER_ERROR.toString());
193             LOGGER.error("Cannot start simulator - unexpected exception", e);
194             return ResponseBuilder.status(INTERNAL_SERVER_ERROR)
195                     .put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
196                     .put(MESSAGE, "Unexpected exception: " + e.getMessage()).build();
197         } finally {
198             MDC.clear();
199         }
200     }
201
202
203
204     @GetMapping("status")
205     public ResponseEntity status() {
206         if (isSimulatorRunning()) {
207             ResponseBuilder responseBuilder = ResponseBuilder.status(OK)
208                     .put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT)).put(SIMULATOR_STATUS, "RUNNING");
209
210             return !simulator.isEndless() ? responseBuilder.put(REMAINING_TIME, simulator.getRemainingTime()).build()
211                     : responseBuilder.build();
212         } else {
213             return ResponseBuilder.status(OK).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
214                     .put(SIMULATOR_STATUS, "NOT RUNNING").build();
215         }
216     }
217
218     @PostMapping("stop")
219     public ResponseEntity stop() {
220         if (isSimulatorRunning()) {
221             simulator.interrupt();
222
223             return ResponseBuilder.status(OK).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
224                     .put(MESSAGE, "Simulator successfully stopped").build();
225         } else {
226             return ResponseBuilder.status(BAD_REQUEST).put(TIMESTAMP, DateUtil.getTimestamp(RESPONSE_DATE_FORMAT))
227                     .put(MESSAGE, "Cannot stop simulator, because it's not running").build();
228         }
229     }
230
231     private boolean isSimulatorRunning() {
232         return simulator != null && simulator.isAlive();
233     }
234 }
235