Initial source code
[oam/tr069-adapter.git] / acs / requestprocessor / src / main / java / org / commscope / tr069adapter / acs / requestprocessor / custom / ConfigureMultipleObject.java
1 /*\r
2  * ============LICENSE_START========================================================================\r
3  * ONAP : tr-069-adapter\r
4  * =================================================================================================\r
5  * Copyright (C) 2020 CommScope Inc Intellectual Property.\r
6  * =================================================================================================\r
7  * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,\r
8  * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You\r
9  * may obtain a copy of the License at\r
10  *\r
11  * http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r
14  * either express or implied. See the License for the specific language governing permissions and\r
15  * limitations under the License.\r
16  * ===============LICENSE_END=======================================================================\r
17  */\r
18 \r
19 package org.commscope.tr069adapter.acs.requestprocessor.custom;\r
20 \r
21 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.NUMBER_REGEX;\r
22 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.SUCCESS;\r
23 \r
24 import java.util.ArrayList;\r
25 import java.util.List;\r
26 import java.util.regex.Matcher;\r
27 import java.util.regex.Pattern;\r
28 \r
29 import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;\r
30 import org.commscope.tr069adapter.acs.common.DeviceRPCResponse;\r
31 import org.commscope.tr069adapter.acs.common.OperationDetails;\r
32 import org.commscope.tr069adapter.acs.common.OperationResponse;\r
33 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
34 import org.commscope.tr069adapter.acs.common.dto.TR069DeviceDetails;\r
35 import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;\r
36 import org.commscope.tr069adapter.acs.common.dto.TR069OperationDetails;\r
37 import org.commscope.tr069adapter.acs.common.exception.TR069EventProcessingException;\r
38 import org.commscope.tr069adapter.acs.common.response.AddObjectResponse;\r
39 import org.commscope.tr069adapter.acs.common.response.DeleteObjectResponse;\r
40 import org.commscope.tr069adapter.acs.common.response.GetParameterValueResponse;\r
41 import org.commscope.tr069adapter.acs.common.response.SetParameterValueResponse;\r
42 import org.commscope.tr069adapter.acs.common.utils.ErrorCode;\r
43 import org.commscope.tr069adapter.acs.requestprocessor.dao.DeviceRPCRequestRepositoryHelper;\r
44 import org.commscope.tr069adapter.acs.requestprocessor.dto.CustomOperationData;\r
45 import org.commscope.tr069adapter.acs.requestprocessor.entity.TR069DeviceRPCRequestEntity;\r
46 import org.commscope.tr069adapter.acs.requestprocessor.impl.TR069RequestProcessEngine;\r
47 import org.commscope.tr069adapter.acs.requestprocessor.util.TR069RequestProcessorUtility;\r
48 import org.slf4j.Logger;\r
49 import org.slf4j.LoggerFactory;\r
50 import org.springframework.beans.factory.annotation.Autowired;\r
51 import org.springframework.stereotype.Component;\r
52 \r
53 @Component("ConfigureMultipleObject")\r
54 public class ConfigureMultipleObject implements CustomOperation {\r
55 \r
56   private static final Logger logger = LoggerFactory.getLogger(ConfigureMultipleObject.class);\r
57 \r
58   @Autowired\r
59   TR069RequestProcessEngine tr069ProcessEngine;\r
60 \r
61   @Autowired\r
62   protected DeviceRPCRequestRepositoryHelper deviceRPCRequestRepositoryHelper;\r
63 \r
64   public CustomOperationData executeCustomLogic(CustomOperationData customOperationData)\r
65       throws TR069EventProcessingException {\r
66 \r
67     TR069DeviceDetails deviceDetails = customOperationData.getDeviceDetails();\r
68     DeviceRPCResponse deviceRPCResponse = customOperationData.getDeviceRPCResponse();\r
69     DeviceRPCRequest nbiDeviceOperationRequest = customOperationData.getDeviceRPCRequest();\r
70 \r
71     logger.debug("Started processing Configure multiple object");\r
72     DeviceRPCRequest operRequest = null;\r
73     Long responseOperationId = null;\r
74     if (deviceRPCResponse != null && deviceRPCResponse.getOperationId() != null) {\r
75       responseOperationId = deviceRPCResponse.getOperationId();\r
76       if (deviceRPCResponse.getFaultKey() != null && responseOperationId != null\r
77           && responseOperationId.equals(nbiDeviceOperationRequest.getOperationId())) {\r
78         logger.error("The Configure Multiple Object operation has failed, Reason: {}",\r
79             deviceRPCResponse.getFaultString());\r
80 \r
81         logger.debug(\r
82             "Deleting the NBI operation request for custom operation configureMultipleObjects with operation ID: {}",\r
83             responseOperationId);\r
84         List<TR069DeviceRPCRequestEntity> tr069DeviceRPCRequestEntityList =\r
85             deviceRPCRequestRepositoryHelper\r
86                 .findByDeviceIdAndOperationId(deviceDetails.getDeviceId(), responseOperationId);\r
87         for (TR069DeviceRPCRequestEntity tr069DeviceRPCRequestEntity : tr069DeviceRPCRequestEntityList) {\r
88           tr069DeviceRPCRequestEntity.setIsProcessed(Integer.valueOf(1));\r
89         }\r
90         deviceRPCRequestRepositoryHelper.saveAll(tr069DeviceRPCRequestEntityList);\r
91 \r
92         OperationResponse operationResponse = new GetParameterValueResponse();\r
93         operationResponse.setParameterDTOs(new ArrayList<ParameterDTO>());\r
94         operationResponse.setStatus(1);\r
95         deviceRPCResponse.setOperationResponse(operationResponse);\r
96 \r
97         customOperationData.setDeviceRPCResponse(deviceRPCResponse);\r
98         customOperationData.setDeviceRPCRequest(null);\r
99         logger.debug("Finished processing Configure multiple object");\r
100         return customOperationData;\r
101       }\r
102     }\r
103 \r
104     TR069OperationDetails tr069OperationDetails =\r
105         (TR069OperationDetails) nbiDeviceOperationRequest.getOpDetails();\r
106     List<ParameterDTO> tr069deleteParamList = tr069OperationDetails.getDeleteParamList();\r
107     List<ParameterDTO> tr069modifyParamList = tr069OperationDetails.getModifyParamList();\r
108     List<ParameterDTO> tr069setParamList = tr069OperationDetails.getSetParamList();\r
109 \r
110     OperationOrder nextOperation = null;\r
111     boolean isPendingOperationExists = true;\r
112     final String NXT_OPERATION = "Next operation to be executed is : ";\r
113 \r
114     if ((responseOperationId == null) || (responseOperationId != null\r
115         && !responseOperationId.equals(nbiDeviceOperationRequest.getOperationId()))) {\r
116       // Must be called from Empty HTTP request, First operation to be called\r
117 \r
118       // Must be called from a different user operation, First operation to be called\r
119       // if response operation id is different from current\r
120       // nbiDevOperRequest operation id then first step is deleteObject\r
121 \r
122       nextOperation = OperationOrder.DELETE_OBJECT;\r
123       logger.debug(NXT_OPERATION, nextOperation);\r
124     } else {\r
125       // Since the responseOperation is not null and equivalent, find the\r
126       // response type and the take next action\r
127       OperationResponse opResponse = deviceRPCResponse.getOperationResponse();\r
128       if (opResponse instanceof DeleteObjectResponse) {\r
129         logger.debug("Received delete object response");\r
130         if (null != tr069deleteParamList && !tr069deleteParamList.isEmpty()) {\r
131           int i = 0;\r
132           for (ParameterDTO deleteParam : tr069deleteParamList) {\r
133             i++;\r
134             if (!deleteParam.isProcessed()) {\r
135               deleteParam.setProcessed(true);\r
136             } else {\r
137               continue;\r
138             }\r
139             logger.debug("Persisting the NBI request for deleteObject");\r
140             // Update the existing NBI request\r
141             List<TR069DeviceRPCRequestEntity> entityList =\r
142                 deviceRPCRequestRepositoryHelper.findByDeviceIdAndOperationId(\r
143                     deviceDetails.getDeviceId(), nbiDeviceOperationRequest.getOperationId());\r
144             List<TR069DeviceRPCRequestEntity> tr069DeviceRPCRequestEntityList =\r
145                 TR069RequestProcessorUtility.convertToEntity(nbiDeviceOperationRequest);\r
146             for (int j = 0; j < entityList.size(); j++) {\r
147               tr069DeviceRPCRequestEntityList.get(j).setId(entityList.get(j).getId());\r
148             }\r
149             deviceRPCRequestRepositoryHelper.saveAll(tr069DeviceRPCRequestEntityList);\r
150 \r
151             if (tr069deleteParamList.size() > i) {\r
152               nextOperation = OperationOrder.DELETE_OBJECT;\r
153               logger.debug(NXT_OPERATION, nextOperation);\r
154               break;\r
155             } else {\r
156               nextOperation = OperationOrder.ADD_OBJECT;\r
157               logger.debug(NXT_OPERATION, nextOperation);\r
158             }\r
159           }\r
160         } else {\r
161           nextOperation = OperationOrder.ADD_OBJECT;\r
162           logger.debug(NXT_OPERATION, nextOperation);\r
163         }\r
164       } else if (opResponse instanceof AddObjectResponse) {\r
165         logger.debug("Received Add object response");\r
166         if (null != tr069setParamList && !tr069setParamList.isEmpty()) {\r
167           long instanceNumber;\r
168           boolean addParamExist = false;\r
169           AddObjectResponse addObjResponse =\r
170               (AddObjectResponse) deviceRPCResponse.getOperationResponse();\r
171           List<ParameterDTO> modifyParamList = new ArrayList<>();\r
172           List<ParameterDTO> removeParamList = new ArrayList<>();\r
173           ParameterDTO addParam = null;\r
174 \r
175           if (null != addObjResponse) {\r
176             instanceNumber = addObjResponse.getInstanceNumber();\r
177             String replaceIndex = null;\r
178             String replaceParam = null;\r
179 \r
180             for (ParameterDTO setParam : tr069setParamList) {\r
181               if (!setParam.isProcessed()) {\r
182                 String paramName = setParam.getParamName();\r
183                 final Matcher matcher = Pattern.compile(NUMBER_REGEX).matcher(paramName);\r
184                 String index = null;\r
185                 String modifyParamName = null;\r
186                 String subString = null;\r
187                 while (matcher.find()) {\r
188                   index = matcher.group().substring(1, matcher.group().length() - 1);\r
189                   StringBuilder sb = new StringBuilder(paramName);\r
190                   int lastIndex = paramName.lastIndexOf(matcher.group());\r
191                   modifyParamName = (sb.replace(lastIndex, lastIndex + matcher.group().length(),\r
192                       "." + instanceNumber + ".")).toString();\r
193                   subString = paramName.substring(0, matcher.start()) + ".";\r
194                 }\r
195                 if (null == replaceIndex)\r
196                   replaceIndex = index;\r
197                 if (null == replaceParam)\r
198                   replaceParam = subString;\r
199                 if (null != replaceIndex && null != index && replaceIndex.equals(index)\r
200                     && replaceParam.equalsIgnoreCase(subString)) {\r
201                   setParam.setProcessed(true);\r
202                   modifyParamList.add(prepareParamDTO(modifyParamName, null, setParam));\r
203                   removeParamList.add(prepareParamDTO(null, null, setParam));\r
204                 } else {\r
205                   addParamExist = true;\r
206                 }\r
207                 if (null == addParam) {\r
208                   logger.debug(\r
209                       "The device index chosen is {} for adding the NBI tab parameter with index {}",\r
210                       instanceNumber, replaceIndex);\r
211                   addParam = prepareParamDTO(subString + replaceIndex,\r
212                       String.valueOf(instanceNumber), setParam);\r
213                 }\r
214               }\r
215             }\r
216           }\r
217           // Replace index with instance number and add in modify param list\r
218           if (!modifyParamList.isEmpty()) {\r
219             tr069modifyParamList.addAll(modifyParamList);\r
220           }\r
221           // Prepare add object param and add in set param list\r
222           if (null != addParam) {\r
223             addParam.setDataType("1");\r
224             tr069setParamList.add(addParam);\r
225           }\r
226           // Remove all processed set params from set param list\r
227           if (!removeParamList.isEmpty()) {\r
228             tr069setParamList.removeAll(removeParamList);\r
229           }\r
230 \r
231           logger.debug("Persisting the NBI request for addObject");\r
232           List<TR069DeviceRPCRequestEntity> entityList =\r
233               deviceRPCRequestRepositoryHelper.findByDeviceIdAndOperationId(\r
234                   deviceDetails.getDeviceId(), nbiDeviceOperationRequest.getOperationId());\r
235           List<TR069DeviceRPCRequestEntity> tr069DeviceRPCRequestEntityList =\r
236               TR069RequestProcessorUtility.convertToEntity(nbiDeviceOperationRequest);\r
237           for (int i = 0; i < entityList.size(); i++) {\r
238             tr069DeviceRPCRequestEntityList.get(i).setId(entityList.get(i).getId());\r
239           }\r
240           deviceRPCRequestRepositoryHelper.saveAll(tr069DeviceRPCRequestEntityList);\r
241 \r
242           if (addParamExist) {\r
243             nextOperation = OperationOrder.ADD_OBJECT;\r
244             logger.debug(NXT_OPERATION, nextOperation);\r
245           } else {\r
246             nextOperation = OperationOrder.SET_PARAMETER_VALUE;\r
247             logger.debug(NXT_OPERATION, nextOperation);\r
248           }\r
249         } else {\r
250           nextOperation = OperationOrder.SET_PARAMETER_VALUE;\r
251           logger.debug(NXT_OPERATION, nextOperation);\r
252         }\r
253       } else if (opResponse instanceof SetParameterValueResponse) {\r
254         logger.debug("Received Set parameter value response");\r
255         isPendingOperationExists = false;\r
256       }\r
257     }\r
258 \r
259     if (isPendingOperationExists) {\r
260       boolean checkForNextoperation = true;\r
261       while (checkForNextoperation) {\r
262         switch (nextOperation) {\r
263           case DELETE_OBJECT:\r
264             if (null != tr069deleteParamList && !tr069deleteParamList.isEmpty()) {\r
265               logger.debug("Started executing delete object request");\r
266               checkForNextoperation = false;\r
267               DeviceRPCRequest clonedOpRequest = cloneNBIRequest(nbiDeviceOperationRequest);\r
268               List<ParameterDTO> deleteParamList = new ArrayList<>();\r
269               // Just take the first not processed delete object from the list\r
270               for (ParameterDTO deleteParam : tr069deleteParamList) {\r
271                 if (!deleteParam.isProcessed()) {\r
272                   deleteParamList.add(deleteParam);\r
273                   break;\r
274                 }\r
275               }\r
276               clonedOpRequest.setOpDetails(null);\r
277               OperationDetails opDetails = new OperationDetails();\r
278               opDetails.setOpCode(TR069OperationCode.DELETE_OBJECT);\r
279               opDetails.setParmeters(deleteParamList);\r
280               clonedOpRequest.setOpDetails(opDetails);\r
281               operRequest = clonedOpRequest;\r
282             } else {\r
283               nextOperation = OperationOrder.ADD_OBJECT;\r
284               logger.debug(NXT_OPERATION, nextOperation);\r
285             }\r
286             break;\r
287           case ADD_OBJECT:\r
288             if (null != tr069setParamList && !tr069setParamList.isEmpty()) {\r
289               logger.debug("Started executing Add object request");\r
290               checkForNextoperation = false;\r
291               DeviceRPCRequest clonedOpRequest = cloneNBIRequest(nbiDeviceOperationRequest);\r
292               List<ParameterDTO> addParamList = new ArrayList<>();\r
293               // Just take the first not processed delete object from the list\r
294               for (ParameterDTO addParam : tr069setParamList) {\r
295                 if (!addParam.isProcessed()) {\r
296                   String addParamMO = null;\r
297                   final Matcher matcher =\r
298                       Pattern.compile(NUMBER_REGEX).matcher(addParam.getParamName());\r
299                   while (matcher.find()) {\r
300                     addParamMO = addParam.getParamName().substring(0, matcher.start()) + ".";\r
301                   }\r
302                   if (null != addParamMO) {\r
303                     addParamList.add(prepareParamDTO(addParamMO, null, addParam));\r
304                   }\r
305                   break;\r
306                 }\r
307               }\r
308               clonedOpRequest.setOpDetails(null);\r
309               OperationDetails opDetails = new OperationDetails();\r
310               opDetails.setOpCode(TR069OperationCode.ADD_OBJECT);\r
311               opDetails.setParmeters(addParamList);\r
312               clonedOpRequest.setOpDetails(opDetails);\r
313               operRequest = clonedOpRequest;\r
314             } else {\r
315               nextOperation = OperationOrder.SET_PARAMETER_VALUE;\r
316               logger.debug(NXT_OPERATION, nextOperation);\r
317             }\r
318             break;\r
319           case SET_PARAMETER_VALUE:\r
320             checkForNextoperation = false;\r
321             if (null != tr069modifyParamList && !tr069modifyParamList.isEmpty()) {\r
322               logger.debug("Started executing SPV request");\r
323               DeviceRPCRequest clonedOpRequest = cloneNBIRequest(nbiDeviceOperationRequest);\r
324               clonedOpRequest.setOpDetails(null);\r
325               OperationDetails opDetails = new OperationDetails();\r
326               opDetails.setOpCode(TR069OperationCode.SET_PARAMETER_VALUES);\r
327               opDetails.setParmeters(tr069modifyParamList);\r
328               clonedOpRequest.setOpDetails(opDetails);\r
329               operRequest = clonedOpRequest;\r
330             } else {\r
331               isPendingOperationExists = false;\r
332               operRequest = null;\r
333             }\r
334             break;\r
335           default:\r
336             isPendingOperationExists = false;\r
337             operRequest = null;\r
338         }\r
339       }\r
340     }\r
341 \r
342     if (!isPendingOperationExists) {\r
343       logger.debug(\r
344           "No pending operation exists, hence marking the operation as processed with id {} "\r
345               + "and sending GetParameterValueResponse for ConfigureMultipleObjects",\r
346           responseOperationId);\r
347       List<ParameterDTO> responseParamList = new ArrayList<>();\r
348 \r
349       if (tr069deleteParamList != null) {\r
350         for (ParameterDTO delete : tr069deleteParamList) {\r
351           delete.setParamValue(SUCCESS);\r
352           delete.setDataType("2");\r
353           responseParamList.add(delete);\r
354         }\r
355       }\r
356 \r
357       if (tr069modifyParamList != null) {\r
358         for (ParameterDTO modify : tr069modifyParamList) {\r
359           modify.setParamValue(SUCCESS);\r
360           modify.setDataType("4");\r
361           responseParamList.add(modify);\r
362         }\r
363       }\r
364 \r
365       responseParamList.addAll(tr069setParamList);\r
366 \r
367       OperationResponse operationResponse = new GetParameterValueResponse();\r
368       operationResponse.setParameterDTOs(responseParamList);\r
369       if (deviceRPCResponse != null) {\r
370         deviceRPCResponse.setDeviceDetails(deviceDetails);\r
371         deviceRPCResponse.setOperationResponse(operationResponse);\r
372         deviceRPCResponse.setOperationId(responseOperationId);\r
373       }\r
374 \r
375       logger.debug(\r
376           "Prepared operation result for custom operation Configure Multiple Objects, hence marking as processed the corresponding NBI Operation request record");\r
377       deviceRPCRequestRepositoryHelper.markDeviceRPCRequestAsProcessed(deviceDetails.getDeviceId(),\r
378           responseOperationId);\r
379     }\r
380 \r
381     customOperationData.setDeviceRPCResponse(deviceRPCResponse);\r
382     customOperationData.setDeviceRPCRequest(operRequest);\r
383     logger.debug("Finished processing Configure multiple object");\r
384     return customOperationData;\r
385   }\r
386 \r
387   enum OperationOrder {\r
388 \r
389     SET_PARAMETER_VALUE(null), ADD_OBJECT(SET_PARAMETER_VALUE), DELETE_OBJECT(ADD_OBJECT);\r
390 \r
391     OperationOrder nextOperation;\r
392 \r
393     OperationOrder(OperationOrder nextOperation) {\r
394       this.nextOperation = nextOperation;\r
395     }\r
396 \r
397     public OperationOrder getNextOperation() {\r
398       return nextOperation;\r
399     }\r
400 \r
401   }\r
402 \r
403   private DeviceRPCRequest cloneNBIRequest(DeviceRPCRequest nbiDeviceOperationRequest)\r
404       throws TR069EventProcessingException {\r
405     DeviceRPCRequest clonedOpRequest = null;\r
406     try {\r
407       clonedOpRequest = (DeviceRPCRequest) nbiDeviceOperationRequest.clone();\r
408     } catch (CloneNotSupportedException e) {\r
409       throw new TR069EventProcessingException(ErrorCode.UNKNOWN_ERROR, e.getMessage());\r
410     }\r
411 \r
412     return clonedOpRequest;\r
413   }\r
414 \r
415   private ParameterDTO prepareParamDTO(String name, String value, ParameterDTO paramDTO) {\r
416     ParameterDTO parameterDTO = new ParameterDTO();\r
417     if (null != name) {\r
418       parameterDTO.setParamName(name);\r
419     } else {\r
420       parameterDTO.setParamName(paramDTO.getParamName());\r
421     }\r
422     if (null != value) {\r
423       parameterDTO.setParamValue(value);\r
424     } else {\r
425       parameterDTO.setParamValue(paramDTO.getParamValue());\r
426     }\r
427     parameterDTO.setDataType(paramDTO.getDataType());\r
428     parameterDTO.setProcessed(paramDTO.isProcessed());\r
429 \r
430     return parameterDTO;\r
431   }\r
432 \r
433 }\r