4597cbb9b46385cf74ea619ac09b861bf7672a04
[oam/tr069-adapter.git] / acs / cpe / src / main / java / org / commscope / tr069adapter / acs / cpe / handler / DeviceEventHandler.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.cpe.handler;\r
20 \r
21 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.CONNECTION_REQUEST;\r
22 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.SEPERATOR;\r
23 \r
24 import java.util.ArrayList;\r
25 import java.util.HashMap;\r
26 import java.util.List;\r
27 import java.util.Map;\r
28 import java.util.Set;\r
29 \r
30 import javax.servlet.http.HttpServletResponse;\r
31 \r
32 import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;\r
33 import org.commscope.tr069adapter.acs.common.DeviceRPCResponse;\r
34 import org.commscope.tr069adapter.acs.common.OperationResponse;\r
35 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
36 import org.commscope.tr069adapter.acs.common.dto.DeviceOperationRequestDetails;\r
37 import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;\r
38 import org.commscope.tr069adapter.acs.common.exception.SessionManagerException;\r
39 import org.commscope.tr069adapter.acs.common.exception.TR069EventProcessingException;\r
40 import org.commscope.tr069adapter.acs.common.inform.AbstractDeviceInform;\r
41 import org.commscope.tr069adapter.acs.common.inform.TransferCompleteInform;\r
42 import org.commscope.tr069adapter.acs.common.requestprocessor.service.TR069DeviceEventHandler;\r
43 import org.commscope.tr069adapter.acs.common.response.DeviceInformResponse;\r
44 import org.commscope.tr069adapter.acs.common.utils.ErrorCode;\r
45 import org.commscope.tr069adapter.acs.cpe.TR069RPC;\r
46 import org.commscope.tr069adapter.acs.cpe.builder.DeviceInformBuilder;\r
47 import org.commscope.tr069adapter.acs.cpe.builder.DeviceRPCBuilder;\r
48 import org.commscope.tr069adapter.acs.cpe.builder.DeviceRPCResponseBuilder;\r
49 import org.commscope.tr069adapter.acs.cpe.rpc.Fault;\r
50 import org.commscope.tr069adapter.acs.cpe.rpc.Inform;\r
51 import org.commscope.tr069adapter.acs.cpe.rpc.TransferComplete;\r
52 import org.commscope.tr069adapter.common.timer.TimerException;\r
53 import org.commscope.tr069adapter.common.timer.TimerServiceManagerAPI;\r
54 import org.slf4j.Logger;\r
55 import org.slf4j.LoggerFactory;\r
56 import org.slf4j.MDC;\r
57 import org.springframework.beans.factory.annotation.Autowired;\r
58 import org.springframework.stereotype.Component;\r
59 \r
60 @Component\r
61 public class DeviceEventHandler {\r
62 \r
63   private static final Logger logger = LoggerFactory.getLogger(DeviceEventHandler.class);\r
64 \r
65   private static final String CLIENT_STR = "client";\r
66 \r
67   @Autowired\r
68   private DeviceInformBuilder deviceInformBuilder;\r
69 \r
70   @Autowired\r
71   private DeviceRPCBuilder deviceRPCBuilder;\r
72 \r
73   @Autowired\r
74   private DeviceRPCResponseBuilder deviceRPCResponseBuilder;\r
75 \r
76   @Autowired\r
77   private TR069DeviceEventHandler tr069DeviceEventHandler;\r
78 \r
79   @Autowired\r
80   private TimerServiceManagerAPI timerServiceManagerAPI;\r
81 \r
82   @Autowired\r
83   private DeviceValidator deviceValidtor;\r
84 \r
85   private static Map<String, List<String>> informParameter = null;\r
86 \r
87   static {\r
88     informParameter = new HashMap<>();\r
89     List<String> parameters = new ArrayList<>();\r
90     parameters.add("InternetGatewayDevice.DeviceInfo.HardwareVersion");\r
91     parameters.add("InternetGatewayDevice.DeviceInfo.SoftwareVersion");\r
92     parameters.add("InternetGatewayDevice.DeviceInfo.ProvisioningCode");\r
93     parameters.add("InternetGatewayDevice.ManagementServer.ConnectionRequestURL");\r
94     parameters.add("InternetGatewayDevice.ManagementServer.ParameterKey");\r
95     informParameter.put("InternetGatewayDevice", parameters);\r
96 \r
97     List<String> deviceParameters = new ArrayList<>();\r
98     deviceParameters.add("Device.DeviceInfo.HardwareVersion");\r
99     deviceParameters.add("Device.DeviceInfo.SoftwareVersion");\r
100     deviceParameters.add("Device.DeviceInfo.ProvisioningCode");\r
101     deviceParameters.add("Device.ManagementServer.ConnectionRequestURL");\r
102     deviceParameters.add("Device.ManagementServer.ParameterKey");\r
103     informParameter.put("Device", deviceParameters);\r
104   }\r
105 \r
106   /**\r
107    * @param inform\r
108    * @param authorizationHeader\r
109    * @return\r
110    * @throws TR069EventProcessingException\r
111    */\r
112   public DeviceInformResponse processDeviceInform(Inform inform, String authorizationHeader)\r
113       throws TR069EventProcessingException {\r
114 \r
115     DeviceInformResponse deviceInformResponse = null;\r
116     try {\r
117       String deviceId = inform.getSn();\r
118       MDC.put(CLIENT_STR, deviceId);\r
119 \r
120       logger.info("Processing the device Inform event");\r
121 \r
122       logger.debug("Authorization header received in the request -> {}", authorizationHeader);\r
123       Boolean isAuthorized = deviceValidtor.isDeviceAuthorized(inform, authorizationHeader);\r
124       logger.info("Is device authentication successful: {}", isAuthorized);\r
125       if (!isAuthorized.booleanValue()) {\r
126         TR069EventProcessingException ex =\r
127             new TR069EventProcessingException(ErrorCode.UNAUTHORIZED_EVENT, "Authorization failed");\r
128         logger.error(ex.getMessage());\r
129         throw ex;\r
130       }\r
131 \r
132       logger.debug("The root element is: {}", inform.getRoot());\r
133       // Canceling any connection initiator timer running, due to inform event\r
134       stopConnectionInitiatorTimer(inform.getSn());\r
135 \r
136       if (!deviceValidtor.validateDevice(inform.getSn(), inform.getOui(), inform.getProductClass())\r
137           .booleanValue()) {\r
138         TR069EventProcessingException ex =\r
139             new TR069EventProcessingException(ErrorCode.OUI_OR_PC_MISMATCH);\r
140         logger.error(ex.getMessage());\r
141         throw ex;\r
142       }\r
143 \r
144       if (!validateInformParameters(inform)) {\r
145         TR069EventProcessingException ex =\r
146             new TR069EventProcessingException(ErrorCode.INVALID_PARAMS_IN_INFORM);\r
147         logger.error(ex.getMessage());\r
148         throw ex;\r
149       }\r
150 \r
151       AbstractDeviceInform deviceInform = deviceInformBuilder.constructDeviceInform(inform);\r
152       if (deviceInform == null) {\r
153         TR069EventProcessingException ex =\r
154             new TR069EventProcessingException(ErrorCode.INVALID_PARAMS_IN_INFORM);\r
155         logger.error(ex.getMessage());\r
156         throw ex;\r
157       }\r
158 \r
159       logger.debug("Sending the device inform to TR069 Request Processor to process");\r
160       deviceInformResponse = tr069DeviceEventHandler.processDeviceInform(deviceInform);\r
161 \r
162     } catch (TR069EventProcessingException tr069Ex) {\r
163       throw tr069Ex;\r
164     } catch (Exception e) {\r
165       TR069EventProcessingException ex =\r
166           new TR069EventProcessingException(ErrorCode.FAILED_PROCESSING_INFORM, e.getMessage());\r
167       logger.error(ex.getMessage());\r
168       throw ex;\r
169     } finally {\r
170       MDC.remove(CLIENT_STR);\r
171     }\r
172 \r
173     return deviceInformResponse;\r
174 \r
175   }\r
176 \r
177   /**\r
178    * @param tc\r
179    * @return\r
180    * @throws TR069EventProcessingException\r
181    */\r
182   public DeviceInformResponse processTransferComplete(TransferComplete tc)\r
183       throws TR069EventProcessingException {\r
184 \r
185     logger.debug("Processing Transfer Complete");\r
186 \r
187     String startTime = tc.getStartTime();\r
188     String completeTime = tc.getCompleteTime();\r
189     int faultCode = tc.getFaultCode();\r
190     String faultString = tc.getFaultString();\r
191     String commandKey = tc.getCommandKey();\r
192 \r
193     DeviceInformResponse deviceInformResponse = null;\r
194 \r
195     try {\r
196       MDC.put(CLIENT_STR, commandKey);\r
197       TransferCompleteInform transferCompleteInform = new TransferCompleteInform();\r
198       transferCompleteInform.setCommandKey(tc.getCommandKey());\r
199       transferCompleteInform.setCompleteTime(completeTime);\r
200       transferCompleteInform.setFaultCode(faultCode);\r
201       transferCompleteInform.setFaultString(faultString);\r
202       transferCompleteInform.setStartTime(startTime);\r
203 \r
204       logger.debug("TransferComplete inform received with Start time");\r
205 \r
206       transferCompleteInform.setDeviceDetails(tr069DeviceEventHandler.getDeviceDetails(commandKey));\r
207       deviceInformResponse = tr069DeviceEventHandler.processDeviceInform(transferCompleteInform);\r
208       logger.debug("Successfully processed the TRANSFER COMPLETE Inform");\r
209 \r
210     } catch (Exception e) {\r
211       throw new TR069EventProcessingException(ErrorCode.FAILED_PROCESSING_INFORM, e.getMessage());\r
212     } finally {\r
213       MDC.remove(CLIENT_STR);\r
214     }\r
215 \r
216     return deviceInformResponse;\r
217   }\r
218 \r
219   /**\r
220    * @param msg\r
221    * @param sessionId\r
222    * @return\r
223    * @throws TR069EventProcessingException\r
224    */\r
225   public TR069RPC processRPCResponse(TR069RPC msg, String sessionId)\r
226       throws TR069EventProcessingException {\r
227     DeviceOperationRequestDetails deviceOperationRequestDetails = null;\r
228     try {\r
229       deviceOperationRequestDetails =\r
230           tr069DeviceEventHandler.getOpRequestDetailsBySessionId(sessionId);\r
231       if (null == deviceOperationRequestDetails\r
232           || null == deviceOperationRequestDetails.getDeviceDetails()) {\r
233         logger.error("Response with invalid session ID: {}", sessionId);\r
234         return null;\r
235       }\r
236 \r
237       String deviceId = deviceOperationRequestDetails.getDeviceDetails().getDeviceId();\r
238       MDC.put(CLIENT_STR, deviceId);\r
239       DeviceRPCResponse deviceRPCResponse = new DeviceRPCResponse();\r
240       deviceRPCResponse.setDeviceDetails(deviceOperationRequestDetails.getDeviceDetails());\r
241       deviceRPCResponse.setOperationId(deviceOperationRequestDetails.getOperationId());\r
242       OperationResponse operationResponse = null;\r
243       if (msg instanceof Fault) {\r
244         Fault values = (Fault) msg;\r
245         logger.info("{} ID->{} faultCode->{} faultString->{}", values.getName(), values.getId(),\r
246             values.getCwmpFaultCode(), values.getFaultStringCwmp());\r
247         deviceRPCResponse.setFaultKey(values.getCwmpFaultCode());\r
248         deviceRPCResponse.setFaultString(\r
249             values.getFaultStringCwmp() + ": Error code: " + values.getCwmpFaultCode());\r
250 \r
251         TR069OperationCode operationCode =\r
252             (TR069OperationCode) deviceOperationRequestDetails.getOpCode();\r
253         operationResponse = constructResponseForFault(operationCode);\r
254         if (operationResponse != null) {\r
255           operationResponse.setStatus(1);\r
256           operationResponse.setParameterDTOs(new ArrayList<ParameterDTO>());\r
257         }\r
258       } else {\r
259         operationResponse = deviceRPCResponseBuilder.constructDeviceRPCResponse(msg);\r
260       }\r
261       deviceRPCResponse.setOperationResponse(operationResponse);\r
262 \r
263       DeviceRPCRequest deviceRPCRequest =\r
264           tr069DeviceEventHandler.processDeviceRPCResponse(deviceRPCResponse);\r
265       if (null != deviceRPCRequest) {\r
266         return deviceRPCBuilder.constructDeviceRPC(deviceRPCRequest);\r
267       }\r
268     } catch (SessionManagerException e) {\r
269       logger.error("Error while getting device detail for the session id: {}", sessionId);\r
270     } catch (Exception e) {\r
271       throw new TR069EventProcessingException(ErrorCode.FAILED_PROCESSING_RPC_RESPONSE,\r
272           msg.getName(), e.getMessage());\r
273     } finally {\r
274       MDC.remove(CLIENT_STR);\r
275     }\r
276 \r
277     return null;\r
278   }\r
279 \r
280   /**\r
281    * @param sessionId\r
282    * @return\r
283    * @throws TR069EventProcessingException\r
284    */\r
285   public TR069RPC processEmptyRequest(String sessionId) throws TR069EventProcessingException {\r
286     try {\r
287       DeviceOperationRequestDetails deviceOperationRequestDetails =\r
288           tr069DeviceEventHandler.getOpRequestDetailsBySessionId(sessionId);\r
289       DeviceRPCRequest deviceRPCRequest = null;\r
290       String deviceId = deviceOperationRequestDetails.getDeviceDetails().getDeviceId();\r
291       MDC.put(CLIENT_STR, deviceId);\r
292       deviceRPCRequest = tr069DeviceEventHandler\r
293           .processEmptyDeviceRequest(deviceOperationRequestDetails.getDeviceDetails());\r
294       if (null == deviceRPCRequest) {\r
295         return null;\r
296       } else {\r
297         logger.debug("There exists a NBI request to process.");\r
298         return deviceRPCBuilder.constructDeviceRPC(deviceRPCRequest);\r
299       }\r
300     } catch (SessionManagerException e) {\r
301       logger.error("Error while processing empty request, reason: {}", e.getMessage());\r
302     } catch (Exception e) {\r
303       throw new TR069EventProcessingException(ErrorCode.EMPTY_REQUEST_PROCESSING_ERROR,\r
304           e.getMessage());\r
305     } finally {\r
306       MDC.remove(CLIENT_STR);\r
307     }\r
308     return null;\r
309   }\r
310 \r
311   /**\r
312    * @param operationCode\r
313    * @return\r
314    */\r
315   private OperationResponse constructResponseForFault(TR069OperationCode operationCode) {\r
316     OperationResponse operationResponse = null;\r
317     if (operationCode.equals(TR069OperationCode.ADD_OBJECT)) {\r
318       operationResponse = new org.commscope.tr069adapter.acs.common.response.AddObjectResponse();\r
319     } else if (operationCode.equals(TR069OperationCode.DELETE_OBJECT)) {\r
320       operationResponse = new org.commscope.tr069adapter.acs.common.response.DeleteObjectResponse();\r
321     } else if (operationCode.equals(TR069OperationCode.SET_PARAMETER_VALUES)) {\r
322       operationResponse =\r
323           new org.commscope.tr069adapter.acs.common.response.SetParameterValueResponse();\r
324     } else if (operationCode.equals(TR069OperationCode.GET_PARAMETER_VALUES)) {\r
325       operationResponse =\r
326           new org.commscope.tr069adapter.acs.common.response.GetParameterValueResponse();\r
327     } else if (operationCode.equals(TR069OperationCode.GET_PARAMETER_ATTRIBUTES)) {\r
328       operationResponse =\r
329           new org.commscope.tr069adapter.acs.common.response.GetParameterAttributeResponse();\r
330     }\r
331     return operationResponse;\r
332   }\r
333 \r
334   /**\r
335    * @param serialNumber\r
336    */\r
337   public void stopConnectionInitiatorTimer(String serialNumber) {\r
338     String timerId = serialNumber + SEPERATOR + CONNECTION_REQUEST;\r
339     try {\r
340       logger\r
341           .debug("Canceling the Connection initiation timer, as Inform is been sent by the device");\r
342       timerServiceManagerAPI.stopTimer(timerId);\r
343     } catch (TimerException e) {\r
344       logger.error(\r
345           "An exception occurred while stopping the connection initiator session timer, Reason: {}",\r
346           e.getMessage());\r
347     }\r
348   }\r
349 \r
350   /**\r
351    * @param lastInform\r
352    * @return\r
353    */\r
354   private boolean validateInformParameters(Inform lastInform) {\r
355     boolean validate = false;\r
356     String root = lastInform.getRoot();\r
357     if (!informParameter.containsKey(root))\r
358       return validate;\r
359     List<String> params = informParameter.get(root);\r
360     Set<String> keySet = lastInform.getParams().keySet();\r
361     validate = true;\r
362     for (String param : params) {\r
363       if (!keySet.contains(param)) {\r
364         logger.warn("This param Not found in the inform {}", param);\r
365         validate = false;\r
366         break;\r
367       }\r
368     }\r
369     return validate;\r
370   }\r
371 \r
372   /**\r
373    * @param tr069ex\r
374    * @return\r
375    */\r
376   public int handleException(TR069EventProcessingException tr069ex) {\r
377 \r
378     int errorresponseCode = 0;\r
379 \r
380     ErrorCode errorCode = tr069ex.getErrorCode();\r
381     switch (errorCode) {\r
382       case UNSUPPORTED_CHARACTER_ENCODING:\r
383       case INVALID_PARAMS_IN_INFORM:\r
384       case FAILED_PROCESSING_INFORM:\r
385         errorresponseCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;\r
386         break;\r
387       case UNAUTHORIZED_EVENT:\r
388         errorresponseCode = HttpServletResponse.SC_UNAUTHORIZED;\r
389         break;\r
390       default:\r
391         break;\r
392     }\r
393 \r
394     return errorresponseCode;\r
395   }\r
396 \r
397   /***************************************************************************************************************************/\r
398 \r
399   public void setDeviceInformBuilder(DeviceInformBuilder deviceInformBuilder) {\r
400     this.deviceInformBuilder = deviceInformBuilder;\r
401   }\r
402 \r
403   public void setDeviceRPCBuilder(DeviceRPCBuilder deviceRPCBuilder) {\r
404     this.deviceRPCBuilder = deviceRPCBuilder;\r
405   }\r
406 \r
407   public void setDeviceRPCResponseBuilder(DeviceRPCResponseBuilder deviceRPCResponseBuilder) {\r
408     this.deviceRPCResponseBuilder = deviceRPCResponseBuilder;\r
409   }\r
410 \r
411   public void setTr069DeviceEventHandler(TR069DeviceEventHandler tr069DeviceEventHandler) {\r
412     this.tr069DeviceEventHandler = tr069DeviceEventHandler;\r
413   }\r
414 \r
415   public void setTimerServiceManagerAPI(TimerServiceManagerAPI timerServiceManagerAPI) {\r
416     this.timerServiceManagerAPI = timerServiceManagerAPI;\r
417   }\r
418 \r
419   public void setDeviceAuthenticator(DeviceValidator deviceAuthenticator) {\r
420     this.deviceValidtor = deviceAuthenticator;\r
421   }\r
422 \r
423 }\r