Merge "VES Heartbeat and Software Management Feature"
[oam/tr069-adapter.git] / ves-agent / src / main / java / org / commscope / tr069adapter / vesagent / service / VesAgentServiceHelper.java
1 package org.commscope.tr069adapter.vesagent.service;\r
2 \r
3 import com.google.gson.Gson;\r
4 \r
5 import java.util.ArrayList;\r
6 import java.util.HashMap;\r
7 import java.util.List;\r
8 import java.util.Map;\r
9 import java.util.concurrent.TimeUnit;\r
10 import java.util.function.Function;\r
11 \r
12 import org.commscope.tr069adapter.acs.common.DeviceDetails;\r
13 import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;\r
14 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
15 import org.commscope.tr069adapter.mapper.model.VESNotification;\r
16 import org.commscope.tr069adapter.vesagent.async.WaitForNotifications;\r
17 import org.commscope.tr069adapter.vesagent.entity.DeviceDataEntity;\r
18 import org.commscope.tr069adapter.vesagent.exception.VesAgentException;\r
19 import org.commscope.tr069adapter.vesagent.repository.VesDataRepository;\r
20 import org.commscope.tr069adapter.vesagent.timer.HeartBeatTimeoutTask;\r
21 import org.commscope.tr069adapter.vesagent.timer.ScheduleInfo;\r
22 import org.commscope.tr069adapter.vesagent.timer.ScheduleTaskService;\r
23 import org.commscope.tr069adapter.vesagent.util.VesAgentConstants;\r
24 import org.commscope.tr069adapter.vesagent.util.VesAgentUtils;\r
25 import org.slf4j.Logger;\r
26 import org.slf4j.LoggerFactory;\r
27 import org.springframework.beans.factory.annotation.Autowired;\r
28 import org.springframework.stereotype.Component;\r
29 \r
30 @Component\r
31 public class VesAgentServiceHelper {\r
32   private final Logger logger = LoggerFactory.getLogger(this.getClass());\r
33 \r
34   @Autowired\r
35   private Function<String, HeartBeatTimeoutTask> beanFactory;\r
36 \r
37   public HeartBeatTimeoutTask getBeanInstance(String name) {\r
38     return beanFactory.apply(name);\r
39   }\r
40 \r
41   @Autowired\r
42   VesDataRepository vesDataRepository;\r
43 \r
44   @Autowired\r
45   WaitForNotifications waitForNotifications;\r
46 \r
47   @Autowired\r
48   ScheduleTaskService timerService;\r
49 \r
50   private boolean saveDeviceDataEntity(DeviceDetails deviceDetails, String eNodeBName,\r
51       String heartBeatPeriod) throws VesAgentException {\r
52 \r
53     List<DeviceDataEntity> deviceDataEntityList = vesDataRepository\r
54         .findByDeviceIdAndAttrGroup(deviceDetails.getDeviceId(), VesAgentConstants.HEART_BEAT);\r
55 \r
56     DeviceDataEntity deviceDataEntity = null;\r
57     Map<String, String> attrJsonMap = null;\r
58 \r
59     if (null == deviceDataEntityList || deviceDataEntityList.isEmpty()) {\r
60       deviceDataEntity = new DeviceDataEntity();\r
61 \r
62       deviceDataEntity.setDeviceId(deviceDetails.getDeviceId());\r
63       deviceDataEntity.seteNodeBName(eNodeBName);\r
64       deviceDataEntity.setOui(deviceDetails.getOui());\r
65       deviceDataEntity.setProductClass(deviceDetails.getProductClass());\r
66       deviceDataEntity.setAttrGroup(VesAgentConstants.HEART_BEAT);\r
67 \r
68       attrJsonMap = new HashMap<>();\r
69     } else {\r
70       deviceDataEntity = deviceDataEntityList.get(0);\r
71       attrJsonMap = deviceDataEntity.getAttributesMap();\r
72     }\r
73 \r
74     String existingHeartBeatPeriod = attrJsonMap.get(VesAgentConstants.HEART_BEAT_PERIOD);\r
75 \r
76     if (null == heartBeatPeriod\r
77         && (Boolean.TRUE.equals(VesAgentUtils.isNullOrEmpty(existingHeartBeatPeriod))\r
78             || existingHeartBeatPeriod\r
79                 .equalsIgnoreCase(VesAgentConstants.REMOVE_HEART_BEAT_TIMER_VAL))) {\r
80       return false;\r
81     }\r
82 \r
83     if (!VesAgentUtils.isNullOrEmpty(heartBeatPeriod)) {\r
84       attrJsonMap.put(VesAgentConstants.HEART_BEAT_PERIOD, heartBeatPeriod);\r
85     }\r
86 \r
87     deviceDataEntity.setAttributesMap(attrJsonMap);\r
88 \r
89     vesDataRepository.save(deviceDataEntity);\r
90 \r
91     return true;\r
92   }\r
93 \r
94   public void processHeartBeatSetRequest(DeviceRPCRequest deviceRPCRequest, String heartBeatPeriod,\r
95       String countDownTimer) throws VesAgentException {\r
96 \r
97     String deviceId = deviceRPCRequest.getDeviceDetails().getDeviceId();\r
98 \r
99     VesAgentUtils.validateDeviceId(deviceId);\r
100 \r
101     if (VesAgentUtils.isNullOrEmpty(heartBeatPeriod)\r
102         && VesAgentUtils.isNullOrEmpty(countDownTimer)) {\r
103       String errorMsg =\r
104           "Invalid input: HeartBeatPeriod and countDownTimer both are null for device " + deviceId;\r
105       logger.error(errorMsg);\r
106       throw new VesAgentException(VesAgentConstants.INVALID_PARAMETER_VALUE, errorMsg);\r
107     }\r
108 \r
109     Object eNodeBNameObj = deviceRPCRequest.getContext().get(VesAgentConstants.ENODEB_NAME);\r
110 \r
111     String eNodeBName = null;\r
112     if (null != eNodeBNameObj) {\r
113       eNodeBName = (String) eNodeBNameObj;\r
114     }\r
115 \r
116     boolean resetTimerJob =\r
117         saveDeviceDataEntity(deviceRPCRequest.getDeviceDetails(), eNodeBName, heartBeatPeriod);\r
118 \r
119     if (resetTimerJob) {\r
120       resetTimerJob(deviceId, heartBeatPeriod, countDownTimer);\r
121       abortRunningDeviceConnectivityCheck(deviceRPCRequest);\r
122     }\r
123 \r
124   }\r
125 \r
126   public void processHeartBeatGetRequest(DeviceRPCRequest deviceRPCRequest) {\r
127 \r
128     String deviceId = deviceRPCRequest.getDeviceDetails().getDeviceId();\r
129     List<DeviceDataEntity> deviceDataEntityList =\r
130         vesDataRepository.findByDeviceIdAndAttrGroup(deviceId, VesAgentConstants.HEART_BEAT);\r
131 \r
132     if (VesAgentUtils.isNullOrEmpty(deviceDataEntityList)\r
133         || VesAgentUtils.isNullOrEmpty(deviceDataEntityList.get(0).getAttributesMap())) {\r
134       return;\r
135     }\r
136 \r
137     DeviceDataEntity deviceDataEntity = deviceDataEntityList.get(0);\r
138 \r
139     List<ParameterDTO> resultparamDTOList = null;\r
140     List<ParameterDTO> paramDTOList = deviceRPCRequest.getOpDetails().getParmeters();\r
141 \r
142     for (ParameterDTO paramDTO : paramDTOList) {\r
143       resultparamDTOList = ifDataTypeObject(paramDTO, deviceDataEntity);\r
144 \r
145       if (!resultparamDTOList.isEmpty()) {\r
146         break;\r
147       }\r
148 \r
149       if (paramDTO.getParamName().equalsIgnoreCase(VesAgentConstants.COUNT_DOWN_TIMER)) {\r
150         paramDTO.setParamValue(getCountDownTimerParam(deviceDataEntity).getParamValue());\r
151       } else {\r
152         paramDTO.setParamValue(deviceDataEntity.getAttributesMap().get(paramDTO.getParamName()));\r
153       }\r
154     }\r
155 \r
156     if (null != resultparamDTOList && !resultparamDTOList.isEmpty()) {\r
157       deviceRPCRequest.getOpDetails().setParmeters(resultparamDTOList);\r
158     }\r
159   }\r
160 \r
161   public void processHeartBeatDeleteRequest(VESNotification vesNotification) {\r
162     List<ParameterDTO> paramDTOList = vesNotification.getOperationDetails().getParmeters();\r
163 \r
164     for (ParameterDTO paramDTO : paramDTOList) {\r
165       if (Boolean.TRUE.equals(VesAgentUtils.isVesNotificationRequest(paramDTO))) {\r
166         List<DeviceDataEntity> deviceDataEntityList = vesDataRepository.findByDeviceIdAndAttrGroup(\r
167             vesNotification.geteNodeBName(), VesAgentConstants.HEART_BEAT);\r
168 \r
169         if (Boolean.TRUE.equals(VesAgentUtils.isNullOrEmpty(deviceDataEntityList))) {\r
170           return;\r
171         }\r
172         vesDataRepository.delete(deviceDataEntityList.get(0));\r
173         timerService.cancelSchedule(vesNotification.geteNodeBName());\r
174         break;\r
175       }\r
176     }\r
177   }\r
178 \r
179   private List<ParameterDTO> ifDataTypeObject(ParameterDTO paramDTO,\r
180       DeviceDataEntity deviceDataEntity) {\r
181     List<ParameterDTO> paramDTOList = new ArrayList<>();\r
182 \r
183     if (null != paramDTO.getDataType()\r
184         && paramDTO.getDataType().equalsIgnoreCase(VesAgentConstants.OBJECT_DATA_TYPE.toLowerCase())\r
185         && paramDTO.getParamName().toLowerCase()\r
186             .contains(VesAgentConstants.HEART_BEAT.toLowerCase())) {\r
187 \r
188       Map<String, String> attrMap = deviceDataEntity.getAttributesMap();\r
189 \r
190       for (Map.Entry<String, String> entry : attrMap.entrySet()) {\r
191         ParameterDTO param = new ParameterDTO();\r
192         param.setParamName(entry.getKey());\r
193         param.setParamValue(entry.getValue());\r
194 \r
195         paramDTOList.add(param);\r
196       }\r
197 \r
198       ParameterDTO countDownParam = getCountDownTimerParam(deviceDataEntity);\r
199       paramDTOList.add(countDownParam);\r
200     }\r
201 \r
202     return paramDTOList;\r
203   }\r
204 \r
205   private ParameterDTO getCountDownTimerParam(DeviceDataEntity deviceDataEntity) {\r
206     Long countDownTimerVal = timerService\r
207         .getTimeRemainingTillNextExecution(deviceDataEntity.getDeviceId(), TimeUnit.MINUTES);\r
208 \r
209     ParameterDTO param = new ParameterDTO();\r
210     param.setParamName(VesAgentConstants.COUNT_DOWN_TIMER);\r
211 \r
212     if (null != countDownTimerVal) {\r
213       param.setParamValue(countDownTimerVal.toString());\r
214     }\r
215 \r
216     return param;\r
217   }\r
218 \r
219 \r
220   public void processHeartBeatGetRequest(String deviceId, Integer HeartBeatPeriod,\r
221       Integer countDownTimer) throws VesAgentException {\r
222     VesAgentUtils.validateDeviceId(deviceId);\r
223 \r
224 \r
225     if (null == HeartBeatPeriod && null == countDownTimer) {// this should just check if heartbeat\r
226                                                             // is null\r
227       String errorMsg =\r
228           "Invalid input: HeartBeatPeriod and countDownTimer both are null for device " + deviceId;\r
229       logger.error(errorMsg);\r
230       throw new VesAgentException(errorMsg);\r
231     }\r
232 \r
233     List<DeviceDataEntity> deviceDataEntityList =\r
234         vesDataRepository.findByDeviceIdAndAttrGroup(deviceId, VesAgentConstants.HEART_BEAT);\r
235 \r
236     DeviceDataEntity deviceDataEntity = null;\r
237     Map<String, String> attrJsonMap = null;\r
238 \r
239     if (null == deviceDataEntityList || deviceDataEntityList.isEmpty()) {\r
240       deviceDataEntity = new DeviceDataEntity();\r
241       deviceDataEntity.setDeviceId(deviceId);\r
242       deviceDataEntity.setAttrGroup(VesAgentConstants.HEART_BEAT);\r
243 \r
244       attrJsonMap = new HashMap<String, String>();\r
245     } else {\r
246       deviceDataEntity = deviceDataEntityList.get(0);\r
247       attrJsonMap = new Gson().fromJson(deviceDataEntity.getAttrJson(), Map.class);\r
248     }\r
249 \r
250 \r
251     if (null != HeartBeatPeriod) {\r
252       attrJsonMap.put(VesAgentConstants.HEART_BEAT_PERIOD, HeartBeatPeriod.toString());\r
253     }\r
254 \r
255     if (null != countDownTimer) {\r
256       attrJsonMap.put(VesAgentConstants.COUNT_DOWN_TIMER, countDownTimer.toString());\r
257     }\r
258 \r
259     String attrJson = new Gson().toJson(attrJsonMap);\r
260     deviceDataEntity.setAttrJson(attrJson);\r
261 \r
262     vesDataRepository.save(deviceDataEntity);\r
263   }\r
264 \r
265   private void resetTimerJob(String deviceId, String heartBeatPeriod, String countDownTimer) {\r
266     if (null == heartBeatPeriod || heartBeatPeriod.isEmpty()) {\r
267       scheduleTimerJob(deviceId, Integer.parseInt(countDownTimer));\r
268     } else if (heartBeatPeriod.equals(VesAgentConstants.REMOVE_HEART_BEAT_TIMER_VAL)) {\r
269       timerService.cancelSchedule(deviceId);\r
270     } else {\r
271       if (Boolean.FALSE.equals(VesAgentUtils.isNullOrEmpty(countDownTimer))) {\r
272         scheduleTimerJob(deviceId, Integer.parseInt(countDownTimer));\r
273       } else {\r
274         scheduleTimerJob(deviceId, Integer.parseInt(heartBeatPeriod));\r
275       }\r
276     }\r
277   }\r
278 \r
279   private void scheduleTimerJob(String deviceId, Integer timeoutInterval) {\r
280     ScheduleInfo scheduleInfo = new ScheduleInfo();\r
281     scheduleInfo.setInterval(timeoutInterval);\r
282     scheduleInfo.setTimeUnit(TimeUnit.MINUTES);\r
283 \r
284     HeartBeatTimeoutTask callbackTask = getBeanInstance(deviceId);\r
285 \r
286     timerService.schedule(deviceId, scheduleInfo, callbackTask);\r
287   }\r
288 \r
289   private void abortRunningDeviceConnectivityCheck(DeviceRPCRequest deviceRPCRequest) {\r
290     waitForNotifications.notifyResult(VesAgentUtils.getErrorResponse(deviceRPCRequest, null, null));\r
291   }\r
292 \r
293   public List<DeviceDataEntity> getAllDeviceDataEntity() {\r
294     return (List<DeviceDataEntity>) vesDataRepository.findAll();\r
295   }\r
296 \r
297   public List<DeviceDataEntity> findByDeviceIdAndGroup(String deviceId, String attrGroup) {\r
298     return vesDataRepository.findByDeviceIdAndAttrGroup(deviceId, attrGroup);\r
299   }\r
300 \r
301 \r
302 \r
303 }\r