blob: c46a5679ab0ac00a9e651adc158363518700b4d8 [file] [log] [blame]
Ofir Sonsino1cfb0872018-01-31 17:19:00 +02001VID Simulator
2************************************************************************************
3
4
5************************************************************************************
6Motivation:
7************************************************************************************
8Allow intuitive and extensible framework for mocking REST calls towards VID external peers,
9both for dev and testing purposes.
10
11
12
13************************************************************************************
14Technologies:
15************************************************************************************
16Spring MVC
17MockServer (Apache License 2.0)
18http://www.mock-server.com
19
20
21
22************************************************************************************
23High-level description:
24************************************************************************************
25
26The Simulator uses MockServer instance running "under the hood" listening to its own HTTP port.
27the Simulator allows to register the expected request and response to the MockServer instance
28with an exposed REST call (see details below), and all other requests are automatically redirected to MockServer.
29If a request was properly registered, the MockServer will reply with an expected response, which will be in turn
30returned by the Simulator to the caller.
31
32The Simulator supports both dynamic and preset (static) registration, looking for JSON files in correct registration format and
33registrating them on startup - see details below under "Preset registration"
34
35Note that the behaviour is generic, and no additional code is expected to be added when there are new
36MSO/AAI/any other component APIs to be mocked. They will just need to be properly registered using the existing API.
37
38
39Simulator can be used in both test and dev modes. You can change the server root of any of VID external REST peers
40to the one of the simulator (see details in "Usage"), and either register the expected request/response dynamically or preset it
41to be loaded during startup. That's it - you're ready to use the simulator either in dev mode, or in test mode by running integration tests vs VID.
42
43
44***********************************************************************************
45Simulator configuration:
46************************************************************************************
47
48Under src/main/resources/:
49
501) simulator.properties - currently allows to configure the connection details of MockServer, preset registration mode, and other simulator-related props.
51
522) mockserver.properties - TBD (MockServer logging, SSL etc.)
53
54
55************************************************************************************
56Preset registration:
57************************************************************************************
58
59If enabled in the properties, the Simulator will also run preset registration, looking for JSON files in correct registration format and
60registrating them on startup.
61
62The files must be placed under src/main/resources/preset_registration.
63
64If preset registration is enabled, the simulator will run the scheduler "schedulerDetails" API registration, and any other JSON file which it will find under the folder.
65
66
67get_scheduler_details_short.json:
68
69{
70 "simulatorRequest": {
71 "method": "GET",
72 "path": "/scheduler/v1/ChangeManagement/schedules/scheduleDetails"
73 } ,
74 "simulatorResponse": {
75 "responseCode": 200,
76 "body": "[{\"vnfName\":\"ZRDM1MMSC04c53a\",\"status\":\"Pending Schedule\",\"groupId\":\"\",\"policyId\":\"SNIRO.Config_MS_Demo_TimeLimitAndVerticalTopology_zone\",\"scheduleRequest\":{\"id\":1,\"createDateTime\":\"2017-09-06T13:29:43Z\",\"optimizerDateTime\":\"2017-09-06T13:29:55Z\",\"optimizerMessage\":\"\\n{\\n \\\"requestError\\\": {\\n \\\"serviceException\\\": {\\n \\\"messageId\\\": \\\"SVC0001\\\",\\n \\\"requestId\\\": \\\"CM-c098bd33-a51e-461b-8fd2-6c4d2666c706\\\",\\n \\\"text\\\": \\\"sniro.operation.exceptions.PolicyNotFoundException: Cannot fetch policy SNIRO.Config_MS_Demo_TimeLimitAndVerticalTopology_zone: : HTTPSConnectionPool(host='policypdp-conexus-ist.ecomp.cci.att.com', port=8081): Max retries exceeded with url: \/pdp\/getConfig (Caused by ConnectTimeoutError(<urllib3.connection.VerifiedHTTPSConnection object at 0x7f0ecc00d6d8>, 'Connection to policypdp-conexus-ist.ecomp.cci.att.com timed out. (connect timeout=6.5)'))\\\",\\n \\\"variables\\\": [\\\"severity\\\", 400]\\n }\\n }\\n}\",\"optimizerStatus\":\"HTTP Status: 400\",\"optimizerAttemptsToSchedule\":1,\"optimizerTransactionId\":\"08fb4c32-ecb4-4d72-b618-a6156d3fc53a\",\"scheduleId\":\"08fb4c32-ecb4-4d72-b618-a6156d3fc53a\",\"scheduleName\":\"08fb4c32-ecb4-4d72-b618-a6156d3fc53a\",\"status\":\"Schedule Failed\",\"userId\":\"su7376\",\"domain\":\"ChangeManagement\",\"domainData\":[{\"id\":1,\"name\":\"CallbackData\",\"value\":\"{\\\"requestDetails\\\": [{\\\"vnfInstanceId\\\": \\\"Test\\\", \\\"relatedInstanceList\\\": [{\\\"relatedInstance\\\": {\\\"instanceId\\\": \\\"{serviceInstanceId}\\\", \\\"modelInfo\\\": {\\\"modelName\\\": \\\"{parent service model name}\\\", \\\"modelVersion\\\": \\\"2.0\\\", \\\"modelType\\\": \\\"service\\\", \\\"modelInvariantId\\\": \\\"ff3514e3-5a33-55df-13ab-12abad84e7ff\\\", \\\"modelCustomizationName\\\": \\\"vSAMP12 1\\\", \\\"modelVersionId\\\": \\\"9ebb1521-2e74-47a4-aac7-e71a79f73a79\\\", \\\"modelCustomizationId\\\": \\\"c539433a-84a6-4082-a12e-5c9b00c3b960\\\"}}}], \\\"requestParameters\\\": {\\\"usePreload\\\": \\\"True\\\"}, \\\"requestInfo\\\": {\\\"source\\\": \\\"VID\\\", \\\"requestorId\\\": \\\"az2016\\\", \\\"suppressRollback\\\": \\\"False\\\"}, \\\"vnfName\\\": \\\"Name\\\", \\\"modelInfo\\\": {\\\"modelName\\\": \\\"vSAMP12\\\", \\\"modelVersion\\\": \\\"2.0\\\", \\\"modelType\\\": \\\"vnf\\\", \\\"modelInvariantId\\\": \\\"ff5256d1-5a33-55df-13ab-12abad84e7ff\\\", \\\"modelCustomizationName\\\": \\\"vSAMP12 1\\\", \\\"modelVersionId\\\": \\\"254583ad-b38c-498b-bdbd-b8de5e07541b\\\", \\\"modelCustomizationId\\\": \\\"c539433a-84a6-4082-a12e-5c9b00c3b960\\\"}, \\\"cloudConfiguration\\\": {\\\"lcpCloudRegionId\\\": \\\"mdt1\\\", \\\"tenantId\\\": \\\"88a6ca3ee0394ade9403f075db23167e\\\"}}]}\"},{\"id\":2,\"name\":\"WorkflowName\",\"value\":\"Build Software Upgrade for vNFs\"},{\"id\":3,\"name\":\"CallbackUrl\",\"value\":\"http:\/\/127.0.0.1:8989\/scheduler\/v1\/loopbacktest\/vid\"}],\"scheduleApprovals\":[]},\"schedulesId\":0}]"
77 }
78}
79
80
81************************************************************************************
82Dynamic registration:
83*************************************************************************************
84If you need dynamic registration, register API for dynamic registration:
85
86POST {protocol}://{Tomcat host}:{Tomcat port}/vidSimulator/registerToVidSimulator
87
88To unregister and clear *all* expectations, use DELETE action:
89
90DELETE {protocol}://{Tomcat host}:{Tomcat port}/vidSimulator/registerToVidSimulator
91
92
93***********************************************************************************
94Registration body JSON specification (see and copy/paste examples below):
95***************************************************************************************
96
97
98 "simulatorRequest" - request wrapper.
99
100 Note that from the below fields, it's mandatory to populate at least one.
101 No field is mandatory by itself.
102
103 "id" - String, will be expected as a value in an X-header with a key "x-simulator-id"
104 "method" - String, HTTP method of the request.
105 "path" - String, relative path of the request, MUST be WITH leading slash and WITHOUT trailing slash.
106 "queryParams" - Map<String, List<String>>, query params of key-->list of values.
107 "body" - String, body of the request in case of POST/PUT.
108 Note that JSON String should be properly escaped.
109
110 "simulatorResponse" - response wrapper.
111
112 Note that from the below fields, it's mandatory to populate at least "responseCode".
113
114 "responseCode" - integer, HTTP response code.
115 "responseHeaders" - Dictionary Object with HTTP headers and values.
116 "body" - String, body of the response.
117 Note that JSON String should be properly escaped.
118 "file" - String, a filename of the file sitting in "vid-ext-services-simulator\src\main\resources\download_files"
119 Used for simulating file download requests.
120
121 "misc" - optional configurations.
122 "numberOfTimes" - Integer. Limit this expectation to fire only a
123 given amount of times. Values like -1 or less are
124 treated as "unlimited". Default is unlimited.
125 "replace" - Boolean. If there is already a registered expectation with
126 same simulatorRequest, remove the old registered expectation.
127 If set to 'False' -- the result will be appended to fire
128 after the old registered expectation(s) will fulfill their
129 numberOfTimes. Default is 'True'.
130
131************************************************************************************
132Usage:
133************************************************************************************
134
1351) In system.properties, change the API you want to mock - set server root to be
136{protocol}://{Tomcat host}:{Tomcat port}/vidSimulator (for example http://localhost:7080/vidSimulator)
137
138Example of mocking the scheduler:
139
Ofir Sonsino1cfb0872018-01-31 17:19:00 +0200140scheduler.server.url=http://localhost:7080/vidSimulator/scheduler
141
142
1432) Check the simulator.properties file under /resources to verify the desired properties of the inner MockServer instance.
144 * Default MockServer URI is http://localhost:1080
145
1463) Build VID and VID Simulator WARs
147
1484) Deploy the Simulator WAR under Tomcat, either same as VID or another instance.
149 * Application context path of the Simulator is /vidSimulator
150
151
152
153********************************************************************************
154Some more examples of usage with demo requests/responses:
155********************************************************************************
156
157
158********************************************************************************
1591) Getting a response by "id" (method and path are insignificant in this case)
160
161********************************************************************************
162Registration:
163-----------------
164
165 Request:
166
167 POST /vidSimulator/registerToVidSimulator HTTP/1.1
168 Host: localhost:7080
169 Content-Type: application/json
170 Cache-Control: no-cache
171 {
172 "simulatorRequest": {
173 "id": "pavelId"
174 } ,
175 "simulatorResponse": {
176 "responseCode": 200,
177 "responseHeaders": {
178 "Content-Type": "application/json"
179 },
180 "body": "{\"value1\": \"kuku\",\"value2\": \"shmuku\"}"
181 }
182 }
183
184
185 Response:
186
187 200 OK
188 Registration successful!
189
190
191Running:
192--------
193
194
195 Request:
196
197 GET /vidSimulator/scheduler/testApi HTTP/1.1
198 Host: localhost:7080
199 Content-Type: application/json
200 X-Simulator-Id: pavelId
201 Cache-Control: no-cache
202
203 Response:
204
205 200 OK
206 {
207 "value1": "kuku",
208 "value2": "shmuku"
209 }
210
211
212********************************************************************************
2132) Getting a response by "id", "method" and "path" - sunny and rainy flows
214********************************************************************************
215Registration:
216-------------
217
218 Request:
219
220 POST /vidSimulator/registerToVidSimulator HTTP/1.1
221 Host: localhost:7080
222 Content-Type: application/json
223 Cache-Control: no-cache
224
225 {
226 "simulatorRequest": {
227 "id": "pavelIdGet",
228 "method": "GET",
229 "path": "/scheduler/testApiGet"
230 } ,
231 "simulatorResponse": {
232 "responseCode": 200,
233 "responseHeaders": {
234 "Content-Type": "application/json"
235 },
236 "body": "{\"value1\": \"kukuResponse\",\"value2\": \"shmukuResponse\"}"
237 }
238 }
239
240
241 Response:
242
243 200 OK
244 Registration successful!
245
246
247Running - sunny flow:
248---------------------
249
250
251 Request:
252
253 GET /vidSimulator/scheduler/testApiGet HTTP/1.1
254 Host: localhost:7080
255 Content-Type: application/json
Joanna Jeremicz9c2c7e82018-08-21 13:29:02 +0200256 X-Simulator-Id: pavelIdGet
Ofir Sonsino1cfb0872018-01-31 17:19:00 +0200257 Cache-Control: no-cache
258
259 Response:
260
261 200 OK
262 {
263 "value1": "kukuResponse",
264 "value2": "shmukuResponse"
265 }
266
267
268Running POST - will return 404 since GET method was explicitly registered:
269--------------------------------------------------------------------------
270
271 Request:
272
273 POST /vidSimulator/scheduler/testApiGet HTTP/1.1
274 Host: localhost:7080
275 Content-Type: application/json
276 X-Simulator-Id: pavelIdGet
277 Cache-Control: no-cache
278 {
279 "id": "pavelId",
280 "responseCode": 200,
281 "body": {
282 "value1": "kuku",
283 "value2": "shmuku"
284 }
285 }
286
287 Response:
288
289 404 Not Found
290
291
292********************************************************************************
2933) Getting an error HTTP response (based on "id" in this example)
294********************************************************************************
295
296Registration:
297-------------
298
299 Request:
300
301 POST /vidSimulator/registerToVidSimulator HTTP/1.1
302 Host: localhost:7080
303 Content-Type: application/json
304 Cache-Control: no-cache
305
306 {
307 "simulatorRequest": {
308 "id": "pavelIdError"
309 } ,
310 "simulatorResponse": {
311 "responseCode": 417
312 }
313 }
314
315 Response:
316
317 200 OK
318 Registration successful!
319
320Running:
321-----------
322
323 Request:
324
325 GET /vidSimulator/scheduler/anyApi HTTP/1.1
326 Host: localhost:7080
327 Content-Type: application/json
328 X-Simulator-Id: pavelIdError
329 Cache-Control: no-cache
330
331
332 Response:
333
334 417 Expectation Failed.
335
336
337********************************************************************************
3384) Query params
339********************************************************************************
340
341Registration:
342-------------
343
344 Request:
345
346 POST /vidSimulator/registerToVidSimulator HTTP/1.1
347 Host: localhost:7080
348 Content-Type: application/json
349 Cache-Control: no-cache
350 Postman-Token: 0bbfeb0f-b8b6-368e-6fbd-38a90fc544b4
351
352 {
353 "simulatorRequest": {
354 "method": "GET",
355 "path": "/cloudResourcesRequests/v1",
356 "queryParams": {
357 "requestId" : ["3212b08c-0dcd-4d20-8c84-51e4f325c14a", "3212b08c-0dcd-4d20-8c84-51e4f325c14b"]
358 }
359 } ,
360 "simulatorResponse": {
361 "responseCode": 200,
362 "body": "{\"requestId1\": \"3212b08c-0dcd-4d20-8c84-51e4f325c14a\",\"requestId2\": \"3212b08c-0dcd-4d20-8c84-51e4f325c14b\"}"
363 }
364 }
365
366 Response:
367
368 200 OK
369 Registration successful!
370
371Running:
372-----------
373
374 Request:
375
376 GET /vidSimulator/cloudResourcesRequests/v1?requestId=3212b08c-0dcd-4d20-8c84-51e4f325c14b&amp;requestId=3212b08c-0dcd-4d20-8c84-51e4f325c14a HTTP/1.1
377 Host: 127.0.0.1:7080
378 Accept: application/json
379 Cache-Control: no-cache
380 Postman-Token: 9ef5d9d2-77f4-7631-7e9f-4404df10acb6
381
382
383 Response:
384
385 200 OK
386 {"requestId1": "3212b08c-0dcd-4d20-8c84-51e4f325c14a","requestId2": "3212b08c-0dcd-4d20-8c84-51e4f325c14b"}
387
388
389
390********************************************************************************
3915) File Download
392********************************************************************************
393
394Registration:
395-------------
396
397 Request:
398
399 POST /vidSimulator/registerToVidSimulator HTTP/1.1
400 Host: localhost:7080
401 Content-Type: application/json
402 Cache-Control: no-cache
403 Postman-Token: 0bbfeb0f-b8b6-368e-6fbd-38a90fc544b4
404
405 {
406 "simulatorRequest": {
407 "method": "GET",
408 "path": "/vidSimulator/getSomeFile"
409 } ,
410 "simulatorResponse": {
411 "responseCode": 200,
412 "file": "csar3933948645405128424.zip"
413 }
414 }
415
416 Response:
417
418 200 OK
419 Registration successful!
420
421Running:
422-----------
423
424 Request:
425
426 GET /vidSimulator/getSomeFile HTTP/1.1
427 Host: 127.0.0.1:7080
428 Cache-Control: no-cache
429 Postman-Token: 9ef5d9d2-77f4-7631-7e9f-4404df10acb6
430
431
432 Response:
433
434 200 OK
435 File for download.