blob: 033210309fcb487cabe210d62443157788de6418 [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
140#scheduler.server.url=http://mtanjv9sdlg10.aic.cip.att.com:8989/scheduler
141scheduler.server.url=http://localhost:7080/vidSimulator/scheduler
142
143
1442) Check the simulator.properties file under /resources to verify the desired properties of the inner MockServer instance.
145 * Default MockServer URI is http://localhost:1080
146
1473) Build VID and VID Simulator WARs
148
1494) Deploy the Simulator WAR under Tomcat, either same as VID or another instance.
150 * Application context path of the Simulator is /vidSimulator
151
152
153
154********************************************************************************
155Some more examples of usage with demo requests/responses:
156********************************************************************************
157
158
159********************************************************************************
1601) Getting a response by "id" (method and path are insignificant in this case)
161
162********************************************************************************
163Registration:
164-----------------
165
166 Request:
167
168 POST /vidSimulator/registerToVidSimulator HTTP/1.1
169 Host: localhost:7080
170 Content-Type: application/json
171 Cache-Control: no-cache
172 {
173 "simulatorRequest": {
174 "id": "pavelId"
175 } ,
176 "simulatorResponse": {
177 "responseCode": 200,
178 "responseHeaders": {
179 "Content-Type": "application/json"
180 },
181 "body": "{\"value1\": \"kuku\",\"value2\": \"shmuku\"}"
182 }
183 }
184
185
186 Response:
187
188 200 OK
189 Registration successful!
190
191
192Running:
193--------
194
195
196 Request:
197
198 GET /vidSimulator/scheduler/testApi HTTP/1.1
199 Host: localhost:7080
200 Content-Type: application/json
201 X-Simulator-Id: pavelId
202 Cache-Control: no-cache
203
204 Response:
205
206 200 OK
207 {
208 "value1": "kuku",
209 "value2": "shmuku"
210 }
211
212
213********************************************************************************
2142) Getting a response by "id", "method" and "path" - sunny and rainy flows
215********************************************************************************
216Registration:
217-------------
218
219 Request:
220
221 POST /vidSimulator/registerToVidSimulator HTTP/1.1
222 Host: localhost:7080
223 Content-Type: application/json
224 Cache-Control: no-cache
225
226 {
227 "simulatorRequest": {
228 "id": "pavelIdGet",
229 "method": "GET",
230 "path": "/scheduler/testApiGet"
231 } ,
232 "simulatorResponse": {
233 "responseCode": 200,
234 "responseHeaders": {
235 "Content-Type": "application/json"
236 },
237 "body": "{\"value1\": \"kukuResponse\",\"value2\": \"shmukuResponse\"}"
238 }
239 }
240
241
242 Response:
243
244 200 OK
245 Registration successful!
246
247
248Running - sunny flow:
249---------------------
250
251
252 Request:
253
254 GET /vidSimulator/scheduler/testApiGet HTTP/1.1
255 Host: localhost:7080
256 Content-Type: application/json
Joanna Jeremicz9c2c7e82018-08-21 13:29:02 +0200257 X-Simulator-Id: pavelIdGet
Ofir Sonsino1cfb0872018-01-31 17:19:00 +0200258 Cache-Control: no-cache
259
260 Response:
261
262 200 OK
263 {
264 "value1": "kukuResponse",
265 "value2": "shmukuResponse"
266 }
267
268
269Running POST - will return 404 since GET method was explicitly registered:
270--------------------------------------------------------------------------
271
272 Request:
273
274 POST /vidSimulator/scheduler/testApiGet HTTP/1.1
275 Host: localhost:7080
276 Content-Type: application/json
277 X-Simulator-Id: pavelIdGet
278 Cache-Control: no-cache
279 {
280 "id": "pavelId",
281 "responseCode": 200,
282 "body": {
283 "value1": "kuku",
284 "value2": "shmuku"
285 }
286 }
287
288 Response:
289
290 404 Not Found
291
292
293********************************************************************************
2943) Getting an error HTTP response (based on "id" in this example)
295********************************************************************************
296
297Registration:
298-------------
299
300 Request:
301
302 POST /vidSimulator/registerToVidSimulator HTTP/1.1
303 Host: localhost:7080
304 Content-Type: application/json
305 Cache-Control: no-cache
306
307 {
308 "simulatorRequest": {
309 "id": "pavelIdError"
310 } ,
311 "simulatorResponse": {
312 "responseCode": 417
313 }
314 }
315
316 Response:
317
318 200 OK
319 Registration successful!
320
321Running:
322-----------
323
324 Request:
325
326 GET /vidSimulator/scheduler/anyApi HTTP/1.1
327 Host: localhost:7080
328 Content-Type: application/json
329 X-Simulator-Id: pavelIdError
330 Cache-Control: no-cache
331
332
333 Response:
334
335 417 Expectation Failed.
336
337
338********************************************************************************
3394) Query params
340********************************************************************************
341
342Registration:
343-------------
344
345 Request:
346
347 POST /vidSimulator/registerToVidSimulator HTTP/1.1
348 Host: localhost:7080
349 Content-Type: application/json
350 Cache-Control: no-cache
351 Postman-Token: 0bbfeb0f-b8b6-368e-6fbd-38a90fc544b4
352
353 {
354 "simulatorRequest": {
355 "method": "GET",
356 "path": "/cloudResourcesRequests/v1",
357 "queryParams": {
358 "requestId" : ["3212b08c-0dcd-4d20-8c84-51e4f325c14a", "3212b08c-0dcd-4d20-8c84-51e4f325c14b"]
359 }
360 } ,
361 "simulatorResponse": {
362 "responseCode": 200,
363 "body": "{\"requestId1\": \"3212b08c-0dcd-4d20-8c84-51e4f325c14a\",\"requestId2\": \"3212b08c-0dcd-4d20-8c84-51e4f325c14b\"}"
364 }
365 }
366
367 Response:
368
369 200 OK
370 Registration successful!
371
372Running:
373-----------
374
375 Request:
376
377 GET /vidSimulator/cloudResourcesRequests/v1?requestId=3212b08c-0dcd-4d20-8c84-51e4f325c14b&amp;requestId=3212b08c-0dcd-4d20-8c84-51e4f325c14a HTTP/1.1
378 Host: 127.0.0.1:7080
379 Accept: application/json
380 Cache-Control: no-cache
381 Postman-Token: 9ef5d9d2-77f4-7631-7e9f-4404df10acb6
382
383
384 Response:
385
386 200 OK
387 {"requestId1": "3212b08c-0dcd-4d20-8c84-51e4f325c14a","requestId2": "3212b08c-0dcd-4d20-8c84-51e4f325c14b"}
388
389
390
391********************************************************************************
3925) File Download
393********************************************************************************
394
395Registration:
396-------------
397
398 Request:
399
400 POST /vidSimulator/registerToVidSimulator HTTP/1.1
401 Host: localhost:7080
402 Content-Type: application/json
403 Cache-Control: no-cache
404 Postman-Token: 0bbfeb0f-b8b6-368e-6fbd-38a90fc544b4
405
406 {
407 "simulatorRequest": {
408 "method": "GET",
409 "path": "/vidSimulator/getSomeFile"
410 } ,
411 "simulatorResponse": {
412 "responseCode": 200,
413 "file": "csar3933948645405128424.zip"
414 }
415 }
416
417 Response:
418
419 200 OK
420 Registration successful!
421
422Running:
423-----------
424
425 Request:
426
427 GET /vidSimulator/getSomeFile HTTP/1.1
428 Host: 127.0.0.1:7080
429 Cache-Control: no-cache
430 Postman-Token: 9ef5d9d2-77f4-7631-7e9f-4404df10acb6
431
432
433 Response:
434
435 200 OK
436 File for download.