88648f91df8b282dcc6767092ae689ee4f7c7266
[integration.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * PNF-REGISTRATION-HANDLER
4  * ================================================================================
5  * Copyright (C) 2018 Nokia. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.pnfsimulator.rest;
22
23 import com.google.common.collect.ImmutableMap;
24 import com.google.gson.JsonSyntaxException;
25 import org.json.JSONException;
26 import org.onap.pnfsimulator.event.EventData;
27 import org.onap.pnfsimulator.event.EventDataService;
28 import org.onap.pnfsimulator.rest.model.FullEvent;
29 import org.onap.pnfsimulator.rest.model.SimulatorRequest;
30 import org.onap.pnfsimulator.rest.util.DateUtil;
31 import org.onap.pnfsimulator.rest.util.ResponseBuilder;
32 import org.onap.pnfsimulator.simulator.SimulatorService;
33 import org.onap.pnfsimulator.simulatorconfig.SimulatorConfig;
34 import org.quartz.SchedulerException;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import org.slf4j.MDC;
38 import org.slf4j.Marker;
39 import org.slf4j.MarkerFactory;
40 import org.springframework.beans.factory.annotation.Autowired;
41 import org.springframework.http.HttpHeaders;
42 import org.springframework.http.HttpStatus;
43 import org.springframework.http.ResponseEntity;
44 import org.springframework.web.bind.annotation.GetMapping;
45 import org.springframework.web.bind.annotation.PathVariable;
46 import org.springframework.web.bind.annotation.PostMapping;
47 import org.springframework.web.bind.annotation.PutMapping;
48 import org.springframework.web.bind.annotation.RequestBody;
49 import org.springframework.web.bind.annotation.RequestHeader;
50 import org.springframework.web.bind.annotation.RequestMapping;
51 import org.springframework.web.bind.annotation.RestController;
52
53 import javax.validation.Valid;
54 import java.io.IOException;
55 import java.net.MalformedURLException;
56 import java.text.DateFormat;
57 import java.text.SimpleDateFormat;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.UUID;
61
62 import static org.onap.pnfsimulator.logging.MDCVariables.INSTANCE_UUID;
63 import static org.onap.pnfsimulator.logging.MDCVariables.INVOCATION_ID;
64 import static org.onap.pnfsimulator.logging.MDCVariables.REQUEST_ID;
65 import static org.onap.pnfsimulator.logging.MDCVariables.RESPONSE_CODE;
66 import static org.onap.pnfsimulator.logging.MDCVariables.SERVICE_NAME;
67 import static org.onap.pnfsimulator.logging.MDCVariables.X_INVOCATION_ID;
68 import static org.onap.pnfsimulator.logging.MDCVariables.X_ONAP_REQUEST_ID;
69 import static org.onap.pnfsimulator.rest.util.ResponseBuilder.MESSAGE;
70 import static org.onap.pnfsimulator.rest.util.ResponseBuilder.TIMESTAMP;
71 import static org.springframework.http.HttpStatus.ACCEPTED;
72 import static org.springframework.http.HttpStatus.BAD_REQUEST;
73 import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
74 import static org.springframework.http.HttpStatus.NOT_FOUND;
75 import static org.springframework.http.HttpStatus.OK;
76
77 @RestController
78 @RequestMapping("/simulator")
79 public class SimulatorController {
80
81     private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorController.class);
82     private static final Marker ENTRY = MarkerFactory.getMarker("ENTRY");
83     private static final String INCORRECT_TEMPLATE_MESSAGE = "Cannot start simulator, template %s is not in valid format: %s";
84     private static final String NOT_EXISTING_TEMPLATE = "Cannot start simulator - template %s not found.";
85     private final DateFormat responseDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss,SSS");
86     private final SimulatorService simulatorService;
87     private EventDataService eventDataService;
88
89     @Autowired
90     public SimulatorController(SimulatorService simulatorService,
91                                EventDataService eventDataService) {
92         this.simulatorService = simulatorService;
93         this.eventDataService = eventDataService;
94     }
95
96     @PostMapping("test")
97     @Deprecated
98     public ResponseEntity test(@Valid @RequestBody SimulatorRequest simulatorRequest) {
99         MDC.put("test", "test");
100         LOGGER.info(ENTRY, simulatorRequest.toString());
101         return buildResponse(OK, ImmutableMap.of(MESSAGE, "message1234"));
102     }
103
104     @PostMapping(value = "start")
105     public ResponseEntity start(@RequestHeader HttpHeaders headers,
106                                 @Valid @RequestBody SimulatorRequest triggerEventRequest) {
107         logContextHeaders(headers, "/simulator/start");
108         LOGGER.info(ENTRY, "Simulator started");
109
110         try {
111             return processRequest(triggerEventRequest);
112
113         } catch (JSONException | JsonSyntaxException e) {
114             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
115             LOGGER.warn("Cannot trigger event, invalid json format: {}", e.getMessage());
116             LOGGER.debug("Received json has invalid format", e);
117             return buildResponse(BAD_REQUEST, ImmutableMap.of(MESSAGE, String
118                     .format(INCORRECT_TEMPLATE_MESSAGE, triggerEventRequest.getTemplateName(),
119                             e.getMessage())));
120         } catch (IOException e) {
121             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
122             LOGGER.warn("Json validation failed: {}", e.getMessage());
123             return buildResponse(BAD_REQUEST,
124                     ImmutableMap.of(MESSAGE, String.format(NOT_EXISTING_TEMPLATE, triggerEventRequest.getTemplateName())));
125         } catch (Exception e) {
126             MDC.put(RESPONSE_CODE, INTERNAL_SERVER_ERROR.toString());
127             LOGGER.error("Cannot trigger event - unexpected exception", e);
128             return buildResponse(INTERNAL_SERVER_ERROR,
129                     ImmutableMap.of(MESSAGE, "Unexpected exception: " + e.getMessage()));
130         } finally {
131             MDC.clear();
132         }
133     }
134
135     @GetMapping("all-events")
136     @Deprecated
137     public ResponseEntity allEvents() {
138         List<EventData> eventDataList = eventDataService.getAllEvents();
139         StringBuilder sb = new StringBuilder();
140         eventDataList.forEach(e -> sb.append(e).append(System.lineSeparator()));
141
142         return ResponseBuilder
143                 .status(OK).put(MESSAGE, sb.toString())
144                 .build();
145     }
146
147     @GetMapping("config")
148     public ResponseEntity getConfig() {
149         SimulatorConfig configToGet = simulatorService.getConfiguration();
150         return buildResponse(OK, ImmutableMap.of("simulatorConfig", configToGet));
151     }
152
153     @PutMapping("config")
154     public ResponseEntity updateConfig(@Valid @RequestBody SimulatorConfig newConfig) {
155         SimulatorConfig updatedConfig = simulatorService.updateConfiguration(newConfig);
156         return buildResponse(OK, ImmutableMap.of("simulatorConfig", updatedConfig));
157     }
158
159     @PostMapping("cancel/{jobName}")
160     public ResponseEntity cancelEvent(@PathVariable String jobName) throws SchedulerException {
161         LOGGER.info(ENTRY, "Cancel called on {}.", jobName);
162         boolean isCancelled = simulatorService.cancelEvent(jobName);
163         return createCancelEventResponse(isCancelled);
164     }
165
166     @PostMapping("cancel")
167     public ResponseEntity cancelAllEvent() throws SchedulerException {
168         LOGGER.info(ENTRY, "Cancel called on all jobs");
169         boolean isCancelled = simulatorService.cancelAllEvents();
170         return createCancelEventResponse(isCancelled);
171     }
172
173     @PostMapping("event")
174     public ResponseEntity sendEventDirectly(@RequestHeader HttpHeaders headers, @Valid @RequestBody FullEvent event) throws MalformedURLException {
175         logContextHeaders(headers, "/simulator/event");
176         LOGGER.info(ENTRY, "Trying to send one-time event directly to VES Collector");
177         simulatorService.triggerOneTimeEvent(event);
178         return buildResponse(ACCEPTED, ImmutableMap.of(MESSAGE, "One-time direct event sent successfully"));
179     }
180
181     private ResponseEntity processRequest(SimulatorRequest triggerEventRequest)
182             throws IOException, SchedulerException {
183
184         String jobName = simulatorService.triggerEvent(triggerEventRequest);
185         MDC.put(RESPONSE_CODE, OK.toString());
186         return buildResponse(OK, ImmutableMap.of(MESSAGE, "Request started", "jobName", jobName));
187     }
188
189     private ResponseEntity buildResponse(HttpStatus endStatus, Map<String, Object> parameters) {
190         ResponseBuilder builder = ResponseBuilder
191                 .status(endStatus)
192                 .put(TIMESTAMP, DateUtil.getTimestamp(responseDateFormat));
193         parameters.forEach(builder::put);
194         return builder.build();
195     }
196
197     private void logContextHeaders(HttpHeaders headers, String serviceName) {
198         MDC.put(REQUEST_ID, headers.getFirst(X_ONAP_REQUEST_ID));
199         MDC.put(INVOCATION_ID, headers.getFirst(X_INVOCATION_ID));
200         MDC.put(INSTANCE_UUID, UUID.randomUUID().toString());
201         MDC.put(SERVICE_NAME, serviceName);
202     }
203
204     private ResponseEntity createCancelEventResponse(boolean isCancelled) {
205         if (isCancelled) {
206             return buildResponse(OK, ImmutableMap.of(MESSAGE, "Event(s) was cancelled"));
207         } else {
208             return buildResponse(NOT_FOUND, ImmutableMap.of(MESSAGE, "Simulator was not able to cancel event(s)"));
209         }
210     }
211 }