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