0b9bcde4720d3432c081b4e53ba34860249db767
[so.git] /
1 package org.onap.so.bpmn.infrastructure.scripts
2
3 import com.fasterxml.jackson.core.type.TypeReference
4 import com.fasterxml.jackson.databind.ObjectMapper
5 import groovy.json.JsonSlurper
6 import org.camunda.bpm.engine.delegate.DelegateExecution
7 import org.onap.logging.filter.base.ONAPComponents
8 import org.onap.so.beans.nsmf.SliceTaskParams
9 import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor
10 import org.onap.so.bpmn.common.scripts.ExceptionUtil
11 import org.onap.so.bpmn.common.scripts.OofUtils
12 import org.onap.so.bpmn.core.UrnPropertiesReader
13 import org.onap.so.bpmn.core.domain.ServiceDecomposition
14 import org.onap.so.bpmn.core.domain.ServiceProxy
15 import org.onap.so.bpmn.core.json.JsonUtils
16 import org.onap.so.client.HttpClient
17 import org.onap.so.client.HttpClientFactory
18 import org.onap.aaiclient.client.aai.AAIObjectType
19 import org.onap.aaiclient.client.aai.AAIResourcesClient
20 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper
21 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri
22 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory
23 import org.slf4j.Logger
24 import org.slf4j.LoggerFactory
25 import javax.ws.rs.NotFoundException
26 import javax.ws.rs.core.Response
27
28 import static org.apache.commons.lang3.StringUtils.isBlank
29
30 public class DoCreateSliceServiceOption extends AbstractServiceTaskProcessor{
31
32     private static final Logger logger = LoggerFactory.getLogger( DoCreateSliceServiceOption.class)
33
34     ExceptionUtil exceptionUtil = new ExceptionUtil()
35
36     JsonUtils jsonUtil = new JsonUtils()
37
38     OofUtils oofUtils = new OofUtils()
39
40     ObjectMapper objectMapper = new ObjectMapper()
41
42     void preProcessRequest (DelegateExecution execution) {
43     }
44
45
46     void getNSIOptionfromOOF(DelegateExecution execution) {
47
48         //解析sliceProfile
49         logger.debug("start parseServiceProfile")
50         parseServiceProfile(execution)
51         logger.debug("end parseServiceProfile")
52
53         String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
54         logger.debug( "get NSI option OOF Url: " + urlString)
55
56         boolean isNSISuggested = true
57         execution.setVariable("isNSISuggested",isNSISuggested)
58
59         //Prepare auth for OOF - Begin
60         def authHeader = ""
61         String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
62         String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
63
64         String basicAuthValue = utils.encrypt(basicAuth, msokey)
65         if (basicAuthValue != null) {
66             logger.debug( "Obtained BasicAuth username and password for OOF: " + basicAuthValue)
67             try {
68                 authHeader = utils.getBasicAuth(basicAuthValue, msokey)
69                 execution.setVariable("BasicAuthHeaderValue", authHeader)
70             } catch (Exception ex) {
71                 logger.debug( "Unable to encode username and password string: " + ex)
72                 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to " +
73                         "encode username and password string")
74             }
75         } else {
76             logger.debug( "Unable to obtain BasicAuth - BasicAuth value null")
77             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " +
78                     "value null")
79         }
80         //Prepare auth for OOF - End
81
82         String requestId = execution.getVariable("msoRequestId")
83         Map<String, Object> profileInfo = execution.getVariable("serviceProfile")
84         Map<String, Object> nstSolution = execution.getVariable("nstSolution")
85         logger.debug("Get NST selection from OOF: " + nstSolution.toString())
86         String nstInfo = """{
87             "modelInvariantId":"${nstSolution.invariantUUID}",
88             "modelVersionId":"${nstSolution.UUID}",
89             "modelName":"${nstSolution.NSTName}"
90          }"""
91
92         String oofRequest = oofUtils.buildSelectNSIRequest(requestId, nstInfo, profileInfo)
93         logger.debug("Sending request to OOF: " + oofRequest)
94
95         //send request to get NSI option - Begin
96         URL url = new URL(urlString+"/api/oof/selection/nsi/v1")
97         HttpClient httpClient = new HttpClientFactory().newJsonClient(url, ONAPComponents.OOF)
98         httpClient.addAdditionalHeader("Authorization", authHeader)
99         Response httpResponse = httpClient.post(oofRequest)
100
101         processOOFResponse(httpResponse, execution)
102     }
103
104     private void processOOFResponse(Response httpResponse, DelegateExecution execution) {
105         int responseCode = httpResponse.getStatus()
106         logger.debug("OOF sync response code is: " + responseCode)
107
108         if (responseCode != 200) {
109             exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.")
110             logger.debug("Info: No NSI suggested by OOF")
111         }
112
113         SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
114         if (httpResponse.hasEntity()) {
115             String OOFResponse = httpResponse.readEntity(String.class)
116             logger.debug("NSI OOFResponse is: " + OOFResponse)
117             execution.setVariable("OOFResponse", OOFResponse)
118             int index = 0
119             //This needs to be changed to derive a value when we add policy to decide the solution options.
120             Map OOFResponseObject = new JsonSlurper().parseText(OOFResponse)
121             Map solutions = OOFResponseObject.get("solutions")
122
123             Boolean isSharable = false
124             String resourceSharingLevel = execution.getVariable("resourceSharingLevel")
125             if (resourceSharingLevel.equals("shared"))
126                 isSharable = true
127
128             if (solutions != null) {
129                 if (isSharable) {
130                     //sharedNSISolution
131                     processSharedNSISolutions(solutions, execution)
132                 } else {
133                     //TODO test OOF don't implement in Frankfurt release
134                     if (solutions.containsKey("newNSISolutions")) {
135                         List<Map> newNSISolutions = solutions.get("newNSISolutions")
136                         List<Map> NSSImap = new ArrayList<>()
137                         if (newNSISolutions != null && newNSISolutions.size() > 0) {
138                             NSSImap = newNSISolutions.get(index).get("NSSISolutions") as List<Map>
139                         }
140                         for (Map nssi : NSSImap) {
141                             def nssiSolution = nssi.get("NSSISolution") as Map<String, ?>
142                             String nssiName = nssiSolution.getOrDefault("NSSIName", "")
143                             String nssiId = nssiSolution.getOrDefault("NSSIId", "")
144                             String domain = nssiSolution.getOrDefault("domainName", "").toString().toUpperCase()
145                             switch (domain) {
146                                 case "AN":
147                                     sliceTaskParams.setAnSuggestNssiId(nssiId)
148                                     sliceTaskParams.setAnSuggestNssiName(nssiName)
149                                     break
150                                 case "CN":
151                                     sliceTaskParams.setCnSuggestNssiId(nssiId)
152                                     sliceTaskParams.setCnSuggestNssiName(nssiName)
153                                     break
154                                 case "TN":
155                                     sliceTaskParams.setTnSuggestNssiId(nssiId)
156                                     sliceTaskParams.setTnSuggestNssiName(nssiName)
157                                     break
158                                 default:
159                                     break
160                             }
161                         }
162                         //TODO sliceProfile
163                     }
164                 }
165             }
166             execution.setVariable("sliceTaskParams", sliceTaskParams)
167             logger.debug("Info: No NSI suggested by OOF")
168         }
169         logger.debug("*** Completed options Call to OOF ***")
170     }
171
172     private void processSharedNSISolutions(Map solutions, DelegateExecution execution) {
173         if (!solutions.containsKey("sharedNSISolutions"))
174         {
175             logger.error("OOF don't return sharedNSISolutions")
176             return
177         }
178         String nsiName, nsiInstanceId, nssiId, nssiName
179         Map sliceProfile
180         SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
181
182         Map sharedNSIsolution = ((List) solutions.get("sharedNSISolutions")).get(0)
183         nsiInstanceId = sharedNSIsolution.getOrDefault("NSIId", "")
184         nsiName = sharedNSIsolution.getOrDefault("NSIName", "")
185         sliceTaskParams.setNstId(nsiInstanceId)
186         sliceTaskParams.setSuggestNsiName(nsiName)
187
188         //Temporary modification
189         List NSSIs = sharedNSIsolution.get("NSSIs")
190         if(NSSIs.size()==1){
191             Map nssi = NSSIs.get(0)
192             nssiId = nssi.getOrDefault("NSSIId","")
193             nssiName = nssi.getOrDefault("NSSIName","")
194             sliceTaskParams.setCnSuggestNssiId(nssiId)
195             sliceTaskParams.setCnSuggestNssiName(nssiName)
196             sliceProfile = ((List)nssi.get("sliceProfile"))?.get(0)
197 //            execution.setVariable("sliceProfileCn", sliceProfile)
198 //            sliceTaskParams.setSliceProfileCn(sliceProfile)
199         }
200         logger.debug("OOF sharedNSISolution nsiInstanceId:${nsiInstanceId}, nsiName:${nsiName}, nssiId:${nssiId}, nssiName:${nssiName}")
201         logger.debug("OOF SliceProfile:"+sliceProfile.toString())
202     }
203
204     void parseServiceProfile(DelegateExecution execution) {
205         logger.debug("Start parseServiceProfile")
206         String serviceType = execution.getVariable("serviceType")
207         Map<String, Object> serviceProfile = execution.getVariable("serviceProfile")
208
209         // set sliceProfile for three domains
210         Map<String, Object> sliceProfileTn = getSliceProfile(serviceType, "TN", serviceProfile)
211         Map<String, Object> sliceProfileCn = getSliceProfile(serviceType, "CN", serviceProfile)
212         Map<String, Object> sliceProfileAn = getSliceProfile(serviceType, "AN", serviceProfile)
213
214         execution.setVariable("sliceProfileTn", sliceProfileTn)
215         execution.setVariable("sliceProfileCn", sliceProfileCn)
216         execution.setVariable("sliceProfileAn", sliceProfileAn)
217         logger.debug("sliceProfileTn: " + sliceProfileTn)
218         logger.debug("sliceProfileCn: " + sliceProfileCn)
219         logger.debug("sliceProfileAn: " + sliceProfileAn)
220
221         logger.debug("Finish parseServiceProfile")
222     }
223
224     Map getSliceProfile(String serviceType, String domain, Map<String, Object> serviceProfile) {
225         //String variablePath = "nsmf." + serviceType + ".profileMap" + domain
226         //String profileMapStr = UrnPropertiesReader.getVariable(variablePath)
227         String profileMapStr = """ {
228             "skip_post_instantiation_configuration":"skip_post_instantiation_configuration", 
229             "controller_actor":"controller_actor", 
230             "areaTrafficCapDL":"areaTrafficCapDL", 
231             "maxNumberofUEs":"maxNumberofUEs", 
232             "latency":"latency", 
233             "expDataRateUL":"expDataRateUL", 
234             "sNSSAI":"sNSSAI", 
235             "plmnIdList":"plmnIdList", 
236             "sST":"sST", 
237             "areaTrafficCapUL":"areaTrafficCapUL", 
238             "uEMobilityLevel":"uEMobilityLevel", 
239             "expDataRateDL":"expDataRateDL", 
240             "coverageAreaTAList":"coverageAreaTAList", 
241             "activityFactor":"activityFactor", 
242             "resourceSharingLevel":"resourceSharingLevel"
243         }
244         """.trim().replaceAll(" ", "")
245         logger.debug("Profile map for " + domain + " : " + profileMapStr)
246         Map<String, String> profileMaps = objectMapper.readValue(profileMapStr, new TypeReference<Map<String, String>>(){})
247         Map<String, Object> sliceProfileTn = [:]
248         for (Map.Entry<String, String> profileMap : profileMaps) {
249             sliceProfileTn.put(profileMap.key, serviceProfile.get(profileMap.value))
250         }
251
252         return sliceProfileTn
253     }
254
255     void processDecomposition(DelegateExecution execution){
256         logger.debug("Start processDecomposition")
257
258         ServiceDecomposition serviceDecomposition= execution.getVariable("serviceDecomposition")
259         SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
260         String nstName = serviceDecomposition.getModelInfo().getModelName()
261         sliceTaskParams.setNstName(nstName)
262         String nstId = serviceDecomposition.getModelInfo().getModelUuid()
263         sliceTaskParams.setNstId(nstId)
264
265         logger.debug("End processDecomposition")
266     }
267
268
269     void prepareNSTDecompose(DelegateExecution execution) {
270
271         String modelUuid = execution.getVariable("nstModelUuid")
272         String modelInvariantUuid = execution.getVariable("nstModelInvariantUuid")
273
274         String serviceModelInfo = """{
275             "modelInvariantUuid":"${modelInvariantUuid}",
276             "modelUuid":"${modelUuid}",
277             "modelVersion":""
278              }"""
279         execution.setVariable("serviceModelInfo", serviceModelInfo)
280     }
281
282     void prepareNSSTDecompose(DelegateExecution execution) {
283         Boolean isMoreNSSTtoProcess = false
284         Integer maxNSST = execution.getVariable("maxNSST")
285         Integer currentNSST=execution.getVariable("currentNSST")
286         List<String> nsstModelUUIDList = new ArrayList<>()
287         nsstModelUUIDList = execution.getVariable("nsstModelUUIDList")
288         String modelUuid = nsstModelUUIDList.get(currentNSST)
289         String serviceModelInfo = """{
290             "modelInvariantUuid":"",
291             "modelUuid":"${modelUuid}",
292             "modelVersion":""
293              }"""
294         execution.setVariable("serviceModelInfo", serviceModelInfo)
295         currentNSST=currentNSST+1
296         if(currentNSST<maxNSST)
297             isMoreNSSTtoProcess=true
298         execution.setVariable("isMoreNSSTtoProcess",isMoreNSSTtoProcess)
299         execution.setVariable("maxNSST",maxNSST)
300         execution.setVariable("currentNSST",currentNSST)
301     }
302
303
304     void prepareNSSTlistfromNST(DelegateExecution execution) {
305         //Need to update this part from decomposition.
306         logger.trace("Enter prepareNSSTlistfromNST()")
307         Boolean isMoreNSSTtoProcess = false
308         ServiceDecomposition serviceDecomposition= execution.getVariable("serviceDecomposition")
309         SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
310         String nstName = serviceDecomposition.getModelInfo().getModelName()
311         sliceTaskParams.setNstName(nstName)
312         String nstId = serviceDecomposition.getModelInfo().getModelUuid()
313         sliceTaskParams.setNstId(nstId)
314         execution.setVariable("sliceTaskParams",sliceTaskParams)
315
316         List<ServiceProxy> proxyList = serviceDecomposition.getServiceProxy()
317         List<String> nsstModelUUIDList = new ArrayList<>()
318         for(ServiceProxy serviceProxy:proxyList)
319             nsstModelUUIDList.add(serviceProxy.getSourceModelUuid())
320         execution.setVariable("nsstModelUUIDList",nsstModelUUIDList)
321         Integer maxNSST = nsstModelUUIDList.size()
322         Integer currentNSST=0
323         execution.setVariable("maxNSST",maxNSST)
324         execution.setVariable("currentNSST",currentNSST)
325         if(currentNSST<maxNSST)
326             isMoreNSSTtoProcess=true
327         execution.setVariable("isMoreNSSTtoProcess",isMoreNSSTtoProcess)
328         logger.trace("Exit prepareNSSTlistfromNST()")
329
330     }
331
332     void getNSSTOption(DelegateExecution execution) {
333         ServiceDecomposition serviceDecomposition= execution.getVariable("serviceDecomposition")
334         String urlString = UrnPropertiesReader.getVariable("mso.oof.endpoint", execution)
335         String globalSubscriberId = execution.getVariable("globalSubscriberId")
336         String serviceType = execution.getVariable("subscriptionServiceType")
337         String nssiInstanceId =""
338         String nssiName =""
339         SliceTaskParams sliceTaskParams = execution.getVariable("sliceTaskParams")
340         logger.debug( "get NSI option OOF Url: " + urlString)
341         boolean isNSISuggested = false
342         execution.setVariable("isNSISuggested",isNSISuggested)
343
344         //Prepare auth for OOF - Begin
345         def authHeader = ""
346         String basicAuth = UrnPropertiesReader.getVariable("mso.oof.auth", execution)
347         String msokey = UrnPropertiesReader.getVariable("mso.msoKey", execution)
348
349         String basicAuthValue = utils.encrypt(basicAuth, msokey)
350         if (basicAuthValue != null) {
351             logger.debug( "Obtained BasicAuth username and password for OOF: " + basicAuthValue)
352             try {
353                 authHeader = utils.getBasicAuth(basicAuthValue, msokey)
354                 execution.setVariable("BasicAuthHeaderValue", authHeader)
355             } catch (Exception ex) {
356                 logger.debug( "Unable to encode username and password string: " + ex)
357                 exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - Unable to " +
358                         "encode username and password string")
359             }
360         } else {
361             logger.debug( "Unable to obtain BasicAuth - BasicAuth value null")
362             exceptionUtil.buildAndThrowWorkflowException(execution, 401, "Internal Error - BasicAuth " +
363                     "value null")
364         }
365         //Prepare auth for OOF - End
366         //Prepare send request to OOF - Begin
367         String requestId = execution.getVariable("msoRequestId")
368         Map<String, Object> profileInfo = execution.getVariable("serviceProfile")
369         String nsstModelInvariantUuid = serviceDecomposition.getModelInfo().getModelInvariantUuid()
370         String nsstModelUuid = serviceDecomposition.getModelInfo().getModelUuid()
371         String nsstInfo = """"NSSTInfo": {
372         "invariantUUID":"${nsstModelInvariantUuid}",
373         "UUID":"${nsstModelUuid}"
374          }"""
375         String oofRequest = oofUtils.buildSelectNSSIRequest(execution, requestId, nsstInfo ,profileInfo)
376
377
378         URL url = new URL(urlString+"/api/oof/v1/selectnssi")
379         HttpClient httpClient = new HttpClientFactory().newJsonClient(url, ONAPComponents.OOF)
380         httpClient.addAdditionalHeader("Authorization", authHeader)
381         Response httpResponse = httpClient.post(oofRequest)
382
383         int responseCode = httpResponse.getStatus()
384         logger.debug("OOF sync response code is: " + responseCode)
385
386         if(responseCode != 200){
387             exceptionUtil.buildAndThrowWorkflowException(execution, responseCode, "Received a Bad Sync Response from OOF.")
388         }
389
390         if(httpResponse.hasEntity()){
391             String OOFResponse = httpResponse.readEntity(String.class)
392             execution.setVariable("OOFResponse", OOFResponse)
393             nssiInstanceId = jsonUtil.getJsonValue(OOFResponse, "NSSIIInfo.NSSIID")
394             nssiName = jsonUtil.getJsonValue(OOFResponse, "NSSIInfo.NSSIName")
395             execution.setVariable("nssiInstanceId",nssiInstanceId)
396             execution.setVariable("nssiName",nssiName)
397         }
398         if(isBlank(nssiInstanceId)){
399             logger.debug( "There is no valid NSST suggested by OOF.")
400         }else
401         {
402             try {
403                 AAIResourcesClient resourceClient = new AAIResourcesClient()
404                 AAIResourceUri serviceInstanceUri = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, globalSubscriberId, serviceType, nssiInstanceId)
405                 AAIResultWrapper wrapper = resourceClient.get(serviceInstanceUri, NotFoundException.class)
406                 Optional<org.onap.aai.domain.yang.ServiceInstance> si = wrapper.asBean(org.onap.aai.domain.yang.ServiceInstance.class)
407                 org.onap.aai.domain.yang.ServiceInstance nssi = si.get()
408
409                 String domain = nssi.getEnvironmentContext().toString().toUpperCase()
410                 switch (domain) {
411                     case "AN":
412                         sliceTaskParams.setAnSuggestNssiId(nssi.getServiceInstanceId())
413                         sliceTaskParams.setAnSuggestNssiName(nssi.getServiceInstanceName())
414                         break
415                     case "CN":
416                         sliceTaskParams.setCnSuggestNssiId(nssi.getServiceInstanceId())
417                         sliceTaskParams.setCnSuggestNssiName(nssi.getServiceInstanceName())
418                         break
419                     case "TN":
420                         sliceTaskParams.setTnSuggestNssiId(nssi.getServiceInstanceId())
421                         sliceTaskParams.setTnSuggestNssiName(nssi.getServiceInstanceName())
422                         break
423                     default:
424                         break
425                 }
426             }catch(NotFoundException e)
427             {
428                 logger.debug("NSSI Service Instance not found in AAI: " + nssiInstanceId)
429             }catch(Exception e)
430             {
431                 logger.debug("NSSI Service Instance not found in AAI: " + nssiInstanceId)
432             }
433         }
434         logger.debug("Prepare NSSI option completed ")
435     }
436 }
437