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