Initial source code
[oam/tr069-adapter.git] / acs / cpe / src / main / java / org / commscope / tr069adapter / acs / cpe / handler / DeviceEventHandler.java
diff --git a/acs/cpe/src/main/java/org/commscope/tr069adapter/acs/cpe/handler/DeviceEventHandler.java b/acs/cpe/src/main/java/org/commscope/tr069adapter/acs/cpe/handler/DeviceEventHandler.java
new file mode 100644 (file)
index 0000000..4597cbb
--- /dev/null
@@ -0,0 +1,423 @@
+/*\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.cpe.handler;\r
+\r
+import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.CONNECTION_REQUEST;\r
+import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.SEPERATOR;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import javax.servlet.http.HttpServletResponse;\r
+\r
+import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;\r
+import org.commscope.tr069adapter.acs.common.DeviceRPCResponse;\r
+import org.commscope.tr069adapter.acs.common.OperationResponse;\r
+import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
+import org.commscope.tr069adapter.acs.common.dto.DeviceOperationRequestDetails;\r
+import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;\r
+import org.commscope.tr069adapter.acs.common.exception.SessionManagerException;\r
+import org.commscope.tr069adapter.acs.common.exception.TR069EventProcessingException;\r
+import org.commscope.tr069adapter.acs.common.inform.AbstractDeviceInform;\r
+import org.commscope.tr069adapter.acs.common.inform.TransferCompleteInform;\r
+import org.commscope.tr069adapter.acs.common.requestprocessor.service.TR069DeviceEventHandler;\r
+import org.commscope.tr069adapter.acs.common.response.DeviceInformResponse;\r
+import org.commscope.tr069adapter.acs.common.utils.ErrorCode;\r
+import org.commscope.tr069adapter.acs.cpe.TR069RPC;\r
+import org.commscope.tr069adapter.acs.cpe.builder.DeviceInformBuilder;\r
+import org.commscope.tr069adapter.acs.cpe.builder.DeviceRPCBuilder;\r
+import org.commscope.tr069adapter.acs.cpe.builder.DeviceRPCResponseBuilder;\r
+import org.commscope.tr069adapter.acs.cpe.rpc.Fault;\r
+import org.commscope.tr069adapter.acs.cpe.rpc.Inform;\r
+import org.commscope.tr069adapter.acs.cpe.rpc.TransferComplete;\r
+import org.commscope.tr069adapter.common.timer.TimerException;\r
+import org.commscope.tr069adapter.common.timer.TimerServiceManagerAPI;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.slf4j.MDC;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.stereotype.Component;\r
+\r
+@Component\r
+public class DeviceEventHandler {\r
+\r
+  private static final Logger logger = LoggerFactory.getLogger(DeviceEventHandler.class);\r
+\r
+  private static final String CLIENT_STR = "client";\r
+\r
+  @Autowired\r
+  private DeviceInformBuilder deviceInformBuilder;\r
+\r
+  @Autowired\r
+  private DeviceRPCBuilder deviceRPCBuilder;\r
+\r
+  @Autowired\r
+  private DeviceRPCResponseBuilder deviceRPCResponseBuilder;\r
+\r
+  @Autowired\r
+  private TR069DeviceEventHandler tr069DeviceEventHandler;\r
+\r
+  @Autowired\r
+  private TimerServiceManagerAPI timerServiceManagerAPI;\r
+\r
+  @Autowired\r
+  private DeviceValidator deviceValidtor;\r
+\r
+  private static Map<String, List<String>> informParameter = null;\r
+\r
+  static {\r
+    informParameter = new HashMap<>();\r
+    List<String> parameters = new ArrayList<>();\r
+    parameters.add("InternetGatewayDevice.DeviceInfo.HardwareVersion");\r
+    parameters.add("InternetGatewayDevice.DeviceInfo.SoftwareVersion");\r
+    parameters.add("InternetGatewayDevice.DeviceInfo.ProvisioningCode");\r
+    parameters.add("InternetGatewayDevice.ManagementServer.ConnectionRequestURL");\r
+    parameters.add("InternetGatewayDevice.ManagementServer.ParameterKey");\r
+    informParameter.put("InternetGatewayDevice", parameters);\r
+\r
+    List<String> deviceParameters = new ArrayList<>();\r
+    deviceParameters.add("Device.DeviceInfo.HardwareVersion");\r
+    deviceParameters.add("Device.DeviceInfo.SoftwareVersion");\r
+    deviceParameters.add("Device.DeviceInfo.ProvisioningCode");\r
+    deviceParameters.add("Device.ManagementServer.ConnectionRequestURL");\r
+    deviceParameters.add("Device.ManagementServer.ParameterKey");\r
+    informParameter.put("Device", deviceParameters);\r
+  }\r
+\r
+  /**\r
+   * @param inform\r
+   * @param authorizationHeader\r
+   * @return\r
+   * @throws TR069EventProcessingException\r
+   */\r
+  public DeviceInformResponse processDeviceInform(Inform inform, String authorizationHeader)\r
+      throws TR069EventProcessingException {\r
+\r
+    DeviceInformResponse deviceInformResponse = null;\r
+    try {\r
+      String deviceId = inform.getSn();\r
+      MDC.put(CLIENT_STR, deviceId);\r
+\r
+      logger.info("Processing the device Inform event");\r
+\r
+      logger.debug("Authorization header received in the request -> {}", authorizationHeader);\r
+      Boolean isAuthorized = deviceValidtor.isDeviceAuthorized(inform, authorizationHeader);\r
+      logger.info("Is device authentication successful: {}", isAuthorized);\r
+      if (!isAuthorized.booleanValue()) {\r
+        TR069EventProcessingException ex =\r
+            new TR069EventProcessingException(ErrorCode.UNAUTHORIZED_EVENT, "Authorization failed");\r
+        logger.error(ex.getMessage());\r
+        throw ex;\r
+      }\r
+\r
+      logger.debug("The root element is: {}", inform.getRoot());\r
+      // Canceling any connection initiator timer running, due to inform event\r
+      stopConnectionInitiatorTimer(inform.getSn());\r
+\r
+      if (!deviceValidtor.validateDevice(inform.getSn(), inform.getOui(), inform.getProductClass())\r
+          .booleanValue()) {\r
+        TR069EventProcessingException ex =\r
+            new TR069EventProcessingException(ErrorCode.OUI_OR_PC_MISMATCH);\r
+        logger.error(ex.getMessage());\r
+        throw ex;\r
+      }\r
+\r
+      if (!validateInformParameters(inform)) {\r
+        TR069EventProcessingException ex =\r
+            new TR069EventProcessingException(ErrorCode.INVALID_PARAMS_IN_INFORM);\r
+        logger.error(ex.getMessage());\r
+        throw ex;\r
+      }\r
+\r
+      AbstractDeviceInform deviceInform = deviceInformBuilder.constructDeviceInform(inform);\r
+      if (deviceInform == null) {\r
+        TR069EventProcessingException ex =\r
+            new TR069EventProcessingException(ErrorCode.INVALID_PARAMS_IN_INFORM);\r
+        logger.error(ex.getMessage());\r
+        throw ex;\r
+      }\r
+\r
+      logger.debug("Sending the device inform to TR069 Request Processor to process");\r
+      deviceInformResponse = tr069DeviceEventHandler.processDeviceInform(deviceInform);\r
+\r
+    } catch (TR069EventProcessingException tr069Ex) {\r
+      throw tr069Ex;\r
+    } catch (Exception e) {\r
+      TR069EventProcessingException ex =\r
+          new TR069EventProcessingException(ErrorCode.FAILED_PROCESSING_INFORM, e.getMessage());\r
+      logger.error(ex.getMessage());\r
+      throw ex;\r
+    } finally {\r
+      MDC.remove(CLIENT_STR);\r
+    }\r
+\r
+    return deviceInformResponse;\r
+\r
+  }\r
+\r
+  /**\r
+   * @param tc\r
+   * @return\r
+   * @throws TR069EventProcessingException\r
+   */\r
+  public DeviceInformResponse processTransferComplete(TransferComplete tc)\r
+      throws TR069EventProcessingException {\r
+\r
+    logger.debug("Processing Transfer Complete");\r
+\r
+    String startTime = tc.getStartTime();\r
+    String completeTime = tc.getCompleteTime();\r
+    int faultCode = tc.getFaultCode();\r
+    String faultString = tc.getFaultString();\r
+    String commandKey = tc.getCommandKey();\r
+\r
+    DeviceInformResponse deviceInformResponse = null;\r
+\r
+    try {\r
+      MDC.put(CLIENT_STR, commandKey);\r
+      TransferCompleteInform transferCompleteInform = new TransferCompleteInform();\r
+      transferCompleteInform.setCommandKey(tc.getCommandKey());\r
+      transferCompleteInform.setCompleteTime(completeTime);\r
+      transferCompleteInform.setFaultCode(faultCode);\r
+      transferCompleteInform.setFaultString(faultString);\r
+      transferCompleteInform.setStartTime(startTime);\r
+\r
+      logger.debug("TransferComplete inform received with Start time");\r
+\r
+      transferCompleteInform.setDeviceDetails(tr069DeviceEventHandler.getDeviceDetails(commandKey));\r
+      deviceInformResponse = tr069DeviceEventHandler.processDeviceInform(transferCompleteInform);\r
+      logger.debug("Successfully processed the TRANSFER COMPLETE Inform");\r
+\r
+    } catch (Exception e) {\r
+      throw new TR069EventProcessingException(ErrorCode.FAILED_PROCESSING_INFORM, e.getMessage());\r
+    } finally {\r
+      MDC.remove(CLIENT_STR);\r
+    }\r
+\r
+    return deviceInformResponse;\r
+  }\r
+\r
+  /**\r
+   * @param msg\r
+   * @param sessionId\r
+   * @return\r
+   * @throws TR069EventProcessingException\r
+   */\r
+  public TR069RPC processRPCResponse(TR069RPC msg, String sessionId)\r
+      throws TR069EventProcessingException {\r
+    DeviceOperationRequestDetails deviceOperationRequestDetails = null;\r
+    try {\r
+      deviceOperationRequestDetails =\r
+          tr069DeviceEventHandler.getOpRequestDetailsBySessionId(sessionId);\r
+      if (null == deviceOperationRequestDetails\r
+          || null == deviceOperationRequestDetails.getDeviceDetails()) {\r
+        logger.error("Response with invalid session ID: {}", sessionId);\r
+        return null;\r
+      }\r
+\r
+      String deviceId = deviceOperationRequestDetails.getDeviceDetails().getDeviceId();\r
+      MDC.put(CLIENT_STR, deviceId);\r
+      DeviceRPCResponse deviceRPCResponse = new DeviceRPCResponse();\r
+      deviceRPCResponse.setDeviceDetails(deviceOperationRequestDetails.getDeviceDetails());\r
+      deviceRPCResponse.setOperationId(deviceOperationRequestDetails.getOperationId());\r
+      OperationResponse operationResponse = null;\r
+      if (msg instanceof Fault) {\r
+        Fault values = (Fault) msg;\r
+        logger.info("{} ID->{} faultCode->{} faultString->{}", values.getName(), values.getId(),\r
+            values.getCwmpFaultCode(), values.getFaultStringCwmp());\r
+        deviceRPCResponse.setFaultKey(values.getCwmpFaultCode());\r
+        deviceRPCResponse.setFaultString(\r
+            values.getFaultStringCwmp() + ": Error code: " + values.getCwmpFaultCode());\r
+\r
+        TR069OperationCode operationCode =\r
+            (TR069OperationCode) deviceOperationRequestDetails.getOpCode();\r
+        operationResponse = constructResponseForFault(operationCode);\r
+        if (operationResponse != null) {\r
+          operationResponse.setStatus(1);\r
+          operationResponse.setParameterDTOs(new ArrayList<ParameterDTO>());\r
+        }\r
+      } else {\r
+        operationResponse = deviceRPCResponseBuilder.constructDeviceRPCResponse(msg);\r
+      }\r
+      deviceRPCResponse.setOperationResponse(operationResponse);\r
+\r
+      DeviceRPCRequest deviceRPCRequest =\r
+          tr069DeviceEventHandler.processDeviceRPCResponse(deviceRPCResponse);\r
+      if (null != deviceRPCRequest) {\r
+        return deviceRPCBuilder.constructDeviceRPC(deviceRPCRequest);\r
+      }\r
+    } catch (SessionManagerException e) {\r
+      logger.error("Error while getting device detail for the session id: {}", sessionId);\r
+    } catch (Exception e) {\r
+      throw new TR069EventProcessingException(ErrorCode.FAILED_PROCESSING_RPC_RESPONSE,\r
+          msg.getName(), e.getMessage());\r
+    } finally {\r
+      MDC.remove(CLIENT_STR);\r
+    }\r
+\r
+    return null;\r
+  }\r
+\r
+  /**\r
+   * @param sessionId\r
+   * @return\r
+   * @throws TR069EventProcessingException\r
+   */\r
+  public TR069RPC processEmptyRequest(String sessionId) throws TR069EventProcessingException {\r
+    try {\r
+      DeviceOperationRequestDetails deviceOperationRequestDetails =\r
+          tr069DeviceEventHandler.getOpRequestDetailsBySessionId(sessionId);\r
+      DeviceRPCRequest deviceRPCRequest = null;\r
+      String deviceId = deviceOperationRequestDetails.getDeviceDetails().getDeviceId();\r
+      MDC.put(CLIENT_STR, deviceId);\r
+      deviceRPCRequest = tr069DeviceEventHandler\r
+          .processEmptyDeviceRequest(deviceOperationRequestDetails.getDeviceDetails());\r
+      if (null == deviceRPCRequest) {\r
+        return null;\r
+      } else {\r
+        logger.debug("There exists a NBI request to process.");\r
+        return deviceRPCBuilder.constructDeviceRPC(deviceRPCRequest);\r
+      }\r
+    } catch (SessionManagerException e) {\r
+      logger.error("Error while processing empty request, reason: {}", e.getMessage());\r
+    } catch (Exception e) {\r
+      throw new TR069EventProcessingException(ErrorCode.EMPTY_REQUEST_PROCESSING_ERROR,\r
+          e.getMessage());\r
+    } finally {\r
+      MDC.remove(CLIENT_STR);\r
+    }\r
+    return null;\r
+  }\r
+\r
+  /**\r
+   * @param operationCode\r
+   * @return\r
+   */\r
+  private OperationResponse constructResponseForFault(TR069OperationCode operationCode) {\r
+    OperationResponse operationResponse = null;\r
+    if (operationCode.equals(TR069OperationCode.ADD_OBJECT)) {\r
+      operationResponse = new org.commscope.tr069adapter.acs.common.response.AddObjectResponse();\r
+    } else if (operationCode.equals(TR069OperationCode.DELETE_OBJECT)) {\r
+      operationResponse = new org.commscope.tr069adapter.acs.common.response.DeleteObjectResponse();\r
+    } else if (operationCode.equals(TR069OperationCode.SET_PARAMETER_VALUES)) {\r
+      operationResponse =\r
+          new org.commscope.tr069adapter.acs.common.response.SetParameterValueResponse();\r
+    } else if (operationCode.equals(TR069OperationCode.GET_PARAMETER_VALUES)) {\r
+      operationResponse =\r
+          new org.commscope.tr069adapter.acs.common.response.GetParameterValueResponse();\r
+    } else if (operationCode.equals(TR069OperationCode.GET_PARAMETER_ATTRIBUTES)) {\r
+      operationResponse =\r
+          new org.commscope.tr069adapter.acs.common.response.GetParameterAttributeResponse();\r
+    }\r
+    return operationResponse;\r
+  }\r
+\r
+  /**\r
+   * @param serialNumber\r
+   */\r
+  public void stopConnectionInitiatorTimer(String serialNumber) {\r
+    String timerId = serialNumber + SEPERATOR + CONNECTION_REQUEST;\r
+    try {\r
+      logger\r
+          .debug("Canceling the Connection initiation timer, as Inform is been sent by the device");\r
+      timerServiceManagerAPI.stopTimer(timerId);\r
+    } catch (TimerException e) {\r
+      logger.error(\r
+          "An exception occurred while stopping the connection initiator session timer, Reason: {}",\r
+          e.getMessage());\r
+    }\r
+  }\r
+\r
+  /**\r
+   * @param lastInform\r
+   * @return\r
+   */\r
+  private boolean validateInformParameters(Inform lastInform) {\r
+    boolean validate = false;\r
+    String root = lastInform.getRoot();\r
+    if (!informParameter.containsKey(root))\r
+      return validate;\r
+    List<String> params = informParameter.get(root);\r
+    Set<String> keySet = lastInform.getParams().keySet();\r
+    validate = true;\r
+    for (String param : params) {\r
+      if (!keySet.contains(param)) {\r
+        logger.warn("This param Not found in the inform {}", param);\r
+        validate = false;\r
+        break;\r
+      }\r
+    }\r
+    return validate;\r
+  }\r
+\r
+  /**\r
+   * @param tr069ex\r
+   * @return\r
+   */\r
+  public int handleException(TR069EventProcessingException tr069ex) {\r
+\r
+    int errorresponseCode = 0;\r
+\r
+    ErrorCode errorCode = tr069ex.getErrorCode();\r
+    switch (errorCode) {\r
+      case UNSUPPORTED_CHARACTER_ENCODING:\r
+      case INVALID_PARAMS_IN_INFORM:\r
+      case FAILED_PROCESSING_INFORM:\r
+        errorresponseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;\r
+        break;\r
+      case UNAUTHORIZED_EVENT:\r
+        errorresponseCode = HttpServletResponse.SC_UNAUTHORIZED;\r
+        break;\r
+      default:\r
+        break;\r
+    }\r
+\r
+    return errorresponseCode;\r
+  }\r
+\r
+  /***************************************************************************************************************************/\r
+\r
+  public void setDeviceInformBuilder(DeviceInformBuilder deviceInformBuilder) {\r
+    this.deviceInformBuilder = deviceInformBuilder;\r
+  }\r
+\r
+  public void setDeviceRPCBuilder(DeviceRPCBuilder deviceRPCBuilder) {\r
+    this.deviceRPCBuilder = deviceRPCBuilder;\r
+  }\r
+\r
+  public void setDeviceRPCResponseBuilder(DeviceRPCResponseBuilder deviceRPCResponseBuilder) {\r
+    this.deviceRPCResponseBuilder = deviceRPCResponseBuilder;\r
+  }\r
+\r
+  public void setTr069DeviceEventHandler(TR069DeviceEventHandler tr069DeviceEventHandler) {\r
+    this.tr069DeviceEventHandler = tr069DeviceEventHandler;\r
+  }\r
+\r
+  public void setTimerServiceManagerAPI(TimerServiceManagerAPI timerServiceManagerAPI) {\r
+    this.timerServiceManagerAPI = timerServiceManagerAPI;\r
+  }\r
+\r
+  public void setDeviceAuthenticator(DeviceValidator deviceAuthenticator) {\r
+    this.deviceValidtor = deviceAuthenticator;\r
+  }\r
+\r
+}\r