Upgrade sonar plugin
[vid.git] / vid-app-common / src / main / java / org / openecomp / vid / controller / test / TestMsoController.java
1 /*-\r
2  * ============LICENSE_START=======================================================\r
3  * VID\r
4  * ================================================================================\r
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.\r
6  * ================================================================================\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  * \r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * \r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  * ============LICENSE_END=========================================================\r
19  */\r
20 \r
21 package  org.openecomp.vid.controller.test;\r
22 \r
23 import java.io.IOException;\r
24 import java.util.stream.Collectors;\r
25 \r
26 import javax.servlet.http.HttpServletRequest;\r
27 import javax.servlet.http.HttpServletResponse;\r
28 \r
29 import org.codehaus.jackson.map.ObjectMapper;\r
30 import org.openecomp.vid.model.ExceptionResponse;\r
31 import org.springframework.http.HttpStatus;\r
32 import org.springframework.http.ResponseEntity;\r
33 import org.springframework.web.bind.annotation.ExceptionHandler;\r
34 import org.springframework.web.bind.annotation.PathVariable;\r
35 import org.springframework.web.bind.annotation.RequestMapping;\r
36 import org.springframework.web.bind.annotation.RequestMethod;\r
37 import org.springframework.web.bind.annotation.RestController;\r
38 \r
39 import org.openecomp.portalsdk.core.controller.RestrictedBaseController;\r
40 \r
41 /*\r
42  * The "TestMsoController" class is primarily designed to help test "msoCommitController.js"\r
43  * \r
44  * This class expects and receives JSON data in the same format as expected\r
45  * in the "real" application version of this code. However, string versions of JSON are\r
46  * maintained internally here instead of marshalled / unmarshalled JSON objects.\r
47  * The primary reasons for this were to encapsulate all the test code in this single file and\r
48  * minimize the time required to support initial test cases.\r
49  * \r
50  * The non-test equivalent of this controller could alternatively incorporate POJO objects\r
51  * instead of strings. However, the same data format sent to / received from the browser\r
52  * JavaScript code would still be expected.\r
53  * \r
54  * Two specific mechanisms used in this test class may be useful to the application version:\r
55  * \r
56  *              1) The use of "{variable}" elements in @RequestMappings along with the corresponding\r
57  *              @PathVariable declarations.\r
58  * \r
59  *              2) The use of @ExceptionHandler for general purpose exception handler.\r
60  *              (See @ExceptionHandler comments)\r
61  *\r
62  * This class is intended to be used in either:\r
63  * \r
64  *              A) Eclipse environments\r
65  *      OR\r
66  *              B) Linux environments with ONLY a single user running tests.\r
67  *              The "quick and dirty" error simulation approach used here makes use of static states for some\r
68  *              scenarios. Thus multiple users simultaneously testing in Linux environments\r
69  *              may have contention issues.\r
70  */\r
71 \r
72 /**\r
73  * The Class TestMsoController.\r
74  */\r
75 @RestController\r
76 @RequestMapping("testmso")\r
77 public class TestMsoController extends RestrictedBaseController {\r
78 \r
79         /*\r
80          * Artificial delay (in milliseconds) added before responding to create /\r
81          * delete requests\r
82          */\r
83 \r
84         /** The Constant TEST_DELAY_SHORT_MSEC. */\r
85         private final static int TEST_DELAY_SHORT_MSEC = 1000;\r
86 \r
87         /*\r
88          * Long delay to simulate non-responsive server test\r
89          */\r
90 \r
91         /** The Constant TEST_DELAY_LONG_MSEC. */\r
92         private final static int TEST_DELAY_LONG_MSEC = 15000;\r
93 \r
94         /*\r
95          * Default number of polls expected before transaction complete.\r
96          */\r
97 \r
98         /** The Constant MAXIMUM_POLLS_DEFAULT. */\r
99         private final static int MAXIMUM_POLLS_DEFAULT = 4;\r
100 \r
101         /*\r
102          * Number of polls to simulate "maximum polls exceeded" test.\r
103          */\r
104 \r
105         /** The Constant MAXIMUM_POLLS_LARGE. */\r
106         private final static int MAXIMUM_POLLS_LARGE = 10;\r
107 \r
108         /*\r
109          * Simulated error types. The GUI front end is expected to set these values\r
110          * in the "modelName" field of the "mso_create_svc_instance" request.\r
111          */\r
112 \r
113         /** The Constant ERROR_POLICY_EXCEPTION. */\r
114         private final static String ERROR_POLICY_EXCEPTION = "ERROR_POLICY_EXCEPTION";\r
115         \r
116         /** The Constant ERROR_SERVICE_EXCEPTION. */\r
117         private final static String ERROR_SERVICE_EXCEPTION = "ERROR_SERVICE_EXCEPTION";\r
118         \r
119         /** The Constant ERROR_POLL_FAILURE. */\r
120         private final static String ERROR_POLL_FAILURE = "ERROR_POLL_FAILURE";\r
121         \r
122         /** The Constant ERROR_INVALID_FIELD_INITIAL. */\r
123         private final static String ERROR_INVALID_FIELD_INITIAL = "ERROR_INVALID_FIELD_INITIAL";\r
124         \r
125         /** The Constant ERROR_INVALID_FIELD_POLL. */\r
126         private final static String ERROR_INVALID_FIELD_POLL = "ERROR_INVALID_FIELD_POLL";\r
127         \r
128         /** The Constant ERROR_GENERAL_SERVER_EXCEPTION. */\r
129         private final static String ERROR_GENERAL_SERVER_EXCEPTION = "ERROR_GENERAL_SERVER_EXCEPTION";\r
130         \r
131         /** The Constant ERROR_MAX_POLLS. */\r
132         private final static String ERROR_MAX_POLLS = "ERROR_MAX_POLLS";\r
133         \r
134         /** The Constant ERROR_SERVER_TIMEOUT_INITIAL. */\r
135         private final static String ERROR_SERVER_TIMEOUT_INITIAL = "ERROR_SERVER_TIMEOUT_INITIAL";\r
136         \r
137         /** The Constant ERROR_SERVER_TIMEOUT_POLL. */\r
138         private final static String ERROR_SERVER_TIMEOUT_POLL = "ERROR_SERVER_TIMEOUT_POLL";\r
139 \r
140         /** The simulated error. */\r
141         private String simulatedError = "";\r
142         \r
143         /** The maximum polls. */\r
144         private int maximumPolls = 0;\r
145         \r
146         /** The attempt count. */\r
147         private int attemptCount = 0;\r
148 \r
149         /**\r
150          * Creates the svc instance.\r
151          *\r
152          * @param request the request\r
153          * @return the response entity\r
154          * @throws Exception the exception\r
155          */\r
156         @RequestMapping(value = "/mso_create_svc_instance", method = RequestMethod.POST)\r
157         public ResponseEntity<String> createSvcInstance(HttpServletRequest request) throws Exception {\r
158                 readAndLogRequest("CREATE SERVICE INSTANCE", request);\r
159                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
160                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
161                 attemptCount = 0;\r
162 \r
163                 /*\r
164                  * This block of code simulates various errors and would NOT be expected\r
165                  * in a non-test method\r
166                  */\r
167                 System.err.println("simulatedError: " + simulatedError);\r
168 \r
169                 if (simulatedError.equals(ERROR_POLICY_EXCEPTION)) {\r
170                         return new ResponseEntity<String>(policyExceptionResponse, HttpStatus.OK);\r
171                 }\r
172                 if (simulatedError.equals(ERROR_SERVICE_EXCEPTION)) {\r
173                         return new ResponseEntity<String>(serviceExceptionResponse, HttpStatus.OK);\r
174                 }\r
175                 if (simulatedError.equals(ERROR_INVALID_FIELD_INITIAL)) {\r
176                         /*\r
177                          * Force invalid response field name. Return\r
178                          * "XXXXXrequestReferences" instead of "requestReferences"\r
179                          */\r
180                         return new ResponseEntity<String>(acceptResponse.replace("requestReferences", "XXXXXrequestReferences"),\r
181                                         HttpStatus.OK);\r
182                 }\r
183 \r
184                 if (simulatedError.equals(ERROR_GENERAL_SERVER_EXCEPTION)) {\r
185                         throw new IOException("an example of an IO exception");\r
186                 }\r
187 \r
188                 if (simulatedError.equals(ERROR_SERVER_TIMEOUT_INITIAL)) {\r
189                         Thread.sleep(TEST_DELAY_LONG_MSEC);\r
190                 }\r
191 \r
192                 if (simulatedError.equals(ERROR_MAX_POLLS)) {\r
193                         maximumPolls = MAXIMUM_POLLS_LARGE;\r
194                 }\r
195 \r
196                 /*\r
197                  * End of block of simulated error code.\r
198                  */\r
199 \r
200                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
201         }\r
202 \r
203         /**\r
204          * Delete svc instance.\r
205          *\r
206          * @param serviceInstanceId the service instance id\r
207          * @param request the request\r
208          * @return the response entity\r
209          * @throws Exception the exception\r
210          */\r
211         @RequestMapping(value = "/mso_delete_svc_instance/{serviceInstanceId}", method = RequestMethod.POST)\r
212         public ResponseEntity<String> deleteSvcInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,\r
213                         HttpServletRequest request) throws Exception {\r
214                 readAndLogRequest("DELETE SERVICE INSTANCE: serviceInstanceId: " + serviceInstanceId, request);\r
215                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
216                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
217                 attemptCount = 0;\r
218                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
219         }\r
220 \r
221         /**\r
222          * Creates the vnf instance.\r
223          *\r
224          * @param serviceInstanceId the service instance id\r
225          * @param request the request\r
226          * @return the response entity\r
227          * @throws Exception the exception\r
228          */\r
229         @RequestMapping(value = "/mso_create_vnf_instance/{serviceInstanceId}", method = RequestMethod.POST)\r
230         public ResponseEntity<String> createVnfInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,\r
231                         HttpServletRequest request) throws Exception {\r
232                 readAndLogRequest("CREATE VNF INSTANCE: serviceInstanceId: " + serviceInstanceId, request);\r
233                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
234                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
235                 attemptCount = 0;\r
236                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
237         }\r
238 \r
239         /**\r
240          * Delete vnf instance.\r
241          *\r
242          * @param serviceInstanceId the service instance id\r
243          * @param vnfInstanceId the vnf instance id\r
244          * @param request the request\r
245          * @return the response entity\r
246          * @throws Exception the exception\r
247          */\r
248         @RequestMapping(value = "/mso_delete_vnf_instance/{serviceInstanceId}/vnfs/{vnfInstanceId}", method = RequestMethod.POST)\r
249         public ResponseEntity<String> deleteVnfInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,\r
250                         @PathVariable("vnfInstanceId") String vnfInstanceId, HttpServletRequest request) throws Exception {\r
251                 readAndLogRequest(\r
252                                 "DELETE VNF INSTANCE: serviceInstanceId: " + serviceInstanceId + " vnfInstanceId: " + vnfInstanceId,\r
253                                 request);\r
254                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
255                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
256                 attemptCount = 0;\r
257                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
258         }\r
259 \r
260         /**\r
261          * Creates the vf module instance.\r
262          *\r
263          * @param serviceInstanceId the service instance id\r
264          * @param vnfInstanceId the vnf instance id\r
265          * @param request the request\r
266          * @return the response entity\r
267          * @throws Exception the exception\r
268          */\r
269         // /serviceInstances/v2/ff305d54-75b4-431b-adb2-eb6b9e5ff000/vnfs/ff305d54-75b4-ff1b-adb2-eb6b9e5460ff/vfModules\r
270         @RequestMapping(value = "/mso_create_vfmodule_instance/{serviceInstanceId}/vnfs/{vnfInstanceId}", method = RequestMethod.POST)\r
271         public ResponseEntity<String> createVfModuleInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,\r
272                         @PathVariable("vnfInstanceId") String vnfInstanceId, HttpServletRequest request) throws Exception {\r
273                 readAndLogRequest("CREATE VF MODULE INSTANCE: serviceInstanceId: " + serviceInstanceId + " vnfInstanceId: "\r
274                                 + vnfInstanceId, request);\r
275                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
276                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
277                 attemptCount = 0;\r
278                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
279         }\r
280 \r
281         /**\r
282          * Delete vf module instance.\r
283          *\r
284          * @param serviceInstanceId the service instance id\r
285          * @param vnfInstanceId the vnf instance id\r
286          * @param vfModuleInstanceId the vf module instance id\r
287          * @param request the request\r
288          * @return the response entity\r
289          * @throws Exception the exception\r
290          */\r
291         // /serviceInstances/v2/ff305d54-75b4-431b-adb2-eb6b9e5ff000/vnfs/ff305d54-75b4-ff1b-adb2-eb6b9e5460ff/vfModules/ff305d54-75b4-ff1b-bdb2-eb6b9e5460ff\r
292         @RequestMapping(value = "/mso_delete_vfmodule_instance/{serviceInstanceId}/vnfs/{vnfInstanceId}/vfModules/{vfModuleInstanceId}", method = RequestMethod.POST)\r
293         public ResponseEntity<String> deleteVfModuleInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,\r
294                         @PathVariable("vnfInstanceId") String vnfInstanceId,\r
295                         @PathVariable("vfModuleInstanceId") String vfModuleInstanceId, HttpServletRequest request)\r
296                         throws Exception {\r
297                 readAndLogRequest("DELETE VF MODULE INSTANCE: serviceInstanceId: " + serviceInstanceId + " vnfInstanceId: "\r
298                                 + vnfInstanceId + " vfModuleInstanceId: " + vfModuleInstanceId, request);\r
299                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
300                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
301                 attemptCount = 0;\r
302                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
303         }\r
304 \r
305         // POST\r
306         /**\r
307          * Creates the volume group instance.\r
308          *\r
309          * @param serviceInstanceId the service instance id\r
310          * @param vnfInstanceId the vnf instance id\r
311          * @param request the request\r
312          * @return the response entity\r
313          * @throws Exception the exception\r
314          */\r
315         // /serviceInstances/v2/ff305d54-75b4-431b-adb2-eb6b9e5ff000/volumeGroups\r
316         @RequestMapping(value = "/mso_create_volumegroup_instance/{serviceInstanceId}/vnfs/{vnfInstanceId}", method = RequestMethod.POST)\r
317         public ResponseEntity<String> createVolumeGroupInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,\r
318                         @PathVariable("vnfInstanceId") String vnfInstanceId, HttpServletRequest request) throws Exception {\r
319                 readAndLogRequest("CREATE VOLUME GROUP INSTANCE: seviceInstanceId: " + serviceInstanceId + " vnfInstanceId: "\r
320                                 + vnfInstanceId, request);\r
321                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
322                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
323                 attemptCount = 0;\r
324                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
325         }\r
326 \r
327         /**\r
328          * Delete volume group instance.\r
329          *\r
330          * @param serviceInstanceId the service instance id\r
331          * @param vnfInstanceId the vnf instance id\r
332          * @param volumeGroupInstanceId the volume group instance id\r
333          * @param request the request\r
334          * @return the response entity\r
335          * @throws Exception the exception\r
336          */\r
337         // /serviceInstances/v2/ff305d54-75b4-431b-adb2-eb6b9e5ff000/volumeGroups/ff305d54-75b4-ff1b-cdb2-eb6b9e5460ff\r
338         @RequestMapping(value = "/mso_delete_volumegroup_instance/{serviceInstanceId}/vnfs/{vnfInstanceId}/volumeGroups/{volumeGroupInstanceId}", method = RequestMethod.POST)\r
339         public ResponseEntity<String> deleteVolumeGroupInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,\r
340                         @PathVariable("vnfInstanceId") String vnfInstanceId,\r
341                         @PathVariable("volumeGroupInstanceId") String volumeGroupInstanceId, HttpServletRequest request)\r
342                         throws Exception {\r
343                 readAndLogRequest("DELETE NW INSTANCE: serviceInstanceId: " + serviceInstanceId + " vnfInstanceId: "\r
344                                 + vnfInstanceId + " volumeGroupInstanceId: " + volumeGroupInstanceId, request);\r
345                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
346                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
347                 attemptCount = 0;\r
348                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
349         }\r
350 \r
351         /**\r
352          * Creates the nw instance.\r
353          *\r
354          * @param serviceInstanceId the service instance id\r
355          * @param request the request\r
356          * @return the response entity\r
357          * @throws Exception the exception\r
358          */\r
359         @RequestMapping(value = "/mso_create_nw_instance/{serviceInstanceId}", method = RequestMethod.POST)\r
360         public ResponseEntity<String> createNwInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,\r
361                         HttpServletRequest request) throws Exception {\r
362                 readAndLogRequest("CREATE NW INSTANCE: serviceInstanceId: " + serviceInstanceId, request);\r
363                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
364                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
365                 attemptCount = 0;\r
366                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
367         }\r
368 \r
369         /**\r
370          * Delete nw instance.\r
371          *\r
372          * @param serviceInstanceId the service instance id\r
373          * @param networkInstanceId the network instance id\r
374          * @param request the request\r
375          * @return the response entity\r
376          * @throws Exception the exception\r
377          */\r
378         @RequestMapping(value = "/mso_delete_nw_instance/{serviceInstanceId}/networks/{networkInstanceId}", method = RequestMethod.POST)\r
379         public ResponseEntity<String> deleteNwInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,\r
380                         @PathVariable("networkInstanceId") String networkInstanceId, HttpServletRequest request) throws Exception {\r
381                 readAndLogRequest("DELETE NW INSTANCE: serviceInstanceId: " + serviceInstanceId + " networkInstanceId: "\r
382                                 + networkInstanceId, request);\r
383                 Thread.sleep(TEST_DELAY_SHORT_MSEC);\r
384                 maximumPolls = MAXIMUM_POLLS_DEFAULT; // Simulates MSO polling behavior\r
385                 attemptCount = 0;\r
386                 return new ResponseEntity<String>(acceptResponse, HttpStatus.OK);\r
387         }\r
388 \r
389         /**\r
390          * Gets the orchestration request.\r
391          *\r
392          * @param requestId the request id\r
393          * @param request the request\r
394          * @return the orchestration request\r
395          * @throws Exception the exception\r
396          */\r
397         @RequestMapping(value = "/mso_get_orch_req/{requestId}", method = RequestMethod.GET)\r
398         public ResponseEntity<String> getOrchestrationRequest(@PathVariable("requestId") String requestId,\r
399                         HttpServletRequest request) throws Exception {\r
400 \r
401                 System.err.println("GET ORCHESTRATION REQUEST: requestId: " + requestId);\r
402 \r
403                 /*\r
404                  * This block of code simulates various errors and would NOT be expected\r
405                  * in a non-test method\r
406                  */\r
407 \r
408                 if (simulatedError.equals(ERROR_INVALID_FIELD_POLL)) {\r
409                         /*\r
410                          * Force invalid response field name. Return "XXXXXrequestStatus"\r
411                          * instead of "requestStatus"\r
412                          */\r
413                         return new ResponseEntity<String>(inProgressResponse.replace("requestStatus", "XXXXXrequestStatus"),\r
414                                         HttpStatus.OK);\r
415                 }\r
416 \r
417                 if (simulatedError.equals(ERROR_POLL_FAILURE)) {\r
418                         /*\r
419                          * Force status field with "Failure"\r
420                          */\r
421                         return new ResponseEntity<String>(inProgressResponse.replace("InProgress", "Failure"), HttpStatus.OK);\r
422                 }\r
423 \r
424                 if (simulatedError.equals(ERROR_SERVER_TIMEOUT_POLL)) {\r
425                         Thread.sleep(TEST_DELAY_LONG_MSEC);\r
426                 }\r
427 \r
428                 /*\r
429                  * End of block of simulated error code.\r
430                  */\r
431 \r
432                 /*\r
433                  * This logic simulates how MSO might behave ... i.e. return different\r
434                  * results depending on the value of 'maximumPolls'.\r
435                  *\r
436                  */\r
437                 int percentProgress = (++attemptCount * 100) / maximumPolls;\r
438 \r
439                 System.err.println("attempts: " + attemptCount + " max: " + maximumPolls + " percent: " + percentProgress);\r
440 \r
441                 String response = inProgressResponse.replace("\"50\"", "\"" + Integer.toString(percentProgress) + "\"");\r
442 \r
443                 if (attemptCount < maximumPolls) {\r
444                         if (attemptCount > 1) {\r
445                                 response = response.replace("vLan setup", "setup step " + Integer.toString(attemptCount));\r
446                         }\r
447                         return new ResponseEntity<String>(response, HttpStatus.OK);\r
448                 } else {\r
449                         return new ResponseEntity<String>(\r
450                                         response.replace("InProgress", "Complete").replace("vLan setup complete", ""), HttpStatus.OK);\r
451                 }\r
452         }\r
453 \r
454         /**\r
455          * Gets the orchestration requests.\r
456          *\r
457          * @param filterString the filter string\r
458          * @param request the request\r
459          * @return the orchestration requests\r
460          * @throws Exception the exception\r
461          */\r
462         @RequestMapping(value = "/mso_get_orch_reqs/{filterString}", method = RequestMethod.GET)\r
463         public ResponseEntity<String> getOrchestrationRequests(@PathVariable("filterString") String filterString,\r
464                         HttpServletRequest request) throws Exception {\r
465 \r
466                 System.err.println("GET ORCHESTRATION REQUESTS: filterString: " + filterString);\r
467 \r
468                 return new ResponseEntity<String>(getOrchestrationRequestsResponse, HttpStatus.OK);\r
469 \r
470         }\r
471 \r
472         /*\r
473          * General purpose exception handler that could be used in application code.\r
474          * \r
475          * The method returns exceptions as error code 500. Both the exception type\r
476          * and message are written as a JSON object.\r
477          * \r
478          * See the following references:\r
479          * \r
480          * 1) The ExceptionResponse POJO.\r
481          * \r
482          * 2) The "getHttpErrorMessage" function in "utilityService.js" - an example\r
483          * of how the browser JavaScript code can interpret this response.\r
484          */\r
485 \r
486         /**\r
487          * Exception.\r
488          *\r
489          * @param e the e\r
490          * @param response the response\r
491          * @throws IOException Signals that an I/O exception has occurred.\r
492          */\r
493         @ExceptionHandler(Exception.class)\r
494         private void exception(Exception e, HttpServletResponse response) throws IOException {\r
495 \r
496                 /*\r
497                  * This logging step should preferably be replaced with an appropriate\r
498                  * logging method consistent whatever logging mechanism the rest of the\r
499                  * application code uses.\r
500                  */\r
501 \r
502                 e.printStackTrace(System.err);\r
503 \r
504                 response.setContentType("application/json; charset=UTF-8");\r
505                 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\r
506 \r
507                 ExceptionResponse exceptionResponse = new ExceptionResponse();\r
508                 exceptionResponse.setException(e.getClass().toString().replaceFirst("^.*\\.", ""));\r
509                 exceptionResponse.setMessage(e.getMessage());\r
510 \r
511                 response.getWriter().write(new ObjectMapper().writeValueAsString(exceptionResponse));\r
512 \r
513                 response.flushBuffer();\r
514 \r
515         }\r
516 \r
517         /*\r
518          * 'readAndLogRequest' only intended to be used for testing.\r
519          * \r
520          * The method reads JSON from the input stream and thus prevents other\r
521          * mechanisms from reading the input.\r
522          */\r
523 \r
524         /**\r
525          * Read and log request.\r
526          *\r
527          * @param label the label\r
528          * @param request the request\r
529          * @throws Exception the exception\r
530          */\r
531         private void readAndLogRequest(String label, HttpServletRequest request) throws Exception {\r
532                 String input = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));\r
533 \r
534                 ObjectMapper mapper = new ObjectMapper();\r
535                 Object json = mapper.readValue(input, Object.class);\r
536 \r
537                 System.err.println(label + "\n" + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json));\r
538 \r
539                 /*\r
540                  * Only needed for error simulation ...\r
541                  */\r
542                 if (input.matches("^.*modelName.*$")) {\r
543                         simulatedError = input.replaceAll("^.*\"modelName\":\"", "").replaceAll("\".*$", "");\r
544                 }\r
545         }\r
546 \r
547         /*\r
548          * Various test responses:\r
549          */\r
550 \r
551         // @formatter:off\r
552 \r
553         /** The accept response. */\r
554         /*\r
555          * Sample responses to initial create / delete transaction\r
556          */\r
557         private String acceptResponse =\r
558            "{" +\r
559             "  \"status\": 202," +\r
560             "  \"entity\": {" +\r
561             "      \"requestReferences\": {" +\r
562             "         \"instanceId\": \"bc305d54-75b4-431b-adb2-eb6b9e546014\"," +\r
563             "         \"requestId\": \"rq1234d1-5a33-55df-13ab-12abad84e331\"" +\r
564             "      }" +\r
565             "  }" +\r
566             "}";\r
567         \r
568         /** The policy exception response. */\r
569         private String policyExceptionResponse = \r
570                 "{" + \r
571                 "  \"status\": 400," + \r
572                 "  \"entity\": { " + \r
573                 "    \"requestError\": {" + \r
574                 "      \"policyException\": {" + \r
575                 "        \"messageId\": \"POL9003\"," + \r
576                 "        \"text\": \"Message content size exceeds the allowable limit\"" + \r
577                 "      }" + \r
578                 "    }" + \r
579                 "  }" + \r
580                 "}";\r
581 \r
582         /** The service exception response. */\r
583         private String serviceExceptionResponse =\r
584                 "{" + \r
585                 "  \"status\": 400," + \r
586                 "  \"entity\": { " + \r
587                 "    \"requestError\": {" + \r
588                 "      \"serviceException\": {" + \r
589                 "        \"messageId\": \"SVC2000\"," + \r
590                 "        \"text\": \"Missing Parameter: %1. Error code is %2\"," + \r
591                 "        \"variables\": [" + \r
592                 "          \"severity\"," + \r
593                 "          \"400\"" + \r
594                 "        ]" + \r
595                 "      }" + \r
596                 "    }" + \r
597                 "  }" + \r
598                 "}" + \r
599                 "";\r
600         \r
601         /** The in progress response. */\r
602         /*\r
603          * Sample response to subsequent getOrchestrationRequest\r
604          */\r
605         private String inProgressResponse =\r
606                 "{" +\r
607                 "   \"status\": 200," +\r
608                 "   \"entity\": {" +\r
609                 "      \"request\": {" +\r
610                 "         \"requestId\": \"rq1234d1-5a33-55df-13ab-12abad84e333\"," +\r
611                 "         \"startTime\": \"Thu, 04 Jun 2009 02:51:59 GMT\"," +\r
612                 "         \"instanceIds\": {" +\r
613                 "            \"serviceInstanceId\": \"bc305d54-75b4-431b-adb2-eb6b9e546014\"" +\r
614                 "         }," +\r
615                 "         \"requestScope\": \"service\"," +\r
616                 "         \"requestType\": \"createInstance\"," +\r
617                 "         \"requestDetails\": {" +\r
618                 "            \"modelInfo\": {" +\r
619                 "               \"modelType\": \"service\"," +\r
620                 "               \"modelId\": \"sn5256d1-5a33-55df-13ab-12abad84e764\"," +\r
621                 "               \"modelNameVersionId\": \"ab6478e4-ea33-3346-ac12-ab121484a333\"," +\r
622                 "               \"modelName\": \"WanBonding\"," +\r
623                 "               \"modelVersion\": \"1\"" +\r
624                 "            }," +\r
625                 "            \"subscriberInfo\": {" +\r
626                 "                \"globalSubscriberId\": \"C12345\"," +\r
627                 "                \"subscriberName\": \"General Electric Division 12\"" +\r
628                 "            }," +\r
629                 "            \"requestParameters\": {" +\r
630                 "               \"vpnId\": \"1a2b3c4d5e6f\"," +\r
631                 "               \"productName\": \"Trinity\"," +\r
632                 "               \"customerId\": \"icore9883749\"" +\r
633                 "            }" +\r
634                 "         }," +\r
635                 "         \"requestStatus\": {" +\r
636                 "            \"timestamp\": \"Thu, 04 Jun 2009 02:53:39 GMT\"," +\r
637                 "            \"requestState\": \"InProgress\"," +\r
638                 "            \"statusMessage\": \"vLan setup complete\"," +\r
639                 "            \"percentProgress\": \"50\"" +\r
640                 "         }" +\r
641                 "      }" +\r
642                 "   }" +\r
643                 "}";\r
644         \r
645         /*\r
646          * Sample response to subsequent getOrchestrationRequests\r
647          */\r
648         \r
649         /** The get orchestration requests response. */\r
650         private String getOrchestrationRequestsResponse = \r
651                 "{" +\r
652                 "   \"status\": 200," +\r
653                 "   \"entity\": {" +\r
654                 "      \"requestList\": [" +\r
655                 "         {" +\r
656                 "            \"request\": {" +\r
657                 "               \"requestId\": \"rq1234d1-5a33-55df-13ab-12abad84e333\"," +\r
658                 "               \"startTime\": \"Thu, 04 Jun 2009 02:51:59 GMT\"," +\r
659                 "               \"finishTime\": \"Thu, 04 Jun 2009 02:55:59 GMT\"," +\r
660                 "               \"instanceReferences\": {" +\r
661                 "                  \"serviceInstanceId\": \"bc305d54-75b4-431b-adb2-eb6b9e546014\"" +\r
662                 "               }," +\r
663                 "               \"requestScope\": \"service\"," +\r
664                 "               \"requestType\": \"createInstance\"," +\r
665                 "               \"requestDetails\": {" +\r
666                 "                  \"modelInfo\": {" +\r
667                 "                     \"modelType\": \"service\"," +\r
668                 "                     \"modelId\": \"sn5256d1-5a33-55df-13ab-12abad84e764\"," +\r
669                 "                     \"modelNameVersionId\": \"ab6478e4-ea33-3346-ac12-ab121484a333\"," +\r
670                 "                     \"modelName\": \"WanBonding\"," +\r
671                 "                     \"modelVersion\": \"1\"" +\r
672                 "                  }," +\r
673                 "                  \"subscriberInfo\": {" +\r
674                 "                      \"globalSubscriberId\": \"C12345\"," +\r
675                 "                      \"subscriberName\": \"General Electric Division 12\"" +\r
676                 "                  }," +\r
677                 "                  \"requestParameters\": {" +\r
678                 "                     \"vpnId\": \"1a2b3c4d5e6f\"," +\r
679                 "                     \"productName\": \"Trinity\"," +\r
680                 "                     \"customerId\": \"icore9883749\"" +\r
681                 "                  }" +\r
682                 "               }," +\r
683                 "               \"requestStatus\": {" +\r
684                 "                  \"timestamp\": \"Thu, 04 Jun 2009 02:54:49 GMT\"," +\r
685                 "                  \"requestState\": \"complete\"," +\r
686                 "                  \"statusMessage\": \"Resource Created\"," +\r
687                 "                  \"percentProgress\": \"100\"" +\r
688                 "               }" +\r
689                 "            }" +\r
690                 "         }," +\r
691                 "         {" +\r
692                 "            \"request\": {" +\r
693                 "               \"requestId\": \"rq1234d1-5a33-55df-13ab-12abad84e334\"," +\r
694                 "               \"startTime\": \"Thu, 04 Jun 2009 03:52:59 GMT\"," +\r
695                 "               \"instanceReferences\": {" +\r
696                 "                  \"serviceInstanceId\": \"bc305d54-75b4-431b-adb2-eb6b9e546014\"" +\r
697                 "               }," +\r
698                 "               \"requestScope\": \"service\"," +\r
699                 "               \"requestType\": \"updateInstance\"," +\r
700                 "               \"requestDetails\": {" +\r
701                 "                  \"modelInfo\": {" +\r
702                 "                     \"modelType\": \"service\"," +\r
703                 "                     \"modelId\": \"sn5256d1-5a33-55df-13ab-12abad84e764\"," +\r
704                 "                     \"modelNameVersionId\": \"ab6478e4-ea33-3346-ac12-ab121484a333\"," +\r
705                 "                     \"modelName\": \"WanBonding\"," +\r
706                 "                     \"modelVersion\": \"1\"" +\r
707                 "                  }," +\r
708                 "                  \"subscriberInfo\": {" +\r
709                 "                      \"globalSubscriberId\": \"C12345\"," +\r
710                 "                      \"subscriberName\": \"General Electric Division 12\"" +\r
711                 "                  }," +\r
712                 "                  \"requestParameters\": {" +\r
713                 "                     \"vpnId\": \"1a2b3c4d5e70\"," +\r
714                 "                     \"productName\": \"Trinity\"," +\r
715                 "                     \"customerId\": \"icore9883749\"" +\r
716                 "                  }" +\r
717                 "               }," +\r
718                 "               \"requestStatus\": {" +\r
719                 "                  \"timestamp\": \"Thu, 04 Jun 2009 03:53:39 GMT\"," +\r
720                 "                  \"requestState\": \"InProgress\"," +\r
721                 "                  \"statusMessage\": \"vLan setup complete\"," +\r
722                 "                  \"percentProgress\": \"50\"" +\r
723                 "               }" +\r
724                 "            }" +\r
725                 "         }" +\r
726                 "      ]" +\r
727                 "   }" +\r
728                 "}";\r
729 }\r