sonar code issues addressed
[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     validateTimers(heartBeatPeriod, countDownTimer, existingHeartBeatPeriod);
101
102     if (!VesAgentUtils.isNullOrEmpty(heartBeatPeriod)) {
103       attrJsonMap.put(VesAgentConstants.HEART_BEAT_PERIOD, heartBeatPeriod);
104     }
105
106     deviceDataEntity.setAttributesMap(attrJsonMap);
107
108     vesDataRepository.save(deviceDataEntity);
109
110     return true;
111   }
112
113   private void validateTimers(String heartBeatPeriod, String countDownTimer,
114       String existingHeartBeatPeriod) throws VesAgentException {
115     if (null != countDownTimer
116         && !countDownTimer.equalsIgnoreCase(VesAgentConstants.COUNT_DOWN_TIMER_ZERO)) {
117       validateHeartBeatPeriod(heartBeatPeriod, existingHeartBeatPeriod);
118
119     }
120   }
121
122   private void validateHeartBeatPeriod(String heartBeatPeriod, String existingHeartBeatPeriod)
123       throws VesAgentException {
124     if (null == heartBeatPeriod || heartBeatPeriod.equalsIgnoreCase(existingHeartBeatPeriod)) {
125       String exceptionReason = "Can't change timer value if heartbeat value is same";
126       throw new VesAgentException(VesAgentConstants.INVALID_PARAMETER_VALUE, exceptionReason);
127     }
128   }
129
130   public void processHeartBeatSetRequest(DeviceRPCRequest deviceRPCRequest, String heartBeatPeriod,
131       String countDownTimer) throws VesAgentException {
132
133     String deviceId = deviceRPCRequest.getDeviceDetails().getDeviceId();
134
135     VesAgentUtils.validateDeviceId(deviceId);
136
137     if (VesAgentUtils.isNullOrEmpty(heartBeatPeriod)
138         && VesAgentUtils.isNullOrEmpty(countDownTimer)) {
139       String errorMsg =
140           "Invalid input: HeartBeatPeriod and countDownTimer both are null for device " + deviceId;
141       errorMsg = errorMsg.replaceAll("[\n|\r|\t]", "_");
142       logger.error(errorMsg);
143       throw new VesAgentException(VesAgentConstants.INVALID_PARAMETER_VALUE, errorMsg);
144     }
145
146     Object eNodeBNameObj = deviceRPCRequest.getContext().get(VesAgentConstants.ENODEB_NAME);
147
148     String eNodeBName = null;
149     if (null != eNodeBNameObj) {
150       eNodeBName = (String) eNodeBNameObj;
151     }
152
153     boolean resetTimerJob = saveDeviceDataEntity(deviceRPCRequest.getDeviceDetails(), eNodeBName,
154         heartBeatPeriod, countDownTimer);
155
156     if (resetTimerJob) {
157       resetTimerJob(deviceId, heartBeatPeriod, countDownTimer);
158       abortRunningDeviceConnectivityCheck(deviceRPCRequest);
159     }
160
161   }
162
163   public void processHeartBeatGetRequest(DeviceRPCRequest deviceRPCRequest) {
164
165     String deviceId = deviceRPCRequest.getDeviceDetails().getDeviceId();
166     List<DeviceDataEntity> deviceDataEntityList =
167         vesDataRepository.findByDeviceIdAndAttrGroup(deviceId, VesAgentConstants.HEART_BEAT);
168
169     if (VesAgentUtils.isNullOrEmpty(deviceDataEntityList)
170         || VesAgentUtils.isNullOrEmpty(deviceDataEntityList.get(0).getAttributesMap())) {
171       return;
172     }
173
174     DeviceDataEntity deviceDataEntity = deviceDataEntityList.get(0);
175
176     List<ParameterDTO> resultparamDTOList = null;
177     List<ParameterDTO> paramDTOList = deviceRPCRequest.getOpDetails().getParmeters();
178
179     for (ParameterDTO paramDTO : paramDTOList) {
180       resultparamDTOList = ifDataTypeObject(paramDTO, deviceDataEntity);
181
182       if (!resultparamDTOList.isEmpty()) {
183         break;
184       }
185
186       if (paramDTO.getParamName().equalsIgnoreCase(VesAgentConstants.COUNT_DOWN_TIMER)) {
187         paramDTO.setParamValue(getCountDownTimerParam(deviceDataEntity).getParamValue());
188       } else {
189         paramDTO.setParamValue(deviceDataEntity.getAttributesMap().get(paramDTO.getParamName()));
190       }
191     }
192
193     if (null != resultparamDTOList && !resultparamDTOList.isEmpty()) {
194       deviceRPCRequest.getOpDetails().setParmeters(resultparamDTOList);
195     }
196   }
197
198   public void processHeartBeatDeleteRequest(VESNotification vesNotification) {
199     List<ParameterDTO> paramDTOList = vesNotification.getOperationDetails().getParmeters();
200
201     for (ParameterDTO paramDTO : paramDTOList) {
202       if (Boolean.TRUE.equals(VesAgentUtils.isVesNotificationRequest(paramDTO))) {
203         List<DeviceDataEntity> deviceDataEntityList = vesDataRepository.findByDeviceIdAndAttrGroup(
204             vesNotification.geteNodeBName(), VesAgentConstants.HEART_BEAT);
205
206         if (Boolean.TRUE.equals(VesAgentUtils.isNullOrEmpty(deviceDataEntityList))) {
207           return;
208         }
209         vesDataRepository.delete(deviceDataEntityList.get(0));
210         timerService.cancelSchedule(vesNotification.geteNodeBName());
211         break;
212       }
213     }
214   }
215
216   private List<ParameterDTO> ifDataTypeObject(ParameterDTO paramDTO,
217       DeviceDataEntity deviceDataEntity) {
218     List<ParameterDTO> paramDTOList = new ArrayList<>();
219
220     if (null != paramDTO.getDataType()
221         && paramDTO.getDataType().equalsIgnoreCase(VesAgentConstants.OBJECT_DATA_TYPE.toLowerCase())
222         && paramDTO.getParamName().toLowerCase()
223             .contains(VesAgentConstants.HEART_BEAT.toLowerCase())) {
224
225       Map<String, String> attrMap = deviceDataEntity.getAttributesMap();
226
227       for (Map.Entry<String, String> entry : attrMap.entrySet()) {
228         ParameterDTO param = new ParameterDTO();
229         param.setParamName(entry.getKey());
230         param.setParamValue(entry.getValue());
231
232         paramDTOList.add(param);
233       }
234
235       ParameterDTO countDownParam = getCountDownTimerParam(deviceDataEntity);
236       paramDTOList.add(countDownParam);
237     }
238
239     return paramDTOList;
240   }
241
242   private ParameterDTO getCountDownTimerParam(DeviceDataEntity deviceDataEntity) {
243     Long countDownTimerVal = timerService
244         .getTimeRemainingTillNextExecution(deviceDataEntity.getDeviceId(), TimeUnit.MINUTES);
245
246     ParameterDTO param = new ParameterDTO();
247     param.setParamName(VesAgentConstants.COUNT_DOWN_TIMER);
248
249     if (null != countDownTimerVal) {
250       param.setParamValue(countDownTimerVal.toString());
251     }
252
253     return param;
254   }
255
256
257   public void processHeartBeatGetRequest(String deviceId, Integer heartBeatPeriod,
258       Integer countDownTimer) throws VesAgentException {
259     VesAgentUtils.validateDeviceId(deviceId);
260
261
262     if (null == heartBeatPeriod && null == countDownTimer) {// this should just check if heartbeat
263                                                             // is null
264       String errorMsg =
265           "Invalid input: HeartBeatPeriod and countDownTimer both are null for device " + deviceId;
266       logger.error(errorMsg);
267       throw new VesAgentException(errorMsg);
268     }
269
270     List<DeviceDataEntity> deviceDataEntityList =
271         vesDataRepository.findByDeviceIdAndAttrGroup(deviceId, VesAgentConstants.HEART_BEAT);
272
273     DeviceDataEntity deviceDataEntity = null;
274     Map<String, String> attrJsonMap = null;
275
276     if (null == deviceDataEntityList || deviceDataEntityList.isEmpty()) {
277       deviceDataEntity = new DeviceDataEntity();
278       deviceDataEntity.setDeviceId(deviceId);
279       deviceDataEntity.setAttrGroup(VesAgentConstants.HEART_BEAT);
280
281       attrJsonMap = new HashMap<>();
282     } else {
283       deviceDataEntity = deviceDataEntityList.get(0);
284       attrJsonMap = new Gson().fromJson(deviceDataEntity.getAttrJson(), Map.class);
285     }
286
287
288     if (null != heartBeatPeriod) {
289       attrJsonMap.put(VesAgentConstants.HEART_BEAT_PERIOD, heartBeatPeriod.toString());
290     }
291
292     if (null != countDownTimer) {
293       attrJsonMap.put(VesAgentConstants.COUNT_DOWN_TIMER, countDownTimer.toString());
294     }
295
296     String attrJson = new Gson().toJson(attrJsonMap);
297     deviceDataEntity.setAttrJson(attrJson);
298
299     vesDataRepository.save(deviceDataEntity);
300   }
301
302   private void resetTimerJob(String deviceId, String heartBeatPeriod, String countDownTimer) {
303     if (null == heartBeatPeriod || heartBeatPeriod.isEmpty()) {
304       scheduleTimerJob(deviceId, Integer.parseInt(countDownTimer));
305     } else if (heartBeatPeriod.equals(VesAgentConstants.REMOVE_HEART_BEAT_TIMER_VAL)) {
306       timerService.cancelSchedule(deviceId);
307     } else {
308       if (Boolean.FALSE.equals(VesAgentUtils.isNullOrEmpty(countDownTimer))) {
309         scheduleTimerJob(deviceId, Integer.parseInt(countDownTimer));
310       } else {
311         scheduleTimerJob(deviceId, Integer.parseInt(heartBeatPeriod));
312       }
313     }
314   }
315
316   private void scheduleTimerJob(String deviceId, Integer timeoutInterval) {
317     ScheduleInfo scheduleInfo = new ScheduleInfo();
318     scheduleInfo.setInterval(timeoutInterval);
319     scheduleInfo.setTimeUnit(TimeUnit.MINUTES);
320
321     HeartBeatTimeoutTask callbackTask = getBeanInstance(deviceId);
322
323     timerService.schedule(deviceId, scheduleInfo, callbackTask);
324   }
325
326   private void abortRunningDeviceConnectivityCheck(DeviceRPCRequest deviceRPCRequest) {
327     waitForNotifications.notifyResult(VesAgentUtils.getErrorResponse(deviceRPCRequest, null, null));
328   }
329
330   public List<DeviceDataEntity> getAllDeviceDataEntity() {
331     return (List<DeviceDataEntity>) vesDataRepository.findAll();
332   }
333
334   public List<DeviceDataEntity> findByDeviceIdAndGroup(String deviceId, String attrGroup) {
335     return vesDataRepository.findByDeviceIdAndAttrGroup(deviceId, attrGroup);
336   }
337
338
339
340 }