0e4bd56ad5ee23d1b6b434444e9fbeb7cff4131e
[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.security.GeneralSecurityException;
57 import java.text.DateFormat;
58 import java.text.SimpleDateFormat;
59 import java.util.List;
60 import java.util.Map;
61 import java.util.UUID;
62
63 import static org.onap.pnfsimulator.logging.MDCVariables.INSTANCE_UUID;
64 import static org.onap.pnfsimulator.logging.MDCVariables.INVOCATION_ID;
65 import static org.onap.pnfsimulator.logging.MDCVariables.REQUEST_ID;
66 import static org.onap.pnfsimulator.logging.MDCVariables.RESPONSE_CODE;
67 import static org.onap.pnfsimulator.logging.MDCVariables.SERVICE_NAME;
68 import static org.onap.pnfsimulator.logging.MDCVariables.X_INVOCATION_ID;
69 import static org.onap.pnfsimulator.logging.MDCVariables.X_ONAP_REQUEST_ID;
70 import static org.onap.pnfsimulator.rest.util.ResponseBuilder.MESSAGE;
71 import static org.onap.pnfsimulator.rest.util.ResponseBuilder.TIMESTAMP;
72 import static org.springframework.http.HttpStatus.ACCEPTED;
73 import static org.springframework.http.HttpStatus.BAD_REQUEST;
74 import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
75 import static org.springframework.http.HttpStatus.NOT_FOUND;
76 import static org.springframework.http.HttpStatus.OK;
77
78 @RestController
79 @RequestMapping("/simulator")
80 public class SimulatorController {
81
82     private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorController.class);
83     private static final Marker ENTRY = MarkerFactory.getMarker("ENTRY");
84     private static final String INCORRECT_TEMPLATE_MESSAGE = "Cannot start simulator, template %s is not in valid format: %s";
85     private static final String NOT_EXISTING_TEMPLATE = "Cannot start simulator - template %s not found.";
86     private final DateFormat responseDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss,SSS");
87     private final SimulatorService simulatorService;
88     private EventDataService eventDataService;
89
90     @Autowired
91     public SimulatorController(SimulatorService simulatorService,
92                                EventDataService eventDataService) {
93         this.simulatorService = simulatorService;
94         this.eventDataService = eventDataService;
95     }
96
97     @PostMapping("test")
98     @Deprecated
99     public ResponseEntity test(@Valid @RequestBody SimulatorRequest simulatorRequest) {
100         MDC.put("test", "test");
101         LOGGER.info(ENTRY, simulatorRequest.toString());
102         return buildResponse(OK, ImmutableMap.of(MESSAGE, "message1234"));
103     }
104
105     @PostMapping(value = "start")
106     public ResponseEntity start(@RequestHeader HttpHeaders headers,
107                                 @Valid @RequestBody SimulatorRequest triggerEventRequest) {
108         logContextHeaders(headers, "/simulator/start");
109         LOGGER.info(ENTRY, "Simulator started");
110
111         try {
112             return processRequest(triggerEventRequest);
113
114         } catch (JSONException | JsonSyntaxException e) {
115             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
116             LOGGER.warn("Cannot trigger event, invalid json format: {}", e.getMessage());
117             LOGGER.debug("Received json has invalid format", e);
118             return buildResponse(BAD_REQUEST, ImmutableMap.of(MESSAGE, String
119                     .format(INCORRECT_TEMPLATE_MESSAGE, triggerEventRequest.getTemplateName(),
120                             e.getMessage())));
121         } catch (GeneralSecurityException e ){
122             MDC.put(RESPONSE_CODE, INTERNAL_SERVER_ERROR.toString() );
123             LOGGER.error("Client certificate validation failed: {}", e.getMessage());
124             return buildResponse(INTERNAL_SERVER_ERROR,
125                     ImmutableMap.of(MESSAGE, "Invalid or misconfigured client certificate"));
126         }
127          catch (IOException e) {
128             MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
129             LOGGER.warn("Json validation failed: {}", e.getMessage());
130             return buildResponse(BAD_REQUEST,
131                     ImmutableMap.of(MESSAGE, String.format(NOT_EXISTING_TEMPLATE, triggerEventRequest.getTemplateName())));
132         } catch (Exception e) {
133             MDC.put(RESPONSE_CODE, INTERNAL_SERVER_ERROR.toString());
134             LOGGER.error("Cannot trigger event - unexpected exception", e);
135             return buildResponse(INTERNAL_SERVER_ERROR,
136                     ImmutableMap.of(MESSAGE, "Unexpected exception: " + e.getMessage()));
137         } finally {
138             MDC.clear();
139         }
140     }
141
142     @GetMapping("all-events")
143     @Deprecated
144     public ResponseEntity allEvents() {
145         List<EventData> eventDataList = eventDataService.getAllEvents();
146         StringBuilder sb = new StringBuilder();
147         eventDataList.forEach(e -> sb.append(e).append(System.lineSeparator()));
148
149         return ResponseBuilder
150                 .status(OK).put(MESSAGE, sb.toString())
151                 .build();
152     }
153
154     @GetMapping("config")
155     public ResponseEntity getConfig() {
156         SimulatorConfig configToGet = simulatorService.getConfiguration();
157         return buildResponse(OK, ImmutableMap.of("simulatorConfig", configToGet));
158     }
159
160     @PutMapping("config")
161     public ResponseEntity updateConfig(@Valid @RequestBody SimulatorConfig newConfig) {
162         SimulatorConfig updatedConfig = simulatorService.updateConfiguration(newConfig);
163         return buildResponse(OK, ImmutableMap.of("simulatorConfig", updatedConfig));
164     }
165
166     @PostMapping("cancel/{jobName}")
167     public ResponseEntity cancelEvent(@PathVariable String jobName) throws SchedulerException {
168         LOGGER.info(ENTRY, "Cancel called on {}.", jobName);
169         boolean isCancelled = simulatorService.cancelEvent(jobName);
170         return createCancelEventResponse(isCancelled);
171     }
172
173     @PostMapping("cancel")
174     public ResponseEntity cancelAllEvent() throws SchedulerException {
175         LOGGER.info(ENTRY, "Cancel called on all jobs");
176         boolean isCancelled = simulatorService.cancelAllEvents();
177         return createCancelEventResponse(isCancelled);
178     }
179
180     @PostMapping("event")
181     public ResponseEntity sendEventDirectly(@RequestHeader HttpHeaders headers, @Valid @RequestBody FullEvent event)
182             throws IOException, GeneralSecurityException{
183         logContextHeaders(headers, "/simulator/event");
184         LOGGER.info(ENTRY, "Trying to send one-time event directly to VES Collector");
185         simulatorService.triggerOneTimeEvent(event);
186         return buildResponse(ACCEPTED, ImmutableMap.of(MESSAGE, "One-time direct event sent successfully"));
187     }
188
189     private ResponseEntity processRequest(SimulatorRequest triggerEventRequest)
190             throws IOException, SchedulerException, GeneralSecurityException {
191
192         String jobName = simulatorService.triggerEvent(triggerEventRequest);
193         MDC.put(RESPONSE_CODE, OK.toString());
194         return buildResponse(OK, ImmutableMap.of(MESSAGE, "Request started", "jobName", jobName));
195     }
196
197     private ResponseEntity buildResponse(HttpStatus endStatus, Map<String, Object> parameters) {
198         ResponseBuilder builder = ResponseBuilder
199                 .status(endStatus)
200                 .put(TIMESTAMP, DateUtil.getTimestamp(responseDateFormat));
201         parameters.forEach(builder::put);
202         return builder.build();
203     }
204
205     private void logContextHeaders(HttpHeaders headers, String serviceName) {
206         MDC.put(REQUEST_ID, headers.getFirst(X_ONAP_REQUEST_ID));
207         MDC.put(INVOCATION_ID, headers.getFirst(X_INVOCATION_ID));
208         MDC.put(INSTANCE_UUID, UUID.randomUUID().toString());
209         MDC.put(SERVICE_NAME, serviceName);
210     }
211
212     private ResponseEntity createCancelEventResponse(boolean isCancelled) {
213         if (isCancelled) {
214             return buildResponse(OK, ImmutableMap.of(MESSAGE, "Event(s) was cancelled"));
215         } else {
216             return buildResponse(NOT_FOUND, ImmutableMap.of(MESSAGE, "Simulator was not able to cancel event(s)"));
217         }
218     }
219 }