b2f78c90233b38f863742cc2f3cb255e8fb7e24a
[oam/tr069-adapter.git] / acs / requestprocessor / src / main / java / org / commscope / tr069adapter / acs / requestprocessor / helper / TR069RequestProcessEngineHelper.java
1 /*\r
2  * ============LICENSE_START========================================================================\r
3  * ONAP : tr-069-adapter\r
4  * =================================================================================================\r
5  * Copyright (C) 2020 CommScope Inc Intellectual Property.\r
6  * =================================================================================================\r
7  * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,\r
8  * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You\r
9  * may obtain a copy of the License at\r
10  *\r
11  * http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r
14  * either express or implied. See the License for the specific language governing permissions and\r
15  * limitations under the License.\r
16  * ===============LICENSE_END=======================================================================\r
17  */\r
18 \r
19 package org.commscope.tr069adapter.acs.requestprocessor.helper;\r
20 \r
21 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.CR_REQ_Q;\r
22 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.DEVICE_RESPONSE_TIMEOUT;\r
23 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.DEVICE_RPC_EXECUTION_TIMEOUT_SECONDS;\r
24 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.SEPERATOR;\r
25 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.SESSION_TIMEOUT_CALLBACK_JNDI;\r
26 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.WAITING_FOR_DEVICE_RESPONSE;\r
27 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.WAITING_FOR_NBI_RESPONSE;\r
28 \r
29 import java.util.Date;\r
30 import java.util.List;\r
31 \r
32 import org.commscope.tr069adapter.acs.common.DeviceDetails;\r
33 import org.commscope.tr069adapter.acs.common.DeviceInform;\r
34 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
35 import org.commscope.tr069adapter.acs.common.dto.TR069DeviceDetails;\r
36 import org.commscope.tr069adapter.acs.common.dto.TR069InformType;\r
37 import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;\r
38 import org.commscope.tr069adapter.acs.common.dto.TR069OperationDetails;\r
39 import org.commscope.tr069adapter.acs.common.exception.DeviceOperationException;\r
40 import org.commscope.tr069adapter.acs.common.exception.SessionConcurrentAccessException;\r
41 import org.commscope.tr069adapter.acs.common.exception.SessionManagerException;\r
42 import org.commscope.tr069adapter.acs.common.utils.ErrorCode;\r
43 import org.commscope.tr069adapter.acs.requestprocessor.custom.CustomOperation;\r
44 import org.commscope.tr069adapter.acs.requestprocessor.dto.CustomOperationData;\r
45 import org.commscope.tr069adapter.acs.requestprocessor.dto.SessionDTO;\r
46 import org.commscope.tr069adapter.acs.requestprocessor.dto.SessionState;\r
47 import org.commscope.tr069adapter.acs.requestprocessor.dto.TR069RequestProcessorData;\r
48 import org.commscope.tr069adapter.acs.requestprocessor.impl.SessionManager;\r
49 import org.commscope.tr069adapter.acs.requestprocessor.util.TR069RequestProcessorCacheUtil;\r
50 import org.commscope.tr069adapter.common.timer.TimerException;\r
51 import org.commscope.tr069adapter.common.timer.TimerServiceManagerAPI;\r
52 import org.slf4j.Logger;\r
53 import org.slf4j.LoggerFactory;\r
54 import org.springframework.beans.factory.annotation.Autowired;\r
55 import org.springframework.context.ApplicationContext;\r
56 import org.springframework.jms.core.JmsTemplate;\r
57 \r
58 public class TR069RequestProcessEngineHelper {\r
59 \r
60   private static final Logger logger =\r
61       LoggerFactory.getLogger(TR069RequestProcessEngineHelper.class);\r
62 \r
63   @Autowired\r
64   private ApplicationContext context;\r
65 \r
66   @Autowired\r
67   private SessionManager sessionManager;\r
68 \r
69   @Autowired\r
70   private TimerServiceManagerAPI timerServiceManagerAPI;\r
71 \r
72   @Autowired\r
73   TR069RequestProcessorCacheUtil requestCacheUtil;\r
74 \r
75   @Autowired\r
76   protected TR069RequestProcessEngineUtility tr069RequestProcessEngineUtility;\r
77 \r
78   @Autowired\r
79   private JmsTemplate jmsTemplate;\r
80 \r
81   /**\r
82    * @param deviceId\r
83    * @return\r
84    * @throws SessionManagerException\r
85    */\r
86   protected SessionDTO getSession(String deviceId) {\r
87     logger.debug("Getting the existing Session Object for the device");\r
88     return sessionManager.getSession(deviceId);\r
89   }\r
90 \r
91   /**\r
92    * @param sessionId\r
93    * @return\r
94    * @throws SessionManagerException\r
95    */\r
96   public SessionDTO getSessionBySessionId(String sessionId) throws SessionManagerException {\r
97     return sessionManager.getSessionBySessionId(sessionId);\r
98   }\r
99 \r
100   /**\r
101    * @param deviceDetails\r
102    * @param session\r
103    */\r
104   protected void initThreadLocalCache(DeviceDetails deviceDetails, SessionDTO session) {\r
105     TR069RequestProcessorData tr069RequestProcessorData = new TR069RequestProcessorData();\r
106     tr069RequestProcessorData.setTr069DeviceDetails((TR069DeviceDetails) deviceDetails);\r
107     tr069RequestProcessorData.setSessionDTO(session);\r
108 \r
109     requestCacheUtil.put(tr069RequestProcessorData);\r
110   }\r
111 \r
112   /**\r
113    * @return\r
114    */\r
115   protected TR069RequestProcessorData getTR069RequestProcessorData() {\r
116     return requestCacheUtil.get();\r
117   }\r
118 \r
119   /**\r
120    * @return\r
121    */\r
122   protected String getUniqueSessionIdentifier() {\r
123     return sessionManager.generateUniqueSessionID();\r
124   }\r
125 \r
126   /**\r
127    * @param deviceId\r
128    * @param notificationType\r
129    * @return\r
130    * @throws SessionConcurrentAccessException\r
131    * @throws DeviceOperationException\r
132    */\r
133   protected SessionDTO acquireSessionLock(String deviceId, TR069InformType notificationType,\r
134       boolean generateNewSessionId)\r
135       throws SessionConcurrentAccessException, DeviceOperationException {\r
136     logger.debug("Acquiring the session lock for the device");\r
137     SessionDTO session = null;\r
138 \r
139     String sessionID = null;\r
140     session = sessionManager.getLockedSession(deviceId);\r
141 \r
142     if (session == null && TR069InformType.BOOTSTRAP.equals(notificationType)) {\r
143       logger.info(\r
144           "Device is contacting ACS for the first time, creating the new session ID for the device");\r
145       sessionID = getUniqueSessionIdentifier();\r
146       session = new SessionDTO(deviceId, sessionID, null);\r
147       session.setSessionStartTime(new Date());\r
148       try {\r
149         sessionManager.createSession(session);\r
150         generateNewSessionId = false;\r
151       } catch (Exception ex) {\r
152         SessionConcurrentAccessException scae =\r
153             new SessionConcurrentAccessException(ErrorCode.SESSION_ALREADY_LOCKED, ex.getMessage());\r
154         logger.error(scae.getMessage());\r
155         throw scae;\r
156       }\r
157 \r
158       session = sessionManager.getLockedSession(deviceId);\r
159     } else if (session == null) {\r
160       DeviceOperationException doe = new DeviceOperationException(ErrorCode.DEVICE_NOT_ACTIVATED);\r
161       logger.error(doe.getMessage());\r
162       throw doe;\r
163     }\r
164 \r
165     if (generateNewSessionId) {\r
166       sessionID = getUniqueSessionIdentifier();\r
167       session.setSessionId(sessionID);\r
168     }\r
169 \r
170     return session;\r
171   }\r
172 \r
173   /**\r
174    * @param session\r
175    * @throws SessionManagerException\r
176    */\r
177   protected void updateSession(SessionDTO session) {\r
178     logger.debug("Updating the session");\r
179     sessionManager.updateSession(session);\r
180   }\r
181 \r
182   /**\r
183    * @param deviceId\r
184    * @throws SessionConcurrentAccessException\r
185    */\r
186   protected void deleteSession(String deviceId) {\r
187     sessionManager.deleteSession(deviceId);\r
188   }\r
189 \r
190   /**\r
191    * Utility method to post the connection request initiation asynchronously on the device\r
192    * \r
193    * @param tr069DeviceDetails\r
194    */\r
195   protected void requestForConnectionRequestInform(TR069DeviceDetails tr069DeviceDetails) {\r
196     logger.info("Initiating Connection request on device: {}", tr069DeviceDetails.getDeviceId());\r
197     try {\r
198       jmsTemplate.convertAndSend(CR_REQ_Q, tr069DeviceDetails);\r
199     } catch (Exception e) {\r
200       logger.error("Connection request initiation failed, Reason: {}", e.getMessage());\r
201     }\r
202   }\r
203 \r
204   /**\r
205    * @param tr069RequestProcessorData\r
206    * @param sessionID\r
207    */\r
208   protected void updateSessionOnDeviceNotification(\r
209       TR069RequestProcessorData tr069RequestProcessorData, String sessionID) {\r
210     SessionDTO session = tr069RequestProcessorData.getSessionDTO();\r
211     session.setSessionId(sessionID);\r
212     session.setSessionStartTime(new Date());\r
213     session.setCurrentOperationId(null);\r
214     session.setSessionState(SessionState.PROCESSING);\r
215   }\r
216 \r
217   /**\r
218    * @param tr069RequestProcessorData\r
219    * @param sessionState\r
220    */\r
221   protected void changeSessionState(TR069RequestProcessorData tr069RequestProcessorData,\r
222       SessionState sessionState) {\r
223     SessionDTO session = tr069RequestProcessorData.getSessionDTO();\r
224     String oldSessionState =\r
225         (session.getSessionState() != null) ? session.getSessionState().name() : null;\r
226     String newSessionState = sessionState.name();\r
227     logger.debug("Changing the session state from {} to {}", oldSessionState, newSessionState);\r
228     session.setSessionState(sessionState);\r
229   }\r
230 \r
231   /**\r
232    * @param tr069RequestProcessorData\r
233    * @param operationId\r
234    */\r
235   protected void updateSessionCurOpId(TR069RequestProcessorData tr069RequestProcessorData,\r
236       Long operationId) {\r
237     SessionDTO session = tr069RequestProcessorData.getSessionDTO();\r
238     session.setCurrentOperationId(operationId);\r
239   }\r
240 \r
241   /**\r
242    * @param tr069RequestProcessorData\r
243    * @param deviceNotification\r
244    * @return\r
245    */\r
246   protected Boolean isDeviceUpdateExists(TR069RequestProcessorData tr069RequestProcessorData,\r
247       DeviceInform deviceNotification) {\r
248     Boolean isDeviceDataUpdated = false;\r
249     TR069DeviceDetails persistedDeviceDetails = tr069RequestProcessorData.getTr069DeviceDetails();\r
250     TR069DeviceDetails notificationDeviceDetails =\r
251         (TR069DeviceDetails) deviceNotification.getDeviceDetails();\r
252 \r
253     if (notificationDeviceDetails.getConnectionRequestURL() == null\r
254         || notificationDeviceDetails.getSoftwareVersion() == null\r
255         || notificationDeviceDetails.getHardwareVersion() == null) {\r
256       isDeviceDataUpdated = true;\r
257       logger.warn(\r
258           "Notification do not contains either connection request URL or swVer or hwVer of the device");\r
259       return isDeviceDataUpdated;\r
260     }\r
261 \r
262     if (!notificationDeviceDetails.getConnectionRequestURL()\r
263         .equals(persistedDeviceDetails.getConnectionRequestURL())\r
264         || !notificationDeviceDetails.getSoftwareVersion()\r
265             .equals(persistedDeviceDetails.getSoftwareVersion())\r
266         || !notificationDeviceDetails.getHardwareVersion()\r
267             .equals(persistedDeviceDetails.getHardwareVersion())) {\r
268       logger.debug("Device details are changed");\r
269       isDeviceDataUpdated = true;\r
270     }\r
271     return isDeviceDataUpdated;\r
272   }\r
273 \r
274   protected void updateDeviceDetails(TR069RequestProcessorData tr069RequestProcessorData,\r
275       DeviceInform deviceNotification) {\r
276     TR069DeviceDetails persistedDeviceDetails = tr069RequestProcessorData.getTr069DeviceDetails();\r
277     TR069DeviceDetails notificationDeviceDetails =\r
278         (TR069DeviceDetails) deviceNotification.getDeviceDetails();\r
279 \r
280     persistedDeviceDetails\r
281         .setConnectionRequestURL(notificationDeviceDetails.getConnectionRequestURL());\r
282     persistedDeviceDetails.setSoftwareVersion(notificationDeviceDetails.getSoftwareVersion());\r
283     persistedDeviceDetails.setHardwareVersion(notificationDeviceDetails.getHardwareVersion());\r
284   }\r
285 \r
286   /**\r
287    * @param customClassJNDI\r
288    * @param customOperationData\r
289    * @return\r
290    */\r
291   public CustomOperationData executeCustomOperation(String customClassJNDI,\r
292       CustomOperationData customOperationData) {\r
293     try {\r
294       logger.debug("Executing the custom logic implemented for JNDI: {}", customClassJNDI);\r
295       CustomOperation customOperation = (CustomOperation) context.getBean(customClassJNDI);\r
296       customOperationData =\r
297           (CustomOperationData) customOperation.executeCustomLogic(customOperationData);\r
298     } catch (Exception e) {\r
299       logger.error("Custom operation execution failed, Reason: {}", e.getMessage());\r
300     }\r
301     return customOperationData;\r
302   }\r
303 \r
304   /**\r
305    * returns the operation code for Custom function execution\r
306    * \r
307    * @param operationDetails\r
308    * @return\r
309    */\r
310   protected TR069OperationCode getCustomOperationCode(TR069OperationDetails operationDetails) {\r
311     List<ParameterDTO> deleteList = operationDetails.getDeleteParamList();\r
312     List<ParameterDTO> setList = operationDetails.getSetParamList();\r
313     List<ParameterDTO> modifyList = operationDetails.getModifyParamList();\r
314 \r
315     for (ParameterDTO param : deleteList) {\r
316       if (!param.isProcessed())\r
317         return TR069OperationCode.DELETE_OBJECT;\r
318     }\r
319 \r
320     for (ParameterDTO param : setList) {\r
321       if (!param.isProcessed())\r
322         return TR069OperationCode.ADD_OBJECT;\r
323     }\r
324 \r
325     for (ParameterDTO param : modifyList) {\r
326       if (!param.isProcessed())\r
327         return TR069OperationCode.SET_PARAMETER_VALUES;\r
328     }\r
329 \r
330     return TR069OperationCode.SET_PARAMETER_VALUES;\r
331   }\r
332 \r
333   /**\r
334    * @param deviceId\r
335    * @param operationId\r
336    * @param timeout\r
337    */\r
338   protected void startDeviceRPCRequestTimer(String deviceId, Long operationId, Long timeout) {\r
339     String timerId = deviceId + SEPERATOR + operationId;\r
340     if (null == timeout || timeout == 0L) {\r
341       timeout = DEVICE_RPC_EXECUTION_TIMEOUT_SECONDS;\r
342     }\r
343 \r
344     try {\r
345       timerServiceManagerAPI.startTimer(timerId, SESSION_TIMEOUT_CALLBACK_JNDI, (timeout * 1000),\r
346           WAITING_FOR_NBI_RESPONSE);\r
347       logger.debug(\r
348           "Successfully started the timer task for Device RPC request with operation ID : {}",\r
349           operationId);\r
350     } catch (TimerException e) {\r
351       logger.error("Couldn't start the timer task for Device RPC Request with operation ID : {}",\r
352           operationId);\r
353     }\r
354   }\r
355 \r
356   /**\r
357    * @param deviceId\r
358    * @param operationId\r
359    */\r
360   public void stopDeviceRPCRequestTimer(String deviceId, Long operationId) {\r
361     String timerId = deviceId + SEPERATOR + operationId;\r
362     try {\r
363       timerServiceManagerAPI.stopTimer(timerId);\r
364       logger.debug(\r
365           "Successfully stopped the timer task for Device RPC request with operation ID : {}",\r
366           operationId);\r
367     } catch (TimerException e) {\r
368       logger.error("Couldn't stop the timer task for Device RPC Request with operation ID : {}",\r
369           operationId);\r
370     }\r
371   }\r
372 \r
373   /**\r
374    * @param deviceId\r
375    * @param operationId\r
376    * @param timeout\r
377    */\r
378   protected void startSessionTimer(String sessionId) {\r
379     try {\r
380       timerServiceManagerAPI.startTimer(sessionId, SESSION_TIMEOUT_CALLBACK_JNDI,\r
381           DEVICE_RESPONSE_TIMEOUT, WAITING_FOR_DEVICE_RESPONSE);\r
382       logger.debug("Successfully started the timer task for Device request with session ID : {}",\r
383           sessionId);\r
384     } catch (TimerException e) {\r
385       logger.error("Couldn't start the timer task for Device Request with session ID : {}",\r
386           sessionId);\r
387     }\r
388   }\r
389 \r
390   /**\r
391    * @param deviceId\r
392    * @param operationId\r
393    */\r
394   protected void stopSessionTimer(String sessionId) {\r
395     try {\r
396       timerServiceManagerAPI.stopTimer(sessionId);\r
397       logger.debug("Successfully stopped the timer task for Device request with session ID : {}",\r
398           sessionId);\r
399     } catch (TimerException e) {\r
400       logger.error("Couldn't stop the timer task for Device Request with session ID : {}",\r
401           sessionId);\r
402     }\r
403   }\r
404 }\r