fix bug for ETSI Catalog Manager needs to raise 303 exception for the same callback_u...
[modeling/etsicatalog.git] / catalog / packages / tests / test_nsdm_subscription.py
1 # Copyright (C) 2019 Verizon. All Rights Reserved
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import json
16 import mock
17 import uuid
18 import os
19 from django.test import TestCase
20 from rest_framework.test import APIClient
21 from rest_framework import status
22 from requests.auth import HTTPBasicAuth
23
24 from catalog.packages.biz.nsdm_subscription import NsdmSubscription
25 from catalog.pub.database.models import NsdmSubscriptionModel
26 from catalog.packages.biz.notificationsutil import NsdNotifications, PnfNotifications
27 from catalog.packages import const
28 from catalog.pub.config import config as pub_config
29 import catalog.pub.utils.timeutil
30 from catalog.packages.tests.const import nsd_data
31 from catalog.pub.database.models import NSPackageModel, VnfPackageModel, PnfPackageModel
32 from catalog.pub.config.config import CATALOG_ROOT_PATH, MSB_SERVICE_IP, MSB_SERVICE_PORT
33 from catalog.pub.utils import toscaparser
34
35
36 class TestNsdmSubscription(TestCase):
37     def setUp(self):
38         self.client = APIClient()
39         NsdmSubscriptionModel.objects.all().delete()
40         self.subscription_id = str(uuid.uuid4())
41         self.subscription = {
42             "callbackUri": "http://callbackuri.com",
43             "authentication": {
44                 "authType": ["BASIC"],
45                 "paramsBasic": {
46                     "userName": "username",
47                     "password": "password"
48                 }
49             },
50             "filter": {
51                 "nsdId": ["b632bddc-abcd-4180-bd8d-4e8a9578eff7"],
52             }
53         }
54         self.links = {
55             "self": {
56                 "href": "/api/v1/subscriptions/" + self.subscription_id
57             }
58         }
59         self.test_subscription = {
60             "callbackUri": "http://callbackuri.com",
61             "id": self.subscription_id,
62             "filter": {
63                 "notificationTypes": [
64                     "NsdOnBoardingNotification"
65                 ],
66                 "nsdInfoId": [],
67                 "nsdId": [],
68                 "nsdName": [],
69                 "nsdVersion": [],
70                 "nsdInvariantId": [],
71                 "vnfPkgIds": [],
72                 "nestedNsdInfoIds": [],
73                 "nsdOnboardingState": [],
74                 "nsdOperationalState": [],
75                 "nsdUsageState": [],
76                 "pnfdInfoIds": [],
77                 "pnfdId": [],
78                 "pnfdName": [],
79                 "pnfdVersion": [],
80                 "pnfdProvider": [],
81                 "pnfdInvariantId": [],
82                 "pnfdOnboardingState": [],
83                 "pnfdUsageState": []
84             },
85             "_links": self.links,
86         }
87
88     def tearDown(self):
89         pass
90
91     @mock.patch("requests.get")
92     @mock.patch.object(uuid, 'uuid4')
93     def test_nsdm_subscribe_notification(self, mock_uuid4, mock_requests):
94         temp_uuid = str(uuid.uuid4())
95         mock_requests.return_value.status_code = 204
96         mock_requests.get.return_value.status_code = 204
97         mock_uuid4.return_value = temp_uuid
98         response = self.client.post("/api/nsd/v1/subscriptions",
99                                     data=self.subscription, format='json')
100         self.assertEqual(201, response.status_code)
101         self.assertEqual(self.subscription["callbackUri"],
102                          response.data["callbackUri"])
103         self.assertEqual(temp_uuid, response.data["id"])
104
105     @mock.patch("requests.get")
106     @mock.patch.object(uuid, 'uuid4')
107     def test_nsdm_subscribe_callbackFailure(self, mock_uuid4, mock_requests):
108         temp_uuid = str(uuid.uuid4())
109         mock_requests.return_value.status_code = 500
110         mock_requests.get.return_value.status_code = 500
111         mock_uuid4.return_value = temp_uuid
112         expected_data = {
113             'status': 500,
114             'detail': "callbackUri http://callbackuri.com didn't"
115                       " return 204 statuscode."
116         }
117         response = self.client.post("/api/nsd/v1/subscriptions",
118                                     data=self.subscription, format='json')
119         self.assertEqual(500, response.status_code)
120         self.assertEqual(expected_data, response.data)
121
122     @mock.patch("requests.get")
123     def test_nsdm_second_subscription(self, mock_requests):
124         mock_requests.return_value.status_code = 204
125         mock_requests.get.return_value.status_code = 204
126         response = self.client.post("/api/nsd/v1/subscriptions",
127                                     data=self.subscription, format='json')
128         self.assertEqual(201, response.status_code)
129         self.assertEqual(self.subscription["callbackUri"],
130                          response.data["callbackUri"])
131         dummy_subscription = {
132             "callbackUri": "http://callbackuri.com",
133             "authentication": {
134                 "authType": ["BASIC"],
135                 "paramsBasic": {
136                     "userName": "username",
137                     "password": "password"
138                 }
139             },
140             "filter": {
141                 "nsdId": ["b632bddc-bccd-4180-bd8d-4e8a9578eff7"],
142             }
143         }
144         response = self.client.post("/api/nsd/v1/subscriptions",
145                                     data=dummy_subscription, format='json')
146         self.assertEqual(201, response.status_code)
147         self.assertEqual(dummy_subscription["callbackUri"],
148                          response.data["callbackUri"])
149
150     @mock.patch("requests.get")
151     def test_nsdm_duplicate_filter_or_callbackuri_subscription(self, mock_requests):
152         mock_requests.return_value.status_code = 204
153         mock_requests.get.return_value.status_code = 204
154         response = self.client.post("/api/nsd/v1/subscriptions",
155                                     data=self.subscription, format='json')
156         self.assertEqual(201, response.status_code)
157         self.assertEqual(self.subscription["callbackUri"],
158                          response.data["callbackUri"])
159         newsub1 = self.subscription
160         newsub1["callbackUri"] = "http://newcallbackuri.com"
161         response = self.client.post("/api/nsd/v1/subscriptions",
162                                     data=newsub1, format='json')
163         self.assertEqual(201, response.status_code)
164         newsub2 = self.subscription
165         newsub2["filter"]["nsdName"] = ["aaa"]
166         response = self.client.post("/api/nsd/v1/subscriptions",
167                                     data=newsub2, format='json')
168         self.assertEqual(201, response.status_code)
169
170     @mock.patch("requests.get")
171     def test_nsdm_duplicate_callbackuri_filter_subscription(self, mock_requests):
172         mock_requests.return_value.status_code = 204
173         mock_requests.get.return_value.status_code = 204
174         response = self.client.post("/api/nsd/v1/subscriptions",
175                                     data=self.subscription, format='json')
176         self.assertEqual(201, response.status_code)
177         self.assertEqual(self.subscription["callbackUri"],
178                          response.data["callbackUri"])
179         subscriptionid = response.data["id"]
180         response = self.client.post("/api/nsd/v1/subscriptions",
181                                     data=self.subscription, format='json')
182         self.assertEqual(303, response.status_code)
183         redirect_addr = "https://%s:%s/%s" % (MSB_SERVICE_IP, MSB_SERVICE_PORT,
184                                               os.path.join(const.NSDM_SUBSCRIPTION_ROOT_URI, subscriptionid))
185         self.assertEqual(redirect_addr, response["Location"])
186
187     @mock.patch("requests.get")
188     def test_nsdm_bad_request(self, mock_requests):
189         dummy_subscription = {
190             "callbackUri": "http://callbackuri.com",
191             "authentication": {
192                 "authType": ["BASIC"],
193                 "paramsBasic": {
194                     "userName": "username",
195                     "password": "password"
196                 }
197             },
198             "filter": {
199                 "nsdId": "b632bddc-bccd-4180-bd8d-4e8a9578eff7",
200             }
201         }
202         response = self.client.post("/api/nsd/v1/subscriptions",
203                                     data=dummy_subscription, format='json')
204         self.assertEqual(400, response.status_code)
205
206     @mock.patch("requests.get")
207     def test_nsdm_invalid_authtype_subscription(self, mock_requests):
208         dummy_subscription = {
209             "callbackUri": "http://callbackuri.com",
210             "authentication": {
211                 "authType": ["OAUTH2_CLIENT_CREDENTIALS"],
212                 "paramsBasic": {
213                     "userName": "username",
214                     "password": "password"
215                 }
216             }
217         }
218         mock_requests.return_value.status_code = 204
219         mock_requests.get.return_value.status_code = 204
220         expected_data = {
221             'status': 400,
222             'detail': 'Auth type should be BASIC'
223         }
224         response = self.client.post("/api/nsd/v1/subscriptions",
225                                     data=dummy_subscription, format='json')
226         self.assertEqual(400, response.status_code)
227         self.assertEqual(expected_data, response.data)
228
229     @mock.patch("requests.get")
230     def test_nsdm_invalid_authtype_oauthclient_subscription(
231             self, mock_requests):
232         dummy_subscription = {
233             "callbackUri": "http://callbackuri.com",
234             "authentication": {
235                 "authType": ["BASIC"],
236                 "paramsOauth2ClientCredentials": {
237                     "clientId": "clientId",
238                     "clientPassword": "password",
239                     "tokenEndpoint": "http://tokenEndpoint"
240                 }
241             }
242         }
243         mock_requests.return_value.status_code = 204
244         mock_requests.get.return_value.status_code = 204
245         expected_data = {
246             'status': 400,
247             'detail': 'Auth type should be OAUTH2_CLIENT_CREDENTIALS'
248         }
249         response = self.client.post("/api/nsd/v1/subscriptions",
250                                     data=dummy_subscription, format='json')
251         self.assertEqual(400, response.status_code)
252         self.assertEqual(expected_data, response.data)
253
254     @mock.patch("requests.get")
255     def test_nsdm_invalid_authparams_subscription(self, mock_requests):
256         dummy_subscription = {
257             "callbackUri": "http://callbackuri.com",
258             "authentication": {
259                 "authType": ["BASIC"],
260                 "paramsBasic": {
261                     "userName": "username"
262                 }
263             }
264         }
265         mock_requests.return_value.status_code = 204
266         mock_requests.get.return_value.status_code = 204
267         expected_data = {
268             'status': 400,
269             'detail': 'userName and password needed for BASIC'
270         }
271         response = self.client.post("/api/nsd/v1/subscriptions",
272                                     data=dummy_subscription, format='json')
273         self.assertEqual(400, response.status_code)
274         self.assertEqual(expected_data, response.data)
275
276     @mock.patch("requests.get")
277     def test_nsdm_invalid_authparams_oauthclient_subscription(
278             self, mock_requests):
279         dummy_subscription = {
280             "callbackUri": "http://callbackuri.com",
281             "authentication": {
282                 "authType": ["OAUTH2_CLIENT_CREDENTIALS"],
283                 "paramsOauth2ClientCredentials": {
284                     "clientPassword": "password",
285                     "tokenEndpoint": "http://tokenEndpoint"
286                 }
287             }
288         }
289         mock_requests.return_value.status_code = 204
290         mock_requests.get.return_value.status_code = 204
291         expected_data = {
292             'status': 400,
293             'detail': 'clientId, clientPassword and tokenEndpoint'
294                       ' required for OAUTH2_CLIENT_CREDENTIALS'
295         }
296         response = self.client.post("/api/nsd/v1/subscriptions",
297                                     data=dummy_subscription, format='json')
298         self.assertEqual(400, response.status_code)
299         self.assertEqual(expected_data, response.data)
300
301     @mock.patch("requests.get")
302     def test_nsdm_invalid_filter_subscription(self, mock_requests):
303         dummy_subscription = {
304             "callbackUri": "http://callbackuri.com",
305             "authentication": {
306                 "authType": ["BASIC"],
307                 "paramsBasic": {
308                     "userName": "username",
309                     "password": "password"
310                 }
311             },
312             "filter": {
313                 "nsdId": ["b632bddc-bccd-4180-bd8d-4e8a9578eff7"],
314                 "nsdInfoId": ["d0ea5ec3-0b98-438a-9bea-488230cff174"]
315             }
316         }
317         mock_requests.return_value.status_code = 204
318         mock_requests.get.return_value.status_code = 204
319         expected_data = {
320             'status': 400,
321             'detail': 'Notification Filter should contain'
322                       ' either nsdId or nsdInfoId'
323         }
324         response = self.client.post("/api/nsd/v1/subscriptions",
325                                     data=dummy_subscription, format='json')
326         self.assertEqual(400, response.status_code)
327         self.assertEqual(expected_data, response.data)
328
329     @mock.patch("requests.get")
330     def test_nsdm_invalid_filter_pnfd_subscription(self, mock_requests):
331         dummy_subscription = {
332             "callbackUri": "http://callbackuri.com",
333             "authentication": {
334                 "authType": ["BASIC"],
335                 "paramsBasic": {
336                     "userName": "username",
337                     "password": "password"
338                 }
339             },
340             "filter": {
341                 "pnfdId": ["b632bddc-bccd-4180-bd8d-4e8a9578eff7"],
342                 "pnfdInfoIds": ["d0ea5ec3-0b98-438a-9bea-488230cff174"]
343             }
344         }
345         mock_requests.return_value.status_code = 204
346         mock_requests.get.return_value.status_code = 204
347         expected_data = {
348             'status': 400,
349             'detail': 'Notification Filter should contain'
350                       ' either pnfdId or pnfdInfoIds'
351         }
352         response = self.client.post("/api/nsd/v1/subscriptions",
353                                     data=dummy_subscription, format='json')
354         self.assertEqual(400, response.status_code)
355         self.assertEqual(expected_data, response.data)
356
357     @mock.patch.object(NsdmSubscription, 'create')
358     def test_nsdmsubscription_create_when_catch_exception(self, mock_create):
359         mock_create.side_effect = TypeError("Unicode type")
360         response = self.client.post('/api/nsd/v1/subscriptions',
361                                     data=self.subscription, format='json')
362         self.assertEqual(response.status_code,
363                          status.HTTP_500_INTERNAL_SERVER_ERROR)
364
365     def test_nsdm_get_subscriptions(self):
366         NsdmSubscriptionModel(subscriptionid=self.subscription_id,
367                               callback_uri="http://callbackuri.com",
368                               auth_info={},
369                               notificationTypes=json.dumps(
370                                   ["NsdOnBoardingNotification"]),
371                               nsdId=[], nsdVersion=[],
372                               nsdInfoId=[], nsdDesigner=[],
373                               nsdName=[], nsdInvariantId=[],
374                               vnfPkgIds=[], pnfdInfoIds=[],
375                               nestedNsdInfoIds=[], nsdOnboardingState=[],
376                               nsdOperationalState=[], nsdUsageState=[],
377                               pnfdId=[], pnfdVersion=[], pnfdProvider=[],
378                               pnfdName=[], pnfdInvariantId=[],
379                               pnfdOnboardingState=[], pnfdUsageState=[],
380                               links=json.dumps(self.links)).save()
381         response = self.client.get("/api/nsd/v1/subscriptions",
382                                    format='json')
383         self.assertEqual(status.HTTP_200_OK, response.status_code)
384         self.assertEqual([self.test_subscription], response.data)
385
386     def test_nsdm_get_subscriptions_filter(self):
387         NsdmSubscriptionModel(subscriptionid=self.subscription_id,
388                               callback_uri="http://callbackuri.com",
389                               auth_info={},
390                               notificationTypes=json.dumps(
391                                   ["NsdOnBoardingNotification"]),
392                               nsdId=[], nsdVersion=[],
393                               nsdInfoId=[], nsdDesigner=[],
394                               nsdName=[], nsdInvariantId=[],
395                               vnfPkgIds=[], pnfdInfoIds=[],
396                               nestedNsdInfoIds=[], nsdOnboardingState=[],
397                               nsdOperationalState=[], nsdUsageState=[],
398                               pnfdId=[], pnfdVersion=[], pnfdProvider=[],
399                               pnfdName=[], pnfdInvariantId=[],
400                               pnfdOnboardingState=[], pnfdUsageState=[],
401                               links=json.dumps(self.links)).save()
402         response = self.client.get("/api/nsd/v1/subscriptions"
403                                    "?notificationTypes"
404                                    "=NsdOnBoardingNotification",
405                                    format='json')
406         self.assertEqual(status.HTTP_200_OK, response.status_code)
407         self.assertEqual([self.test_subscription], response.data)
408
409     def test_nsdm_get_subscriptions_filter_failure(self):
410         NsdmSubscriptionModel(subscriptionid=self.subscription_id,
411                               callback_uri="http://callbackuri.com",
412                               auth_info={},
413                               notificationTypes=json.dumps(
414                                   ["NsdOnBoardingNotification"]),
415                               nsdId=[], nsdVersion=[],
416                               nsdInfoId=[], nsdDesigner=[],
417                               nsdName=[], nsdInvariantId=[],
418                               vnfPkgIds=[], pnfdInfoIds=[],
419                               nestedNsdInfoIds=[], nsdOnboardingState=[],
420                               nsdOperationalState=[], nsdUsageState=[],
421                               pnfdId=[], pnfdVersion=[], pnfdProvider=[],
422                               pnfdName=[], pnfdInvariantId=[],
423                               pnfdOnboardingState=[], pnfdUsageState=[],
424                               links=json.dumps(self.links)).save()
425         response = self.client.get("/api/nsd/v1/subscriptions"
426                                    "?notificationTypes="
427                                    "PnfdOnBoardingFailureNotification",
428                                    format='json')
429         self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
430
431     def test_nsdm_get_subscriptions_invalid_filter(self):
432         NsdmSubscriptionModel(subscriptionid=self.subscription_id,
433                               callback_uri="http://callbackuri.com",
434                               auth_info={},
435                               notificationTypes=json.dumps(
436                                   ["NsdOnBoardingNotification"]),
437                               nsdId=[], nsdVersion=[],
438                               nsdInfoId=[], nsdDesigner=[],
439                               nsdName=[], nsdInvariantId=[],
440                               vnfPkgIds=[], pnfdInfoIds=[],
441                               nestedNsdInfoIds=[], nsdOnboardingState=[],
442                               nsdOperationalState=[], nsdUsageState=[],
443                               pnfdId=[], pnfdVersion=[], pnfdProvider=[],
444                               pnfdName=[], pnfdInvariantId=[],
445                               pnfdOnboardingState=[], pnfdUsageState=[],
446                               links=json.dumps(self.links)).save()
447         response = self.client.get("/api/nsd/v1/subscriptions"
448                                    "?notificationTypes="
449                                    "PnfdOnBoardingFailureNotificati",
450                                    format='json')
451         self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code)
452
453     @mock.patch.object(NsdmSubscription, 'query_multi_subscriptions')
454     def test_nsdmsubscription_get_when_catch_exception(self, mock_create):
455         mock_create.side_effect = TypeError("Unicode type")
456         response = self.client.get('/api/nsd/v1/subscriptions', format='json')
457         self.assertEqual(response.status_code,
458                          status.HTTP_500_INTERNAL_SERVER_ERROR)
459
460     def test_nsdm_get_subscription(self):
461         NsdmSubscriptionModel(subscriptionid=self.subscription_id,
462                               callback_uri="http://callbackuri.com",
463                               auth_info={},
464                               notificationTypes=json.dumps(
465                                   ["NsdOnBoardingNotification"]),
466                               nsdId=[], nsdVersion=[],
467                               nsdInfoId=[], nsdDesigner=[],
468                               nsdName=[], nsdInvariantId=[],
469                               vnfPkgIds=[], pnfdInfoIds=[],
470                               nestedNsdInfoIds=[], nsdOnboardingState=[],
471                               nsdOperationalState=[], nsdUsageState=[],
472                               pnfdId=[], pnfdVersion=[], pnfdProvider=[],
473                               pnfdName=[], pnfdInvariantId=[],
474                               pnfdOnboardingState=[], pnfdUsageState=[],
475                               links=json.dumps(self.links)).save()
476         response = self.client.get('/api/nsd/v1/'
477                                    'subscriptions/' + self.subscription_id,
478                                    format='json')
479         self.assertEqual(status.HTTP_200_OK, response.status_code)
480         self.assertEqual(self.test_subscription, response.data)
481
482     def test_nsdm_get_subscription_failure(self):
483         expected_data = {
484             "status": 404,
485             "detail": "Subscription(" + self.subscription_id + ") "
486                                                                "doesn't exist"
487         }
488         response = self.client.get('/api/nsd/v1/'
489                                    'subscriptions/' + self.subscription_id,
490                                    format='json')
491         self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
492         self.assertEqual(expected_data, response.data)
493
494     def test_nsdm_get_subscription_failure_bad_request(self):
495         response = self.client.get("/api/nsd/v1/subscriptions/123",
496                                    format='json')
497         self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
498
499     @mock.patch.object(NsdmSubscription, 'query_single_subscription')
500     def test_nsdmsubscription_getsingle_when_catch_exception(
501             self, mock_create):
502         mock_create.side_effect = TypeError("Unicode type")
503         response = self.client.get('/api/nsd/v1/'
504                                    'subscriptions/' + self.subscription_id,
505                                    format='json')
506         self.assertEqual(response.status_code,
507                          status.HTTP_500_INTERNAL_SERVER_ERROR)
508
509     def test_ndsm_delete_subscription(self):
510         NsdmSubscriptionModel(subscriptionid=self.subscription_id,
511                               callback_uri="http://callbackuri.com",
512                               auth_info={},
513                               notificationTypes=json.dumps(
514                                   ["NsdOnBoardingNotification"]),
515                               nsdId=[], nsdVersion=[],
516                               nsdInfoId=[], nsdDesigner=[],
517                               nsdName=[], nsdInvariantId=[],
518                               vnfPkgIds=[], pnfdInfoIds=[],
519                               nestedNsdInfoIds=[], nsdOnboardingState=[],
520                               nsdOperationalState=[], nsdUsageState=[],
521                               pnfdId=[], pnfdVersion=[], pnfdProvider=[],
522                               pnfdName=[], pnfdInvariantId=[],
523                               pnfdOnboardingState=[], pnfdUsageState=[],
524                               links=json.dumps(self.links)).save()
525         response = self.client.delete('/api/nsd/v1/'
526                                       'subscriptions/' + self.subscription_id,
527                                       format='json')
528         self.assertEqual(status.HTTP_204_NO_CONTENT, response.status_code)
529
530     def test_ndsm_delete_subscription_failure(self):
531         response = self.client.delete('/api/nsd/v1/'
532                                       'subscriptions/' + self.subscription_id,
533                                       format='json')
534         self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
535
536     def test_nsdm_delete_subscription_failure_bad_request(self):
537         response = self.client.delete("/api/nsd/v1/subscriptions/123",
538                                       format='json')
539         self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
540
541     @mock.patch.object(NsdmSubscription, 'delete_single_subscription')
542     def test_nsdmsubscription_delete_when_catch_exception(self, mock_create):
543         mock_create.side_effect = TypeError("Unicode type")
544         response = self.client.delete('/api/nsd/v1/'
545                                       'subscriptions/' + self.subscription_id,
546                                       format='json')
547         self.assertEqual(response.status_code,
548                          status.HTTP_500_INTERNAL_SERVER_ERROR)
549
550     @mock.patch("requests.post")
551     @mock.patch.object(toscaparser, 'parse_nsd')
552     @mock.patch.object(catalog.pub.utils.timeutil, "now_time")
553     @mock.patch("requests.get")
554     @mock.patch.object(uuid, 'uuid4')
555     def test_nsdm_subscribe_trigger_notification(self, mock_uuid4, mock_requests, mock_nowtime, mock_parse_nsd,
556                                                  mock_requests_post):
557         mock_requests.return_value.status_code = 204
558         mock_requests.get.return_value.status_code = 204
559         mock_uuid4.return_value = "1111"
560         mock_nowtime.return_value = "nowtime()"
561
562         subscription_req = {
563             "callbackUri": "http://callbackuri.com",
564             "authentication": {
565                 "authType": ["BASIC"],
566                 "paramsBasic": {
567                     "userName": "username",
568                     "password": "password"
569                 }
570             },
571             "filter": {
572                 "nsdId": ["b632bddc-bccd-4180-bd8d-4e8a9578eff7"]
573             }
574         }
575         response = self.client.post("/api/nsd/v1/subscriptions",
576                                     data=subscription_req, format='json')
577         self.assertEqual(201, response.status_code)
578
579         self.user_defined_data = {
580             'key1': 'value1',
581             'key2': 'value2',
582             'key3': 'value3',
583         }
584         user_defined_data_json = json.JSONEncoder().encode(self.user_defined_data)
585         mock_parse_nsd.return_value = json.JSONEncoder().encode(nsd_data)
586         VnfPackageModel(
587             vnfPackageId="111",
588             vnfdId="vcpe_vfw_zte_1_0"
589         ).save()
590
591         PnfPackageModel(
592             pnfPackageId="112",
593             pnfdId="m6000_s"
594         ).save()
595
596         NSPackageModel(
597             nsPackageId='d0ea5ec3-0b98-438a-9bea-488230cff174',
598             operationalState='DISABLED',
599             usageState='NOT_IN_USE',
600             userDefinedData=user_defined_data_json,
601         ).save()
602
603         with open('nsd_content.txt', 'wt') as fp:
604             fp.write('test')
605         with open('nsd_content.txt', 'rt') as fp:
606             resp = self.client.put(
607                 "/api/nsd/v1/ns_descriptors/d0ea5ec3-0b98-438a-9bea-488230cff174/nsd_content",
608                 {'file': fp},
609             )
610         file_content = ''
611         with open(os.path.join(CATALOG_ROOT_PATH, 'd0ea5ec3-0b98-438a-9bea-488230cff174/nsd_content.txt')) as fp:
612             data = fp.read()
613             file_content = '%s%s' % (file_content, data)
614         ns_pkg = NSPackageModel.objects.filter(nsPackageId="d0ea5ec3-0b98-438a-9bea-488230cff174")
615         self.assertEqual("b632bddc-bccd-4180-bd8d-4e8a9578eff7", ns_pkg[0].nsdId)
616         self.assertEqual(const.PKG_STATUS.ONBOARDED, ns_pkg[0].onboardingState)
617         self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT)
618         self.assertEqual(None, resp.data)
619         self.assertEqual(file_content, 'test')
620         os.remove('nsd_content.txt')
621         expect_callbackuri = "http://callbackuri.com"
622         expect_notification = {
623             'id': "1111",
624             'notificationType': const.NSD_NOTIFICATION_TYPE.NSD_ONBOARDING,
625             'timeStamp': "nowtime()",
626             'nsdInfoId': "d0ea5ec3-0b98-438a-9bea-488230cff174",
627             'nsdId': "b632bddc-bccd-4180-bd8d-4e8a9578eff7",
628             "subscriptionId": "1111",
629             '_links': {
630                 'subscription': {
631                     'href': 'http://%s:%s/%s%s' % (pub_config.MSB_SERVICE_IP,
632                                                    pub_config.MSB_SERVICE_PORT,
633                                                    const.NSDM_SUBSCRIPTION_ROOT_URI,
634                                                    "1111")},
635                 'nsdInfo': {
636                     'href': 'http://%s:%s/%s/ns_descriptors/%s' % (pub_config.MSB_SERVICE_IP,
637                                                                    pub_config.MSB_SERVICE_PORT,
638                                                                    const.NSD_URL_PREFIX,
639                                                                    "d0ea5ec3-0b98-438a-9bea-488230cff174")
640                 }
641             }
642         }
643         mock_requests_post.assert_called_with(expect_callbackuri, data=expect_notification,
644                                               auth=HTTPBasicAuth("username", "password"),
645                                               headers={'Connection': 'close',
646                                                        'content-type': 'application/json',
647                                                        'accept': 'application/json'},
648                                               verify=False)
649
650
651 class NotificationTest(TestCase):
652     def setUp(self):
653         NsdmSubscriptionModel(subscriptionid="1",
654                               callback_uri="http://127.0.0.1/self",
655                               notificationTypes=const.NOTIFICATION_TYPES,
656                               nsdId="nsdid1",
657                               nsdInfoId="nsdinfoid1",
658                               pnfdInfoIds="pnfdInfoIds1",
659                               pnfdId="pnfdId1"
660                               ).save()
661
662     def tearDown(self):
663         NsdmSubscriptionModel.objects.all().delete()
664
665     @mock.patch("requests.post")
666     @mock.patch("uuid.uuid4")
667     @mock.patch.object(catalog.pub.utils.timeutil, "now_time")
668     def test_nsdpkg_notify(self, mock_nowtime, mock_uuid, mock_requests_post):
669         mock_nowtime.return_value = "nowtime()"
670         mock_uuid.return_value = "1111"
671         notify = NsdNotifications(const.NSD_NOTIFICATION_TYPE.NSD_ONBOARDING_FAILURE,
672                                   nsd_info_id="nsdinfoid1",
673                                   nsd_id="nsdid1",
674                                   failure_details="NSD(nsdid1) already exists.", operational_state=None)
675         notify.send_notification()
676         expect_callbackuri = "http://127.0.0.1/self"
677         expect_notification = {
678             'id': "1111",
679             'notificationType': const.NSD_NOTIFICATION_TYPE.NSD_ONBOARDING_FAILURE,
680             'timeStamp': "nowtime()",
681             'nsdInfoId': "nsdinfoid1",
682             'nsdId': "nsdid1",
683             'onboardingFailureDetails': "NSD(nsdid1) already exists.",
684             "subscriptionId": "1",
685             '_links': {
686                 'subscription': {
687                     'href': 'http://%s:%s/%s%s' % (pub_config.MSB_SERVICE_IP,
688                                                    pub_config.MSB_SERVICE_PORT,
689                                                    const.NSDM_SUBSCRIPTION_ROOT_URI,
690                                                    "1")},
691                 'nsdInfo': {
692                     'href': 'http://%s:%s/%s/ns_descriptors/%s' % (pub_config.MSB_SERVICE_IP,
693                                                                    pub_config.MSB_SERVICE_PORT,
694                                                                    const.NSD_URL_PREFIX,
695                                                                    "nsdinfoid1")
696                 }
697             }
698         }
699         mock_requests_post.assert_called_with(expect_callbackuri,
700                                               data=expect_notification,
701                                               headers={'Connection': 'close',
702                                                        'content-type': 'application/json',
703                                                        'accept': 'application/json'},
704                                               verify=False
705                                               )
706
707     @mock.patch("requests.post")
708     @mock.patch("uuid.uuid4")
709     @mock.patch.object(catalog.pub.utils.timeutil, "now_time")
710     def test_pnfpkg_notify(self, mock_nowtime, mock_uuid, mock_requests_post):
711         mock_nowtime.return_value = "nowtime()"
712         mock_uuid.return_value = "1111"
713         notify = PnfNotifications(const.NSD_NOTIFICATION_TYPE.PNFD_ONBOARDING,
714                                   pnfd_info_id="pnfdInfoIds1",
715                                   pnfd_id='pnfdId1',
716                                   failure_details=None)
717         notify.send_notification()
718         expect_callbackuri = "http://127.0.0.1/self"
719         expect_notification = {
720             'id': "1111",
721             'notificationType': const.NSD_NOTIFICATION_TYPE.PNFD_ONBOARDING,
722             'timeStamp': "nowtime()",
723             'pnfdInfoIds': "pnfdInfoIds1",
724             'pnfdId': "pnfdId1",
725             "subscriptionId": "1",
726             '_links': {
727                 'subscription': {
728                     'href': 'http://%s:%s/%s%s' % (pub_config.MSB_SERVICE_IP,
729                                                    pub_config.MSB_SERVICE_PORT,
730                                                    const.NSDM_SUBSCRIPTION_ROOT_URI,
731                                                    "1")},
732                 'pnfdInfo': {
733                     'href': 'http://%s:%s/%s/pnf_descriptors/%s' % (pub_config.MSB_SERVICE_IP,
734                                                                     pub_config.MSB_SERVICE_PORT,
735                                                                     const.NSD_URL_PREFIX,
736                                                                     "pnfdInfoIds1")
737                 }
738             }
739         }
740         mock_requests_post.assert_called_with(expect_callbackuri, data=expect_notification,
741                                               headers={'Connection': 'close',
742                                                        'content-type': 'application/json',
743                                                        'accept': 'application/json'},
744                                               verify=False)