add junit coverage for SvnfmService
[so.git] / bpmn / MSOCommonBPMN / src / main / groovy / org / onap / so / bpmn / common / scripts / SDNCAdapter.groovy
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.bpmn.common.scripts
24
25 import org.onap.so.logger.LoggingAnchor;
26 import org.onap.so.bpmn.core.UrnPropertiesReader
27 import org.onap.so.logger.ErrorCode;
28
29 import java.text.SimpleDateFormat
30
31 import org.camunda.bpm.engine.delegate.DelegateExecution
32 import org.onap.so.bpmn.core.WorkflowException
33 import org.onap.so.logger.MessageEnum
34 import org.slf4j.Logger
35 import org.slf4j.LoggerFactory
36
37 import static org.apache.commons.lang3.StringUtils.*
38
39
40 // SDNC Adapter Request/Response processing
41 public class SDNCAdapter extends AbstractServiceTaskProcessor {
42     private static final Logger logger = LoggerFactory.getLogger( SDNCAdapter.class);
43
44
45         def Prefix="SDNCA_"
46         ExceptionUtil exceptionUtil = new ExceptionUtil()
47
48         // Script Task: Process SDNC Workflow Request
49         // Params:      Workflow DelegateExecution
50         // Assume:      Received SDNCAdapterWorkflowRequest is in variable 'sdncAdapterWorkflowRequest'
51         //                      Put created SDNCAdapterRequest in variable 'sdncAdapterRequest'
52         public void preProcessRequest (DelegateExecution execution) {
53                 try{
54
55                         logger.trace("Begin PreProcess SDNCAdapterRequestScript  ")
56                         logger.debug("Incoming sdncAdapterWorkflowRequest:\n" + execution.getVariable("sdncAdapterWorkflowRequest"))
57
58                         // Initialize some variables used throughout the flow
59                         execution.setVariable("prefix", Prefix)
60                         execution.setVariable("sdncAdapterResponse", "")
61                         execution.setVariable("asynchronousResponseTimeout", false)
62                         execution.setVariable("continueListening", false)
63                         execution.setVariable("SDNCA_SuccessIndicator", false)
64                         execution.setVariable("SDNCA_InterimNotify", false)
65
66                         String requestId = execution.getVariable("mso-request-id")
67                         if(isBlank(requestId)){
68                                 exceptionUtil.buildAndThrowWorkflowException(execution, 400, 'mso-request-id not provided by calling flow')
69                         }
70
71                         // Authorization Info
72                         String basicAuthValue = UrnPropertiesReader.getVariable("mso.adapters.po.auth", execution)
73
74                         try {
75                                 def encodedString = utils.getBasicAuth(basicAuthValue, UrnPropertiesReader.getVariable("mso.msoKey", execution))
76                                 execution.setVariable("BasicAuthHeaderValue",encodedString)
77                         } catch (IOException ex) {
78                                 logger.error(LoggingAnchor.FOUR, MessageEnum.BPMN_GENERAL_EXCEPTION_ARG.toString(),
79                                                 "Unable to encode username password string", "BPMN",
80                                                 ErrorCode.UnknownError.getValue());
81                         }
82
83                         // TODO Use variables instead of passing xml request - Huh?
84
85                         // Get original RequestHeader
86                         def sdncwfreq= execution.getVariable("sdncAdapterWorkflowRequest")
87                         def requestHeader = utils.getNodeXml(sdncwfreq, "RequestHeader")
88                         requestHeader = requestHeader.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "")
89
90                         // Set Callback URL to use from URN Mapping or jBoss Property
91                         def origCallbackUrl = utils.getNodeText(requestHeader, "CallbackUrl")
92                         def callbackUrlToUse = UrnPropertiesReader.getVariable("mso.workflow.sdncadapter.callback", execution)
93                         MsoUtils msoUtil = new MsoUtils()
94                         def useQualifiedHostName = UrnPropertiesReader.getVariable("mso.use.qualified.host", execution)
95                         if((useQualifiedHostName!=null) && (useQualifiedHostName.equals("true"))){
96                                 callbackUrlToUse = msoUtil.getQualifiedHostNameForCallback(callbackUrlToUse)
97                         }
98                         logger.debug("Callback URL to use:\n" + callbackUrlToUse)
99                         requestHeader = requestHeader.replace(origCallbackUrl, callbackUrlToUse)
100
101                         // Get parameters from request header
102                         def sdnca_svcInstanceId = utils.getNodeText(requestHeader, "SvcInstanceId") // optional
103                         logger.debug("SvcInstanceId: " + sdnca_svcInstanceId)
104                         def sdnca_msoAction = utils.getNodeText(requestHeader, "MsoAction") // optional
105                         logger.debug("MsoAction: " + sdnca_msoAction)
106                         def sdnca_svcAction = utils.getNodeText(requestHeader, "SvcAction")
107                         logger.debug("SvcAction: " + sdnca_svcAction)
108                         def sdnca_svcOperation = utils.getNodeText(requestHeader, "SvcOperation")
109                         logger.debug("SvcOperation: " + sdnca_svcOperation)
110                         def sdncRequestData = utils.getChildNodes(sdncwfreq, "SDNCRequestData")
111                         sdncRequestData = sdncRequestData.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "")
112                         sdncRequestData = sdncRequestData.replaceAll('tag0:', '').replaceAll(':tag0', '')
113                         logger.debug("SDNCRequestData:\n" + sdncRequestData)
114                         def sdnca_serviceType = ""
115                         if (utils.nodeExists(sdncwfreq, "service-type")) {
116                                 sdnca_serviceType = utils.getNodeText(sdncwfreq, "service-type")
117                         }
118                         logger.debug("service-type: " + sdnca_serviceType)
119                         def serviceConfigActivate = false
120                         def source = ''
121                         if ((sdnca_svcAction == 'activate') && (sdnca_svcOperation == 'service-configuration-operation') && (sdnca_serviceType == 'uCPE-VMS')) {
122                                 serviceConfigActivate = true
123                                 if (utils.nodeExists(sdncwfreq, 'source')) {
124                                         source = utils.getNodeText(sdncwfreq, 'source')
125                                 }
126                         }
127                         execution.setVariable("serviceConfigActivate", serviceConfigActivate)
128                         logger.debug("serviceConfigActivate: " + serviceConfigActivate)
129                         execution.setVariable("source", source)
130                         logger.debug("source: " + source)
131
132                         //calling process should pass a generated uuid if sending multiple sdnc requests
133                         def sdncRequestId = utils.getNodeText(requestHeader, "RequestId")
134                         execution.setVariable(Prefix + "requestId", sdncRequestId)
135
136                         // Prepare SDNC Request to the SDNC Adapter
137                         String sdncAdapterRequest = """
138                         <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
139                         <SOAP-ENV:Body>
140                         <aetgt:SDNCAdapterRequest xmlns:aetgt="http://org.onap/workflow/sdnc/adapter/schema/v1" xmlns:sdncadaptersc="http://org.onap/workflow/sdnc/adapter/schema/v1">
141                         <sdncadapter:RequestHeader xmlns:sdncadapter="http://org.onap/workflow/sdnc/adapter/schema/v1">
142                         <sdncadapter:RequestId>${MsoUtils.xmlEscape(sdncRequestId)}</sdncadapter:RequestId>"""
143
144                         if (sdnca_svcInstanceId != null) {
145                                 sdncAdapterRequest += """
146                         <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(sdnca_svcInstanceId)}</sdncadapter:SvcInstanceId>"""
147                                 execution.setVariable("serviceInstanceId", sdnca_svcInstanceId)
148                         }
149
150                         sdncAdapterRequest += """
151                         <sdncadapter:SvcAction>${MsoUtils.xmlEscape(sdnca_svcAction)}</sdncadapter:SvcAction>
152                         <sdncadapter:SvcOperation>${MsoUtils.xmlEscape(sdnca_svcOperation)}</sdncadapter:SvcOperation>
153                         <sdncadapter:CallbackUrl>${MsoUtils.xmlEscape(callbackUrlToUse)}</sdncadapter:CallbackUrl>"""
154
155                         if (sdnca_msoAction != null) {
156                                 sdncAdapterRequest += """
157                         <sdncadapter:MsoAction>${MsoUtils.xmlEscape(sdnca_msoAction)}</sdncadapter:MsoAction>"""
158                         }
159
160                         sdncAdapterRequest += """
161                         </sdncadapter:RequestHeader>
162                         <sdncadaptersc:RequestData>
163                                 ${sdncRequestData}
164                         </sdncadaptersc:RequestData></aetgt:SDNCAdapterRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>"""
165
166                         logger.debug("Outgoing SDNCAdapterRequest:\n" + sdncAdapterRequest)
167                         execution.setVariable("sdncAdapterRequest", sdncAdapterRequest)
168
169                         logger.debug(UrnPropertiesReader.getVariable("mso.adapters.sdnc.endpoint", execution))
170                 }catch(Exception e){
171                         logger.debug('Internal Error occured during PreProcess Method: {}', e.getMessage(), e)
172                         exceptionUtil.buildAndThrowWorkflowException(execution, 9999, 'Internal Error occured during PreProcess Method') // TODO: what message and error code?
173                 }
174                 logger.trace("End pre Process SDNCRequestScript ")
175         }
176
177         public void postProcessResponse (DelegateExecution execution) {
178
179                 try{
180                         logger.trace("Begin POSTProcess SDNCAdapter ")
181                         logger.trace("Incoming sdncAdapterCallbackRequest:\n" + execution.getVariable("sdncAdapterCallbackRequest"))
182
183                         // Check the sdnccallback request and get the responsecode
184                         def sdnccallbackreq = execution.getVariable("sdncAdapterCallbackRequest")
185                         def callbackRequestData = ""
186                         def callbackHeader = ""
187
188                         if(sdnccallbackreq != null){
189                                 callbackHeader = utils.getNodeXml(sdnccallbackreq, "CallbackHeader")
190                                 callbackRequestData = utils.getNodeXml(sdnccallbackreq, "RequestData")
191
192                                 callbackHeader = callbackHeader.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "")
193
194                                 callbackRequestData = callbackRequestData.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "")
195
196                                 logger.trace("EnhancedCallbackRequestData:\n" + callbackRequestData)
197                                 execution.setVariable("enhancedCallbackRequestData", callbackRequestData)
198
199                                 String sdncAdapterWorkflowResponse ="""
200                                                 <sdncadapterworkflow:SDNCAdapterWorkflowResponse xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1">
201                                                 <sdncadapterworkflow:response-data>
202                                                 ${callbackHeader}
203                                                 ${callbackRequestData}
204                                                 </sdncadapterworkflow:response-data>
205                                                 </sdncadapterworkflow:SDNCAdapterWorkflowResponse>"""
206
207
208                                 sdncAdapterWorkflowResponse = utils.formatXml(sdncAdapterWorkflowResponse)
209                                 execution.setVariable("sdncAdapterResponse", sdncAdapterWorkflowResponse)
210                                 // TODO: Should deprecate use of processKey+Response variable for the response. Will use "WorkflowResponse" instead
211                                 execution.setVariable("WorkflowResponse", sdncAdapterWorkflowResponse)
212
213                                 // Check final indicator to determine if we are to continue listening or not
214                                 def continueListening = false
215                                 if (utils.nodeExists(callbackRequestData, "ack-final-indicator")) {
216                                         if (utils.getNodeText(callbackRequestData, "ack-final-indicator") == 'N') {
217                                                 continueListening = true
218                                         }
219                                 }
220                                 execution.setVariable("continueListening", continueListening)
221                                 logger.debug("Continue Listening: " + continueListening)
222                                 execution.setVariable("asynchronousResponseTimeout", false)
223                         }else{
224                                 // Timed out waiting for asynchronous message, build error response
225                                 exceptionUtil.buildWorkflowException(execution, 500, "SDNC Callback Timeout Error")
226                                 execution.setVariable("asynchronousResponseTimeout", true)
227                                 logger.debug("Timed out waiting for asynchronous message")
228                         }
229                 }catch(Exception e){
230                         logger.debug('Internal Error occured during PostProcess Method: ' + e)
231                         exceptionUtil.buildAndThrowWorkflowException(execution, 9999, 'Internal Error occured during PostProcess Method') // TODO: what message and error code?
232                 }
233                 logger.trace("End POSTProcess SDNCAdapter ")
234         }
235
236         public void callbackResponsecheck(DelegateExecution execution){
237
238                 def sdnccallbackreq=execution.getVariable("sdncAdapterCallbackRequest")
239                 logger.debug("sdncAdapterCallbackRequest :" + sdnccallbackreq)
240                 if (sdnccallbackreq==null){
241                         execution.setVariable("callbackResponseReceived",false);
242                 }else{
243                         execution.setVariable("callbackResponseReceived",true);
244                 }
245         }
246
247         public void resetCallbackRequest(DelegateExecution execution) {
248
249                 logger.trace("Begin Reset Callback Info SDNCAdapter ")
250
251                 // Clear sdncAdapterCallbackRequest variable
252                 execution.removeVariable("sdncAdapterCallbackRequest")
253
254                 // Determine and set SDNC Timeout Value
255                 def enhancedCallbackRequestData = execution.getVariable("enhancedCallbackRequestData")
256                 logger.debug("sdncAdapter - enhancedCallbackRequestData :" + enhancedCallbackRequestData)
257                 def interim = false
258                 if (enhancedCallbackRequestData != null) {
259                         if (utils.nodeExists(enhancedCallbackRequestData, "ack-final-indicator")) {
260                                 if (utils.getNodeText(enhancedCallbackRequestData, "ack-final-indicator") == 'N') {
261                                         interim = true
262                                 }
263                         }
264                 }
265                 def timeoutValue = UrnPropertiesReader.getVariable("mso.adapters.sdnc.timeout", execution)
266                 if(timeoutValue==null)
267                         timeoutValue="PT5M"
268                 def sdncAdapterWorkflowRequest = execution.getVariable("sdncAdapterWorkflowRequest")
269                 if (interim && utils.nodeExists(sdncAdapterWorkflowRequest, "InterimSDNCTimeOutValueInHours")) {
270                         timeoutValue = "PT" + utils.getNodeText(sdncAdapterWorkflowRequest, "InterimSDNCTimeOutValueInHours") + "H"
271                 } else if (utils.nodeExists(sdncAdapterWorkflowRequest, "SDNCTimeOutValueInMinutes")) {
272                         timeoutValue = "PT" + utils.getNodeText(sdncAdapterWorkflowRequest, "SDNCTimeOutValueInMinutes") + "M"
273                 }
274                 execution.setVariable("sdncTimeoutValue", timeoutValue)
275                 logger.debug("Setting SDNC Timeout Value to " + timeoutValue)
276
277                 logger.trace("End Reset Callback Info SDNCAdapter ")
278         }
279
280
281         public void prepareDBMessage(DelegateExecution execution) {
282
283                 logger.trace("Begin Prepare DB Message SDNCAdapter ")
284
285                 // Create DB Message
286                 def dbRequestId = execution.getVariable("mso-request-id")
287                 String dbUpdateInterimStageCompletion = """
288                         <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
289                                 <SOAP-ENV:Body>
290                                         <DBAdapter:updateInterimStageCompletion xmlns:DBAdapter="http://org.onap.so/requestsdb">
291                                                 <requestId>${MsoUtils.xmlEscape(dbRequestId)}</requestId>
292                                                 <interimStageCompletion>1</interimStageCompletion>
293                                                 <lastModifiedBy>BPEL</lastModifiedBy>
294                                 </DBAdapter:updateInterimStageCompletion>
295                                 </SOAP-ENV:Body>
296                         </SOAP-ENV:Envelope>
297                         """
298
299                 execution.setVariable("dbUpdateInterimStageCompletion", dbUpdateInterimStageCompletion)
300                 logger.debug("sdncAdapter - dbUpdateInterimStageCompletion :" + dbUpdateInterimStageCompletion)
301                 logger.debug("DB UpdateInterimStageCompletion:\n" + dbUpdateInterimStageCompletion)
302                 logger.trace("End Prepare DB Message SDNCAdapter ")
303         }
304
305         public String generateCurrentTimeInUtc(){
306                 final  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
307                 sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
308                 final String utcTime = sdf.format(new Date());
309                 return utcTime;
310         }
311
312         public void toggleSuccessIndicator(DelegateExecution execution){
313                 execution.setVariable("SDNCA_SuccessIndicator", true)
314                 logger.debug("Setting SDNCA Success Indicator to True")
315         }
316
317         public void assignError(DelegateExecution execution){
318                 logger.trace("Started Assign Error ")
319                 WorkflowException wf = execution.getVariable("WorkflowException")
320                 if(wf == null){
321                         exceptionUtil.buildWorkflowException(execution, 5000, "SDNCAdapter Encountered an Internal Error") // TODO: Not sure what message and error code we want here.....
322                 }else{
323                         execution.setVariable("WorkflowException", wf)
324                 }
325
326                 logger.debug("Outgoing WorkflowException is: " + execution.getVariable("WorkflowException"))
327                 logger.trace("End Assign Error ")
328         }
329
330         public void setTimeout(DelegateExecution execution){
331                 logger.trace("Started SetTimeout ")
332                 logger.debug("Timer expired, telling correlation service to stop listening")
333                 execution.setVariable("asynchronousResponseTimeout", true)
334
335                 logger.debug("Timed out branch sleeping for one second to give success branch a chance to complete if running")
336                 Thread.sleep(1000)
337                 logger.trace("End SetTimeout ")
338         }
339 }