--- /dev/null
+/*\r
+ * ============LICENSE_START========================================================================\r
+ * ONAP : tr-069-adapter\r
+ * =================================================================================================\r
+ * Copyright (C) 2020 CommScope Inc Intellectual Property.\r
+ * =================================================================================================\r
+ * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,\r
+ * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You\r
+ * may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r
+ * either express or implied. See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ===============LICENSE_END=======================================================================\r
+ */\r
+\r
+package org.commscope.tr069adapter.acs.requestprocessor.custom;\r
+\r
+import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.NUMBER_REGEX;\r
+import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.SUCCESS;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;\r
+import org.commscope.tr069adapter.acs.common.DeviceRPCResponse;\r
+import org.commscope.tr069adapter.acs.common.OperationDetails;\r
+import org.commscope.tr069adapter.acs.common.OperationResponse;\r
+import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
+import org.commscope.tr069adapter.acs.common.dto.TR069DeviceDetails;\r
+import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;\r
+import org.commscope.tr069adapter.acs.common.dto.TR069OperationDetails;\r
+import org.commscope.tr069adapter.acs.common.exception.TR069EventProcessingException;\r
+import org.commscope.tr069adapter.acs.common.response.AddObjectResponse;\r
+import org.commscope.tr069adapter.acs.common.response.DeleteObjectResponse;\r
+import org.commscope.tr069adapter.acs.common.response.GetParameterValueResponse;\r
+import org.commscope.tr069adapter.acs.common.response.SetParameterValueResponse;\r
+import org.commscope.tr069adapter.acs.common.utils.ErrorCode;\r
+import org.commscope.tr069adapter.acs.requestprocessor.dao.DeviceRPCRequestRepositoryHelper;\r
+import org.commscope.tr069adapter.acs.requestprocessor.dto.CustomOperationData;\r
+import org.commscope.tr069adapter.acs.requestprocessor.entity.TR069DeviceRPCRequestEntity;\r
+import org.commscope.tr069adapter.acs.requestprocessor.impl.TR069RequestProcessEngine;\r
+import org.commscope.tr069adapter.acs.requestprocessor.util.TR069RequestProcessorUtility;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.stereotype.Component;\r
+\r
+@Component("ConfigureMultipleObject")\r
+public class ConfigureMultipleObject implements CustomOperation {\r
+\r
+ private static final Logger logger = LoggerFactory.getLogger(ConfigureMultipleObject.class);\r
+\r
+ @Autowired\r
+ TR069RequestProcessEngine tr069ProcessEngine;\r
+\r
+ @Autowired\r
+ protected DeviceRPCRequestRepositoryHelper deviceRPCRequestRepositoryHelper;\r
+\r
+ public CustomOperationData executeCustomLogic(CustomOperationData customOperationData)\r
+ throws TR069EventProcessingException {\r
+\r
+ TR069DeviceDetails deviceDetails = customOperationData.getDeviceDetails();\r
+ DeviceRPCResponse deviceRPCResponse = customOperationData.getDeviceRPCResponse();\r
+ DeviceRPCRequest nbiDeviceOperationRequest = customOperationData.getDeviceRPCRequest();\r
+\r
+ logger.debug("Started processing Configure multiple object");\r
+ DeviceRPCRequest operRequest = null;\r
+ Long responseOperationId = null;\r
+ if (deviceRPCResponse != null && deviceRPCResponse.getOperationId() != null) {\r
+ responseOperationId = deviceRPCResponse.getOperationId();\r
+ if (deviceRPCResponse.getFaultKey() != null && responseOperationId != null\r
+ && responseOperationId.equals(nbiDeviceOperationRequest.getOperationId())) {\r
+ logger.error("The Configure Multiple Object operation has failed, Reason: {}",\r
+ deviceRPCResponse.getFaultString());\r
+\r
+ logger.debug(\r
+ "Deleting the NBI operation request for custom operation configureMultipleObjects with operation ID: {}",\r
+ responseOperationId);\r
+ List<TR069DeviceRPCRequestEntity> tr069DeviceRPCRequestEntityList =\r
+ deviceRPCRequestRepositoryHelper\r
+ .findByDeviceIdAndOperationId(deviceDetails.getDeviceId(), responseOperationId);\r
+ for (TR069DeviceRPCRequestEntity tr069DeviceRPCRequestEntity : tr069DeviceRPCRequestEntityList) {\r
+ tr069DeviceRPCRequestEntity.setIsProcessed(Integer.valueOf(1));\r
+ }\r
+ deviceRPCRequestRepositoryHelper.saveAll(tr069DeviceRPCRequestEntityList);\r
+\r
+ OperationResponse operationResponse = new GetParameterValueResponse();\r
+ operationResponse.setParameterDTOs(new ArrayList<ParameterDTO>());\r
+ operationResponse.setStatus(1);\r
+ deviceRPCResponse.setOperationResponse(operationResponse);\r
+\r
+ customOperationData.setDeviceRPCResponse(deviceRPCResponse);\r
+ customOperationData.setDeviceRPCRequest(null);\r
+ logger.debug("Finished processing Configure multiple object");\r
+ return customOperationData;\r
+ }\r
+ }\r
+\r
+ TR069OperationDetails tr069OperationDetails =\r
+ (TR069OperationDetails) nbiDeviceOperationRequest.getOpDetails();\r
+ List<ParameterDTO> tr069deleteParamList = tr069OperationDetails.getDeleteParamList();\r
+ List<ParameterDTO> tr069modifyParamList = tr069OperationDetails.getModifyParamList();\r
+ List<ParameterDTO> tr069setParamList = tr069OperationDetails.getSetParamList();\r
+\r
+ OperationOrder nextOperation = null;\r
+ boolean isPendingOperationExists = true;\r
+ final String NXT_OPERATION = "Next operation to be executed is : ";\r
+\r
+ if ((responseOperationId == null) || (responseOperationId != null\r
+ && !responseOperationId.equals(nbiDeviceOperationRequest.getOperationId()))) {\r
+ // Must be called from Empty HTTP request, First operation to be called\r
+\r
+ // Must be called from a different user operation, First operation to be called\r
+ // if response operation id is different from current\r
+ // nbiDevOperRequest operation id then first step is deleteObject\r
+\r
+ nextOperation = OperationOrder.DELETE_OBJECT;\r
+ logger.debug(NXT_OPERATION, nextOperation);\r
+ } else {\r
+ // Since the responseOperation is not null and equivalent, find the\r
+ // response type and the take next action\r
+ OperationResponse opResponse = deviceRPCResponse.getOperationResponse();\r
+ if (opResponse instanceof DeleteObjectResponse) {\r
+ logger.debug("Received delete object response");\r
+ if (null != tr069deleteParamList && !tr069deleteParamList.isEmpty()) {\r
+ int i = 0;\r
+ for (ParameterDTO deleteParam : tr069deleteParamList) {\r
+ i++;\r
+ if (!deleteParam.isProcessed()) {\r
+ deleteParam.setProcessed(true);\r
+ } else {\r
+ continue;\r
+ }\r
+ logger.debug("Persisting the NBI request for deleteObject");\r
+ // Update the existing NBI request\r
+ List<TR069DeviceRPCRequestEntity> entityList =\r
+ deviceRPCRequestRepositoryHelper.findByDeviceIdAndOperationId(\r
+ deviceDetails.getDeviceId(), nbiDeviceOperationRequest.getOperationId());\r
+ List<TR069DeviceRPCRequestEntity> tr069DeviceRPCRequestEntityList =\r
+ TR069RequestProcessorUtility.convertToEntity(nbiDeviceOperationRequest);\r
+ for (int j = 0; j < entityList.size(); j++) {\r
+ tr069DeviceRPCRequestEntityList.get(j).setId(entityList.get(j).getId());\r
+ }\r
+ deviceRPCRequestRepositoryHelper.saveAll(tr069DeviceRPCRequestEntityList);\r
+\r
+ if (tr069deleteParamList.size() > i) {\r
+ nextOperation = OperationOrder.DELETE_OBJECT;\r
+ logger.debug(NXT_OPERATION, nextOperation);\r
+ break;\r
+ } else {\r
+ nextOperation = OperationOrder.ADD_OBJECT;\r
+ logger.debug(NXT_OPERATION, nextOperation);\r
+ }\r
+ }\r
+ } else {\r
+ nextOperation = OperationOrder.ADD_OBJECT;\r
+ logger.debug(NXT_OPERATION, nextOperation);\r
+ }\r
+ } else if (opResponse instanceof AddObjectResponse) {\r
+ logger.debug("Received Add object response");\r
+ if (null != tr069setParamList && !tr069setParamList.isEmpty()) {\r
+ long instanceNumber;\r
+ boolean addParamExist = false;\r
+ AddObjectResponse addObjResponse =\r
+ (AddObjectResponse) deviceRPCResponse.getOperationResponse();\r
+ List<ParameterDTO> modifyParamList = new ArrayList<>();\r
+ List<ParameterDTO> removeParamList = new ArrayList<>();\r
+ ParameterDTO addParam = null;\r
+\r
+ if (null != addObjResponse) {\r
+ instanceNumber = addObjResponse.getInstanceNumber();\r
+ String replaceIndex = null;\r
+ String replaceParam = null;\r
+\r
+ for (ParameterDTO setParam : tr069setParamList) {\r
+ if (!setParam.isProcessed()) {\r
+ String paramName = setParam.getParamName();\r
+ final Matcher matcher = Pattern.compile(NUMBER_REGEX).matcher(paramName);\r
+ String index = null;\r
+ String modifyParamName = null;\r
+ String subString = null;\r
+ while (matcher.find()) {\r
+ index = matcher.group().substring(1, matcher.group().length() - 1);\r
+ StringBuilder sb = new StringBuilder(paramName);\r
+ int lastIndex = paramName.lastIndexOf(matcher.group());\r
+ modifyParamName = (sb.replace(lastIndex, lastIndex + matcher.group().length(),\r
+ "." + instanceNumber + ".")).toString();\r
+ subString = paramName.substring(0, matcher.start()) + ".";\r
+ }\r
+ if (null == replaceIndex)\r
+ replaceIndex = index;\r
+ if (null == replaceParam)\r
+ replaceParam = subString;\r
+ if (null != replaceIndex && null != index && replaceIndex.equals(index)\r
+ && replaceParam.equalsIgnoreCase(subString)) {\r
+ setParam.setProcessed(true);\r
+ modifyParamList.add(prepareParamDTO(modifyParamName, null, setParam));\r
+ removeParamList.add(prepareParamDTO(null, null, setParam));\r
+ } else {\r
+ addParamExist = true;\r
+ }\r
+ if (null == addParam) {\r
+ logger.debug(\r
+ "The device index chosen is {} for adding the NBI tab parameter with index {}",\r
+ instanceNumber, replaceIndex);\r
+ addParam = prepareParamDTO(subString + replaceIndex,\r
+ String.valueOf(instanceNumber), setParam);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ // Replace index with instance number and add in modify param list\r
+ if (!modifyParamList.isEmpty()) {\r
+ tr069modifyParamList.addAll(modifyParamList);\r
+ }\r
+ // Prepare add object param and add in set param list\r
+ if (null != addParam) {\r
+ addParam.setDataType("1");\r
+ tr069setParamList.add(addParam);\r
+ }\r
+ // Remove all processed set params from set param list\r
+ if (!removeParamList.isEmpty()) {\r
+ tr069setParamList.removeAll(removeParamList);\r
+ }\r
+\r
+ logger.debug("Persisting the NBI request for addObject");\r
+ List<TR069DeviceRPCRequestEntity> entityList =\r
+ deviceRPCRequestRepositoryHelper.findByDeviceIdAndOperationId(\r
+ deviceDetails.getDeviceId(), nbiDeviceOperationRequest.getOperationId());\r
+ List<TR069DeviceRPCRequestEntity> tr069DeviceRPCRequestEntityList =\r
+ TR069RequestProcessorUtility.convertToEntity(nbiDeviceOperationRequest);\r
+ for (int i = 0; i < entityList.size(); i++) {\r
+ tr069DeviceRPCRequestEntityList.get(i).setId(entityList.get(i).getId());\r
+ }\r
+ deviceRPCRequestRepositoryHelper.saveAll(tr069DeviceRPCRequestEntityList);\r
+\r
+ if (addParamExist) {\r
+ nextOperation = OperationOrder.ADD_OBJECT;\r
+ logger.debug(NXT_OPERATION, nextOperation);\r
+ } else {\r
+ nextOperation = OperationOrder.SET_PARAMETER_VALUE;\r
+ logger.debug(NXT_OPERATION, nextOperation);\r
+ }\r
+ } else {\r
+ nextOperation = OperationOrder.SET_PARAMETER_VALUE;\r
+ logger.debug(NXT_OPERATION, nextOperation);\r
+ }\r
+ } else if (opResponse instanceof SetParameterValueResponse) {\r
+ logger.debug("Received Set parameter value response");\r
+ isPendingOperationExists = false;\r
+ }\r
+ }\r
+\r
+ if (isPendingOperationExists) {\r
+ boolean checkForNextoperation = true;\r
+ while (checkForNextoperation) {\r
+ switch (nextOperation) {\r
+ case DELETE_OBJECT:\r
+ if (null != tr069deleteParamList && !tr069deleteParamList.isEmpty()) {\r
+ logger.debug("Started executing delete object request");\r
+ checkForNextoperation = false;\r
+ DeviceRPCRequest clonedOpRequest = cloneNBIRequest(nbiDeviceOperationRequest);\r
+ List<ParameterDTO> deleteParamList = new ArrayList<>();\r
+ // Just take the first not processed delete object from the list\r
+ for (ParameterDTO deleteParam : tr069deleteParamList) {\r
+ if (!deleteParam.isProcessed()) {\r
+ deleteParamList.add(deleteParam);\r
+ break;\r
+ }\r
+ }\r
+ clonedOpRequest.setOpDetails(null);\r
+ OperationDetails opDetails = new OperationDetails();\r
+ opDetails.setOpCode(TR069OperationCode.DELETE_OBJECT);\r
+ opDetails.setParmeters(deleteParamList);\r
+ clonedOpRequest.setOpDetails(opDetails);\r
+ operRequest = clonedOpRequest;\r
+ } else {\r
+ nextOperation = OperationOrder.ADD_OBJECT;\r
+ logger.debug(NXT_OPERATION, nextOperation);\r
+ }\r
+ break;\r
+ case ADD_OBJECT:\r
+ if (null != tr069setParamList && !tr069setParamList.isEmpty()) {\r
+ logger.debug("Started executing Add object request");\r
+ checkForNextoperation = false;\r
+ DeviceRPCRequest clonedOpRequest = cloneNBIRequest(nbiDeviceOperationRequest);\r
+ List<ParameterDTO> addParamList = new ArrayList<>();\r
+ // Just take the first not processed delete object from the list\r
+ for (ParameterDTO addParam : tr069setParamList) {\r
+ if (!addParam.isProcessed()) {\r
+ String addParamMO = null;\r
+ final Matcher matcher =\r
+ Pattern.compile(NUMBER_REGEX).matcher(addParam.getParamName());\r
+ while (matcher.find()) {\r
+ addParamMO = addParam.getParamName().substring(0, matcher.start()) + ".";\r
+ }\r
+ if (null != addParamMO) {\r
+ addParamList.add(prepareParamDTO(addParamMO, null, addParam));\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ clonedOpRequest.setOpDetails(null);\r
+ OperationDetails opDetails = new OperationDetails();\r
+ opDetails.setOpCode(TR069OperationCode.ADD_OBJECT);\r
+ opDetails.setParmeters(addParamList);\r
+ clonedOpRequest.setOpDetails(opDetails);\r
+ operRequest = clonedOpRequest;\r
+ } else {\r
+ nextOperation = OperationOrder.SET_PARAMETER_VALUE;\r
+ logger.debug(NXT_OPERATION, nextOperation);\r
+ }\r
+ break;\r
+ case SET_PARAMETER_VALUE:\r
+ checkForNextoperation = false;\r
+ if (null != tr069modifyParamList && !tr069modifyParamList.isEmpty()) {\r
+ logger.debug("Started executing SPV request");\r
+ DeviceRPCRequest clonedOpRequest = cloneNBIRequest(nbiDeviceOperationRequest);\r
+ clonedOpRequest.setOpDetails(null);\r
+ OperationDetails opDetails = new OperationDetails();\r
+ opDetails.setOpCode(TR069OperationCode.SET_PARAMETER_VALUES);\r
+ opDetails.setParmeters(tr069modifyParamList);\r
+ clonedOpRequest.setOpDetails(opDetails);\r
+ operRequest = clonedOpRequest;\r
+ } else {\r
+ isPendingOperationExists = false;\r
+ operRequest = null;\r
+ }\r
+ break;\r
+ default:\r
+ isPendingOperationExists = false;\r
+ operRequest = null;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!isPendingOperationExists) {\r
+ logger.debug(\r
+ "No pending operation exists, hence marking the operation as processed with id {} "\r
+ + "and sending GetParameterValueResponse for ConfigureMultipleObjects",\r
+ responseOperationId);\r
+ List<ParameterDTO> responseParamList = new ArrayList<>();\r
+\r
+ if (tr069deleteParamList != null) {\r
+ for (ParameterDTO delete : tr069deleteParamList) {\r
+ delete.setParamValue(SUCCESS);\r
+ delete.setDataType("2");\r
+ responseParamList.add(delete);\r
+ }\r
+ }\r
+\r
+ if (tr069modifyParamList != null) {\r
+ for (ParameterDTO modify : tr069modifyParamList) {\r
+ modify.setParamValue(SUCCESS);\r
+ modify.setDataType("4");\r
+ responseParamList.add(modify);\r
+ }\r
+ }\r
+\r
+ responseParamList.addAll(tr069setParamList);\r
+\r
+ OperationResponse operationResponse = new GetParameterValueResponse();\r
+ operationResponse.setParameterDTOs(responseParamList);\r
+ if (deviceRPCResponse != null) {\r
+ deviceRPCResponse.setDeviceDetails(deviceDetails);\r
+ deviceRPCResponse.setOperationResponse(operationResponse);\r
+ deviceRPCResponse.setOperationId(responseOperationId);\r
+ }\r
+\r
+ logger.debug(\r
+ "Prepared operation result for custom operation Configure Multiple Objects, hence marking as processed the corresponding NBI Operation request record");\r
+ deviceRPCRequestRepositoryHelper.markDeviceRPCRequestAsProcessed(deviceDetails.getDeviceId(),\r
+ responseOperationId);\r
+ }\r
+\r
+ customOperationData.setDeviceRPCResponse(deviceRPCResponse);\r
+ customOperationData.setDeviceRPCRequest(operRequest);\r
+ logger.debug("Finished processing Configure multiple object");\r
+ return customOperationData;\r
+ }\r
+\r
+ enum OperationOrder {\r
+\r
+ SET_PARAMETER_VALUE(null), ADD_OBJECT(SET_PARAMETER_VALUE), DELETE_OBJECT(ADD_OBJECT);\r
+\r
+ OperationOrder nextOperation;\r
+\r
+ OperationOrder(OperationOrder nextOperation) {\r
+ this.nextOperation = nextOperation;\r
+ }\r
+\r
+ public OperationOrder getNextOperation() {\r
+ return nextOperation;\r
+ }\r
+\r
+ }\r
+\r
+ private DeviceRPCRequest cloneNBIRequest(DeviceRPCRequest nbiDeviceOperationRequest)\r
+ throws TR069EventProcessingException {\r
+ DeviceRPCRequest clonedOpRequest = null;\r
+ try {\r
+ clonedOpRequest = (DeviceRPCRequest) nbiDeviceOperationRequest.clone();\r
+ } catch (CloneNotSupportedException e) {\r
+ throw new TR069EventProcessingException(ErrorCode.UNKNOWN_ERROR, e.getMessage());\r
+ }\r
+\r
+ return clonedOpRequest;\r
+ }\r
+\r
+ private ParameterDTO prepareParamDTO(String name, String value, ParameterDTO paramDTO) {\r
+ ParameterDTO parameterDTO = new ParameterDTO();\r
+ if (null != name) {\r
+ parameterDTO.setParamName(name);\r
+ } else {\r
+ parameterDTO.setParamName(paramDTO.getParamName());\r
+ }\r
+ if (null != value) {\r
+ parameterDTO.setParamValue(value);\r
+ } else {\r
+ parameterDTO.setParamValue(paramDTO.getParamValue());\r
+ }\r
+ parameterDTO.setDataType(paramDTO.getDataType());\r
+ parameterDTO.setProcessed(paramDTO.isProcessed());\r
+\r
+ return parameterDTO;\r
+ }\r
+\r
+}\r