3 # ============LICENSE_START===================================================
4 # ORAN SMO PACKAGE - PYTHONSDK TESTS
5 # ================================================================================
6 # Copyright (C) 2021 Samsung Electronics
7 # Copyright (C) 2022 AT&T Intellectual Property. All rights
9 # ============================================================================
10 # Licensed under the Apache License, Version 2.0 (the "License");
11 # you may not use this file except in compliance with the License.
12 # You may obtain a copy of the License at
14 # http://www.apache.org/licenses/LICENSE-2.0
16 # Unless required by applicable law or agreed to in writing, software
17 # distributed under the License is distributed on an "AS IS" BASIS,
18 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 # See the License for the specific language governing permissions and
20 # limitations under the License.
22 # SPDX-License-Identifier: Apache-2.0
23 # ============LICENSE_END=====================================================
26 """Create SDC Templates for Network Slicing option2 test."""
29 from time import sleep
31 from onapsdk.sdc.vfc import Vfc
32 from onapsdk.sdc.vf import Vf
33 import onapsdk.constants as const
34 from onapsdk.configuration import settings
35 from onapsdk.exceptions import ResourceNotFound
36 from onapsdk.sdc.properties import Property, ParameterError
37 from waiting import wait
38 from oransdk.aai.service_design_and_creation import AaiModel
39 from oransdk.sdc.sdc import SdcTemplate
40 from oransdk.sdc.service import OranService
42 # Set working dir as python script location
43 abspath = os.path.abspath(__file__)
44 dname = os.path.dirname(abspath)
47 logging.config.dictConfig(settings.LOG_CONFIG)
48 logger = logging.getLogger("####################### Start SDC Preparation")
52 class SdcPreparation():
53 """Can be used to prepare SDC for Network Slicing usecase option2."""
55 def __init__(self, suffix: str = None):
57 Initialize SDC preparation object.
60 suffix (str, optional): the suffix of the SDC template names
68 def prepare_sdc(self) -> dict:
69 """Create SDC templates."""
70 # Populate AAI needed value
73 vendor = sdc.create_vendor('ONAP')
74 sdc.create_vsp('test1', vendor)
76 # 0.create custom categories
77 logger.info("####################### create custom categories")
78 sdc.create_service_category(['CST', 'ServiceProfile', 'AN SliceProfile', 'CN SliceProfile', 'TN SliceProfile',
79 'NST', 'TN BH NSST', 'TN Network Requirement', 'AN NF NSST', 'CN NSST', 'Allotted Resource'])
82 vf_tn_bh_ar = self.create_tn_resources(sdc, vendor)
83 vf_embban_nf_ar = self.create_an_resources(sdc, vendor)
84 vf_embbcn_external_ar = self.create_cn_resources(sdc, vendor)
85 self.create_nst(sdc, vf_embbcn_external_ar, vf_embban_nf_ar, vf_tn_bh_ar)
87 vf_slice_ar = self.create_slice_ar(sdc, vendor)
89 srv_slice_profile_an_o2 = self.create_an_slice_profiles(sdc, vf_slice_ar)
90 srv_slice_profile_tn = self.create_tn_slice_profiles(sdc, vf_slice_ar)
91 srv_slice_profile_cn = self.create_cn_slice_profiles(sdc, vf_slice_ar)
92 srv_profile_o2 = self.create_service_profile(sdc, vf_slice_ar, srv_slice_profile_cn, srv_slice_profile_tn, srv_slice_profile_an_o2)
93 cst = self.create_cst(sdc, srv_profile_o2)
94 wait(lambda: self.verify_distribution(), sleep_seconds=60, timeout_seconds=3600, waiting_for="All services distributed successfully")
95 return [cst.identifier, cst.unique_uuid, srv_profile_o2.identifier]
97 def create_tn_resources(self, sdc, vendor) -> dict:
98 """Create TN related resources."""
99 # 1.Create TN_Network_Requirement Service
100 logger.info("####################### create TN_Network_Requirement Service")
101 props = [Property('ConnectionLink', 'string'),
102 Property('jitter', 'string', value='10'),
103 Property('latency', 'integer', value=10),
104 Property('maxBandwith', 'integer', value=1000)]
106 srv_tn_network = sdc.create_service(self.updated_name('TN_Network_Requirement'), 'TN Network Requirement', properties=props,
107 inputs=[Property('ConnectionLink', 'string')])
108 service_dict[srv_tn_network.identifier] = False
109 service_list.append(srv_tn_network)
111 # 2.Create TN_Network_Req_AR
112 logger.info("####################### create TN_Network_Req_AR")
113 vf = sdc.create_vf(self.updated_name('TN_Network_Req_AR'), 'Allotted Resource', 'Allotted Resource', vendor)
114 for c in vf.components:
115 if c.name == 'AllottedResource 0':
116 c.get_property('providing_service_invariant_uuid').value = srv_tn_network.unique_uuid
117 c.get_property('providing_service_uuid').value = srv_tn_network.identifier
118 c.get_property('providing_service_name').value = srv_tn_network.name
122 # 3.Create Tn_ONAP_internal_BH Service
123 logger.info("####################### create Tn_ONAP_internal_BH Service")
124 props = [Property('pLMNIdList', 'string', value='39-00'),
125 Property('jitter', 'string', value='10'),
126 Property('latency', 'integer', value=10),
127 Property('maxBandwith', 'integer', value=1000)]
129 srv_tn_bh = sdc.create_service(self.updated_name('Tn_ONAP_internal_BH'), 'TN BH NSST', vnfs=[vf],
130 role='ONAP_internal', properties=props)
131 service_dict[srv_tn_bh.identifier] = False
132 service_list.append(srv_tn_bh)
135 logger.info("####################### Create Tn_BH_AR")
136 vf_tn_bh_ar = sdc.create_vf(self.updated_name('Tn_BH_AR'), 'Allotted Resource', 'Allotted Resource', vendor)
137 for c in vf_tn_bh_ar.components:
138 if c.name == 'AllottedResource 0':
139 c.get_property('providing_service_invariant_uuid').value = srv_tn_bh.unique_uuid
140 c.get_property('providing_service_uuid').value = srv_tn_bh.identifier
141 c.get_property('providing_service_name').value = srv_tn_bh.name
143 sdc.onboard_vf(vf_tn_bh_ar)
146 def create_an_resources(self, sdc, vendor) -> dict:
147 """Create AN related resources."""
148 # 4.Create EmbbAn_NF Service Template
149 logger.info("####################### create EmbbAn_NF Service Template")
150 props = [Property('anNSSCap', 'org.openecomp.datatypes.NSSCapabilities')]
151 srv_embban_nf = sdc.create_service(self.updated_name('EmbbAn_NF'), 'AN NF NSST', role='huawei', service_type='embb', properties=props)
152 service_dict[srv_embban_nf.identifier] = False
153 service_list.append(srv_embban_nf)
155 # 7.Create EmbbAn_NF_AR
156 logger.info("####################### create EmbbAn_NF_AR")
157 vf_embban_nf_ar = sdc.create_vf(self.updated_name('EmbbAn_NF_AR'), 'Allotted Resource', 'Allotted Resource', vendor)
158 for c in vf_embban_nf_ar.components:
159 if c.name == 'AllottedResource 0':
160 c.get_property('providing_service_invariant_uuid').value = srv_embban_nf.unique_uuid
161 c.get_property('providing_service_uuid').value = srv_embban_nf.identifier
162 c.get_property('providing_service_name').value = srv_embban_nf.name
164 sdc.onboard_vf(vf_embban_nf_ar)
165 return vf_embban_nf_ar
167 def create_cn_resources(self, sdc, vendor) -> dict:
168 """Create CN related resources."""
169 # 5.Create EmbbCn_External Service Template
170 logger.info("####################### create EmbbCn_External Service Template")
171 srv_embbcn = OranService(name=self.updated_name('EmbbCn_External'),
175 properties=[Property('cnCap', 'org.openecomp.datatypes.NSSCapabilities',\
176 value="{\\\"latency\\\":20,\\\"maxNumberofUEs\\\":10000,\
177 \\\"resourceSharingLevel\\\":\\\"Shared\\\",\\\"sST\\\":\\\"eMBB\\\",\
178 \\\"activityFactor\\\":30,\\\"areaTrafficCapDL\\\":800,\
179 \\\"areaTrafficCapUL\\\":800,\\\"expDataRateDL\\\":1000,\
180 \\\"survivalTime\\\":10,\\\"uEMobilityLevel\\\":\\\"stationary\\\",\
181 \\\"expDataRateUL\\\":1000,\\\"pLMNIdList\\\":\\\"39-00\\\"}")])
185 if srv_embbcn.status == const.DRAFT:
186 srv_embbcn.add_deployment_artifact(artifact_type="WORKFLOW", artifact_name="eMBB.zip", artifact="../resources/eMBB.zip",
187 artifact_label="abc")
189 if srv_embbcn.status != const.DISTRIBUTED:
196 except ResourceNotFound as e:
204 service_dict[srv_embbcn.identifier] = False
205 service_list.append(srv_embbcn)
207 # 8.EmbbCn_External_AR
208 logger.info("####################### create EmbbCn_External_AR")
209 vf_embbcn_external_ar = sdc.create_vf(self.updated_name('EmbbCn_External_AR'), 'Allotted Resource', 'Allotted Resource', vendor)
210 for c in vf_embbcn_external_ar.components:
211 if c.name == 'AllottedResource 0':
212 c.get_property('providing_service_invariant_uuid').value = srv_embbcn.unique_uuid
213 c.get_property('providing_service_uuid').value = srv_embbcn.identifier
214 c.get_property('providing_service_name').value = srv_embbcn.name
216 sdc.onboard_vf(vf_embbcn_external_ar)
217 return vf_embbcn_external_ar
219 def create_nst(self, sdc, vf_embbcn_external_ar, vf_embban_nf_ar, vf_tn_bh_ar) -> None:
221 # 9.Create EmbbNst_O2 Service Template
222 logger.info("####################### create service EmbbNst_O2")
223 props = [Property('latency', 'integer', value=20),
224 Property('maxNumberofUEs', 'integer', value=1000),
225 Property('maxNumberofConns', 'integer', value=100000),
226 Property('resourceSharingLevel', 'string', value='Shared'),
227 Property('sST', 'string', value='eMBB'),
228 Property('activityFactor', 'integer', value=60),
229 Property('availability', 'float', value=0.6),
230 Property('dLThptPerSlice', 'integer', value=1000),
231 Property('uLThptPerSlice', 'integer', value=1000),
232 Property('jitter', 'integer', value=10),
233 Property('survivalTime', 'integer', value=10),
234 Property('uEMobilityLevel', 'string', value='stationary'),
235 Property('pLMNIdList', 'string', value='39-00'),
236 Property('reliability', 'string', value='99%')]
237 nst = sdc.create_service(self.updated_name('EmbbNst_O2'),
240 vnfs=[vf_embbcn_external_ar, vf_embban_nf_ar, vf_tn_bh_ar],
242 service_dict[nst.identifier] = False
243 service_list.append(nst)
245 def create_slice_ar(self, sdc, vendor) -> dict:
246 """Create Slice AR."""
247 # 10. create Slice_AR
248 logger.info("####################### create Slice_AR")
250 vfc = Vfc('AllottedResource')
251 vf_slice_ar = Vf(name=self.updated_name('Slice_AR'), category='Allotted Resource', subcategory='Allotted Resource', vendor=vendor)
253 if vf_slice_ar.status == const.DRAFT:
254 vf_slice_ar.add_resource(vfc)
256 for c in vf_slice_ar.components:
257 if c.name == 'AllottedResource 0':
258 cp = sdc.get_component_property(c, 'providing_service_invariant_uuid')
260 logger.info('declare input for property [%s]', cp)
261 vf_slice_ar.declare_input(cp)
263 raise ParameterError('no property providing_service_invariant_uuid found')
265 cp = sdc.get_component_property(c, 'providing_service_uuid')
267 logger.info('declare input for property [%s]', cp)
268 vf_slice_ar.declare_input(cp)
270 raise ParameterError('no property providing_service_uuid found')
274 sdc.onboard_vf(vf_slice_ar)
275 # AAI bug workaround: create Slice_ar in AAI DB before SO distribution, otherwise service will not be deployed to AAI succesfully
276 aai = AaiModel(invariant_id=vf_slice_ar.unique_uuid, model_type="resource", resource_version=vf_slice_ar.version)
277 aai.create(vf_slice_ar.name, vf_slice_ar.identifier, aai.invariant_id)
280 def create_an_slice_profiles(self, sdc, vf_slice_ar) -> dict:
281 """Create AN Slice profile."""
282 # 11.Create SliceProfile_AN_O2 Service Template
283 logger.info("####################### create SliceProfile_AN_O2 Service Template")
284 an_slice_profile = [Property('ipAddress', 'string'),
285 Property('logicInterfaceId', 'string'),
286 Property('nextHopInfo', 'string')]
287 complex_property = Property('anSP', 'org.openecomp.datatypes.SliceProfile')
288 srv_slice_profile_an_o2 = sdc.create_service_1(self.updated_name('SliceProfile_AN_O2'),
290 properties=an_slice_profile,
291 inputs=an_slice_profile,
292 complex_input=complex_property,
294 service_dict[srv_slice_profile_an_o2.identifier] = False
295 service_list.append(srv_slice_profile_an_o2)
296 return srv_slice_profile_an_o2
298 def create_tn_slice_profiles(self, sdc, vf_slice_ar) -> dict:
299 """Create TN Slice profile."""
300 # 12.Create SliceProfile_TN Service Template
301 logger.info('####################### create service SliceProfile_TN')
302 tn_slice_profile = [Property('jitter', 'string'),
303 Property('latency', 'integer'),
304 Property('pLMNIdList', 'string'),
305 Property('sNSSAI', 'string'),
306 Property('sST', 'integer'),
307 Property('maxBandwidth', 'integer')]
309 srv_slice_profile_tn = sdc.create_service_1(self.updated_name('SliceProfile_TN'),
312 inputs=tn_slice_profile,
313 properties=tn_slice_profile)
314 service_dict[srv_slice_profile_tn.identifier] = False
315 service_list.append(srv_slice_profile_tn)
316 return srv_slice_profile_tn
318 def create_cn_slice_profiles(self, sdc, vf_slice_ar) -> dict:
319 """Create CN Slice profile."""
320 # 13.Create SliceProfile_CN Service Template
321 logger.info('####################### create slice SliceProfile_CN')
322 cn_slice_profile = [Property('ipAddress', 'string'),
323 Property('logicInterfaceId', 'string'),
324 Property('nextHopInfo', 'string')]
325 srv_slice_profile_cn = sdc.create_service_1(self.updated_name('SliceProfile_CN'),
328 inputs=cn_slice_profile,
329 properties=cn_slice_profile)
330 service_dict[srv_slice_profile_cn.identifier] = False
331 service_list.append(srv_slice_profile_cn)
332 return srv_slice_profile_cn
334 def create_service_profile(self, sdc, vf_slice_ar, srv_slice_profile_cn, srv_slice_profile_tn, srv_slice_profile_an_o2) -> dict:
335 """Create Slice profile."""
336 # 14.Create ServiceProfile_O2 Service Template
337 logger.info('####################### create service ServiceProfile O2')
338 service_props = Property('spProp', 'org.openecomp.datatypes.ServiceProfile')
339 srv_profile_o2 = sdc.create_service_1(self.updated_name('ServiceProfile_O2'),
341 properties=[service_props],
342 complex_input=service_props,
343 vnfs=[vf_slice_ar, srv_slice_profile_cn, srv_slice_profile_tn, srv_slice_profile_an_o2],
345 service_dict[srv_profile_o2.identifier] = False
346 service_list.append(srv_profile_o2)
347 return srv_profile_o2
349 def create_cst(self, sdc, srv_profile_o2) -> dict:
351 # 15.Create CST_O2 Service Template
352 logger.info('####################### create service CST O2')
353 cs_prop = Property('csProp', 'org.openecomp.datatypes.CSProperties')
354 cst = sdc.create_service_1(self.updated_name('CST_O2'),
358 vnfs=[srv_profile_o2],
359 properties=[cs_prop],
360 complex_input=cs_prop)
361 service_dict[cst.identifier] = False
362 service_list.append(cst)
365 def updated_name(self, name) -> str:
366 """Adding suffix for the name."""
367 return name + self.suffix
370 def verify_distribution(cls) -> bool:
371 """Verify the distribution of all the services."""
372 for service in service_list:
373 logger.info('####################### verify service:%s', service.name)
374 if service_dict[service.identifier]:
378 result = service.get_distribution_status()
379 for element in result['distributionStatusList']:
380 if (element['omfComponentID'] == "SO-COpenSource-Env11" and (element['status'] == "DEPLOY_OK" or element['status'] == const.DOWNLOAD_OK)):
382 if (element['omfComponentID'] == "aai-ml" and element['status'] == "DEPLOY_OK"):
384 if so_ready and aai_ready:
385 service_dict[service.identifier] = True
386 logger.info('####################### service %s distributed successfully to SO and AAI', service.name)
389 for value in service_dict.values():
391 logger.info('####################### res is:%s, value is:%s', str(res), str(value))