VES Heartbeat and Software Management Feature
[oam/tr069-adapter.git] / ves-agent / src / main / java / org / commscope / tr069adapter / vesagent / service / VesAgentServiceHelper.java
diff --git a/ves-agent/src/main/java/org/commscope/tr069adapter/vesagent/service/VesAgentServiceHelper.java b/ves-agent/src/main/java/org/commscope/tr069adapter/vesagent/service/VesAgentServiceHelper.java
new file mode 100644 (file)
index 0000000..d492a42
--- /dev/null
@@ -0,0 +1,303 @@
+package org.commscope.tr069adapter.vesagent.service;\r
+\r
+import com.google.gson.Gson;\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.concurrent.TimeUnit;\r
+import java.util.function.Function;\r
+\r
+import org.commscope.tr069adapter.acs.common.DeviceDetails;\r
+import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;\r
+import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
+import org.commscope.tr069adapter.mapper.model.VESNotification;\r
+import org.commscope.tr069adapter.vesagent.async.WaitForNotifications;\r
+import org.commscope.tr069adapter.vesagent.entity.DeviceDataEntity;\r
+import org.commscope.tr069adapter.vesagent.exception.VesAgentException;\r
+import org.commscope.tr069adapter.vesagent.repository.VesDataRepository;\r
+import org.commscope.tr069adapter.vesagent.timer.HeartBeatTimeoutTask;\r
+import org.commscope.tr069adapter.vesagent.timer.ScheduleInfo;\r
+import org.commscope.tr069adapter.vesagent.timer.ScheduleTaskService;\r
+import org.commscope.tr069adapter.vesagent.util.VesAgentConstants;\r
+import org.commscope.tr069adapter.vesagent.util.VesAgentUtils;\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\r
+public class VesAgentServiceHelper {\r
+  private final Logger logger = LoggerFactory.getLogger(this.getClass());\r
+\r
+  @Autowired\r
+  private Function<String, HeartBeatTimeoutTask> beanFactory;\r
+\r
+  public HeartBeatTimeoutTask getBeanInstance(String name) {\r
+    return beanFactory.apply(name);\r
+  }\r
+\r
+  @Autowired\r
+  VesDataRepository vesDataRepository;\r
+\r
+  @Autowired\r
+  WaitForNotifications waitForNotifications;\r
+\r
+  @Autowired\r
+  ScheduleTaskService timerService;\r
+\r
+  private boolean saveDeviceDataEntity(DeviceDetails deviceDetails, String eNodeBName,\r
+      String heartBeatPeriod) throws VesAgentException {\r
+\r
+    List<DeviceDataEntity> deviceDataEntityList = vesDataRepository\r
+        .findByDeviceIdAndAttrGroup(deviceDetails.getDeviceId(), VesAgentConstants.HEART_BEAT);\r
+\r
+    DeviceDataEntity deviceDataEntity = null;\r
+    Map<String, String> attrJsonMap = null;\r
+\r
+    if (null == deviceDataEntityList || deviceDataEntityList.isEmpty()) {\r
+      deviceDataEntity = new DeviceDataEntity();\r
+\r
+      deviceDataEntity.setDeviceId(deviceDetails.getDeviceId());\r
+      deviceDataEntity.seteNodeBName(eNodeBName);\r
+      deviceDataEntity.setOui(deviceDetails.getOui());\r
+      deviceDataEntity.setProductClass(deviceDetails.getProductClass());\r
+      deviceDataEntity.setAttrGroup(VesAgentConstants.HEART_BEAT);\r
+\r
+      attrJsonMap = new HashMap<>();\r
+    } else {\r
+      deviceDataEntity = deviceDataEntityList.get(0);\r
+      attrJsonMap = deviceDataEntity.getAttributesMap();\r
+    }\r
+\r
+    String existingHeartBeatPeriod = attrJsonMap.get(VesAgentConstants.HEART_BEAT_PERIOD);\r
+\r
+    if (null == heartBeatPeriod\r
+        && (Boolean.TRUE.equals(VesAgentUtils.isNullOrEmpty(existingHeartBeatPeriod))\r
+            || existingHeartBeatPeriod\r
+                .equalsIgnoreCase(VesAgentConstants.REMOVE_HEART_BEAT_TIMER_VAL))) {\r
+      return false;\r
+    }\r
+\r
+    if (!VesAgentUtils.isNullOrEmpty(heartBeatPeriod)) {\r
+      attrJsonMap.put(VesAgentConstants.HEART_BEAT_PERIOD, heartBeatPeriod);\r
+    }\r
+\r
+    deviceDataEntity.setAttributesMap(attrJsonMap);\r
+\r
+    vesDataRepository.save(deviceDataEntity);\r
+\r
+    return true;\r
+  }\r
+\r
+  public void processHeartBeatSetRequest(DeviceRPCRequest deviceRPCRequest, String heartBeatPeriod,\r
+      String countDownTimer) throws VesAgentException {\r
+\r
+    String deviceId = deviceRPCRequest.getDeviceDetails().getDeviceId();\r
+\r
+    VesAgentUtils.validateDeviceId(deviceId);\r
+\r
+    if (VesAgentUtils.isNullOrEmpty(heartBeatPeriod)\r
+        && VesAgentUtils.isNullOrEmpty(countDownTimer)) {\r
+      String errorMsg =\r
+          "Invalid input: HeartBeatPeriod and countDownTimer both are null for device " + deviceId;\r
+      logger.error(errorMsg);\r
+      throw new VesAgentException(VesAgentConstants.INVALID_PARAMETER_VALUE, errorMsg);\r
+    }\r
+\r
+    Object eNodeBNameObj = deviceRPCRequest.getContext().get(VesAgentConstants.ENODEB_NAME);\r
+\r
+    String eNodeBName = null;\r
+    if (null != eNodeBNameObj) {\r
+      eNodeBName = (String) eNodeBNameObj;\r
+    }\r
+\r
+    boolean resetTimerJob =\r
+        saveDeviceDataEntity(deviceRPCRequest.getDeviceDetails(), eNodeBName, heartBeatPeriod);\r
+\r
+    if (resetTimerJob) {\r
+      resetTimerJob(deviceId, heartBeatPeriod, countDownTimer);\r
+      abortRunningDeviceConnectivityCheck(deviceRPCRequest);\r
+    }\r
+\r
+  }\r
+\r
+  public void processHeartBeatGetRequest(DeviceRPCRequest deviceRPCRequest) {\r
+\r
+    String deviceId = deviceRPCRequest.getDeviceDetails().getDeviceId();\r
+    List<DeviceDataEntity> deviceDataEntityList =\r
+        vesDataRepository.findByDeviceIdAndAttrGroup(deviceId, VesAgentConstants.HEART_BEAT);\r
+\r
+    if (VesAgentUtils.isNullOrEmpty(deviceDataEntityList)\r
+        || VesAgentUtils.isNullOrEmpty(deviceDataEntityList.get(0).getAttributesMap())) {\r
+      return;\r
+    }\r
+\r
+    DeviceDataEntity deviceDataEntity = deviceDataEntityList.get(0);\r
+\r
+    List<ParameterDTO> resultparamDTOList = null;\r
+    List<ParameterDTO> paramDTOList = deviceRPCRequest.getOpDetails().getParmeters();\r
+\r
+    for (ParameterDTO paramDTO : paramDTOList) {\r
+      resultparamDTOList = ifDataTypeObject(paramDTO, deviceDataEntity);\r
+\r
+      if (!resultparamDTOList.isEmpty()) {\r
+        break;\r
+      }\r
+\r
+      if (paramDTO.getParamName().equalsIgnoreCase(VesAgentConstants.COUNT_DOWN_TIMER)) {\r
+        paramDTO.setParamValue(getCountDownTimerParam(deviceDataEntity).getParamValue());\r
+      } else {\r
+        paramDTO.setParamValue(deviceDataEntity.getAttributesMap().get(paramDTO.getParamName()));\r
+      }\r
+    }\r
+\r
+    if (null != resultparamDTOList && !resultparamDTOList.isEmpty()) {\r
+      deviceRPCRequest.getOpDetails().setParmeters(resultparamDTOList);\r
+    }\r
+  }\r
+\r
+  public void processHeartBeatDeleteRequest(VESNotification vesNotification) {\r
+    List<ParameterDTO> paramDTOList = vesNotification.getOperationDetails().getParmeters();\r
+\r
+    for (ParameterDTO paramDTO : paramDTOList) {\r
+      if (Boolean.TRUE.equals(VesAgentUtils.isVesNotificationRequest(paramDTO))) {\r
+        List<DeviceDataEntity> deviceDataEntityList = vesDataRepository.findByDeviceIdAndAttrGroup(\r
+            vesNotification.geteNodeBName(), VesAgentConstants.HEART_BEAT);\r
+\r
+        if (Boolean.TRUE.equals(VesAgentUtils.isNullOrEmpty(deviceDataEntityList))) {\r
+          return;\r
+        }\r
+        vesDataRepository.delete(deviceDataEntityList.get(0));\r
+        timerService.cancelSchedule(vesNotification.geteNodeBName());\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  private List<ParameterDTO> ifDataTypeObject(ParameterDTO paramDTO,\r
+      DeviceDataEntity deviceDataEntity) {\r
+    List<ParameterDTO> paramDTOList = new ArrayList<>();\r
+\r
+    if (null != paramDTO.getDataType()\r
+        && paramDTO.getDataType().equalsIgnoreCase(VesAgentConstants.OBJECT_DATA_TYPE.toLowerCase())\r
+        && paramDTO.getParamName().toLowerCase()\r
+            .contains(VesAgentConstants.HEART_BEAT.toLowerCase())) {\r
+\r
+      Map<String, String> attrMap = deviceDataEntity.getAttributesMap();\r
+\r
+      for (Map.Entry<String, String> entry : attrMap.entrySet()) {\r
+        ParameterDTO param = new ParameterDTO();\r
+        param.setParamName(entry.getKey());\r
+        param.setParamValue(entry.getValue());\r
+\r
+        paramDTOList.add(param);\r
+      }\r
+\r
+      ParameterDTO countDownParam = getCountDownTimerParam(deviceDataEntity);\r
+      paramDTOList.add(countDownParam);\r
+    }\r
+\r
+    return paramDTOList;\r
+  }\r
+\r
+  private ParameterDTO getCountDownTimerParam(DeviceDataEntity deviceDataEntity) {\r
+    Long countDownTimerVal = timerService\r
+        .getTimeRemainingTillNextExecution(deviceDataEntity.getDeviceId(), TimeUnit.MINUTES);\r
+\r
+    ParameterDTO param = new ParameterDTO();\r
+    param.setParamName(VesAgentConstants.COUNT_DOWN_TIMER);\r
+\r
+    if (null != countDownTimerVal) {\r
+      param.setParamValue(countDownTimerVal.toString());\r
+    }\r
+\r
+    return param;\r
+  }\r
+\r
+\r
+  public void processHeartBeatGetRequest(String deviceId, Integer HeartBeatPeriod,\r
+      Integer countDownTimer) throws VesAgentException {\r
+    VesAgentUtils.validateDeviceId(deviceId);\r
+\r
+\r
+    if (null == HeartBeatPeriod && null == countDownTimer) {// this should just check if heartbeat\r
+                                                            // is null\r
+      String errorMsg =\r
+          "Invalid input: HeartBeatPeriod and countDownTimer both are null for device " + deviceId;\r
+      logger.error(errorMsg);\r
+      throw new VesAgentException(errorMsg);\r
+    }\r
+\r
+    List<DeviceDataEntity> deviceDataEntityList =\r
+        vesDataRepository.findByDeviceIdAndAttrGroup(deviceId, VesAgentConstants.HEART_BEAT);\r
+\r
+    DeviceDataEntity deviceDataEntity = null;\r
+    Map<String, String> attrJsonMap = null;\r
+\r
+    if (null == deviceDataEntityList || deviceDataEntityList.isEmpty()) {\r
+      deviceDataEntity = new DeviceDataEntity();\r
+      deviceDataEntity.setDeviceId(deviceId);\r
+      deviceDataEntity.setAttrGroup(VesAgentConstants.HEART_BEAT);\r
+\r
+      attrJsonMap = new HashMap<String, String>();\r
+    } else {\r
+      deviceDataEntity = deviceDataEntityList.get(0);\r
+      attrJsonMap = new Gson().fromJson(deviceDataEntity.getAttrJson(), Map.class);\r
+    }\r
+\r
+\r
+    if (null != HeartBeatPeriod) {\r
+      attrJsonMap.put(VesAgentConstants.HEART_BEAT_PERIOD, HeartBeatPeriod.toString());\r
+    }\r
+\r
+    if (null != countDownTimer) {\r
+      attrJsonMap.put(VesAgentConstants.COUNT_DOWN_TIMER, countDownTimer.toString());\r
+    }\r
+\r
+    String attrJson = new Gson().toJson(attrJsonMap);\r
+    deviceDataEntity.setAttrJson(attrJson);\r
+\r
+    vesDataRepository.save(deviceDataEntity);\r
+  }\r
+\r
+  private void resetTimerJob(String deviceId, String heartBeatPeriod, String countDownTimer) {\r
+    if (null == heartBeatPeriod || heartBeatPeriod.isEmpty()) {\r
+      scheduleTimerJob(deviceId, Integer.parseInt(countDownTimer));\r
+    } else if (heartBeatPeriod.equals(VesAgentConstants.REMOVE_HEART_BEAT_TIMER_VAL)) {\r
+      timerService.cancelSchedule(deviceId);\r
+    } else {\r
+      if (Boolean.FALSE.equals(VesAgentUtils.isNullOrEmpty(countDownTimer))) {\r
+        scheduleTimerJob(deviceId, Integer.parseInt(countDownTimer));\r
+      } else {\r
+        scheduleTimerJob(deviceId, Integer.parseInt(heartBeatPeriod));\r
+      }\r
+    }\r
+  }\r
+\r
+  private void scheduleTimerJob(String deviceId, Integer timeoutInterval) {\r
+    ScheduleInfo scheduleInfo = new ScheduleInfo();\r
+    scheduleInfo.setInterval(timeoutInterval);\r
+    scheduleInfo.setTimeUnit(TimeUnit.MINUTES);\r
+\r
+    HeartBeatTimeoutTask callbackTask = getBeanInstance(deviceId);\r
+\r
+    timerService.schedule(deviceId, scheduleInfo, callbackTask);\r
+  }\r
+\r
+  private void abortRunningDeviceConnectivityCheck(DeviceRPCRequest deviceRPCRequest) {\r
+    waitForNotifications.notifyResult(VesAgentUtils.getErrorResponse(deviceRPCRequest, null, null));\r
+  }\r
+\r
+  public List<DeviceDataEntity> getAllDeviceDataEntity() {\r
+    return (List<DeviceDataEntity>) vesDataRepository.findAll();\r
+  }\r
+\r
+  public List<DeviceDataEntity> findByDeviceIdAndGroup(String deviceId, String attrGroup) {\r
+    return vesDataRepository.findByDeviceIdAndAttrGroup(deviceId, attrGroup);\r
+  }\r
+\r
+\r
+\r
+}\r