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