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
11 * http://www.apache.org/licenses/LICENSE-2.0
\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
19 package org.commscope.tr069adapter.acs.requestprocessor.impl;
\r
21 import static org.commscope.tr069adapter.acs.common.utils.AcsConstants.SESSION_ID;
\r
23 import java.util.List;
\r
25 import org.commscope.tr069adapter.acs.common.DeviceDetails;
\r
26 import org.commscope.tr069adapter.acs.common.DeviceInform;
\r
27 import org.commscope.tr069adapter.acs.common.DeviceRPCRequest;
\r
28 import org.commscope.tr069adapter.acs.common.DeviceRPCResponse;
\r
29 import org.commscope.tr069adapter.acs.common.OperationCode;
\r
30 import org.commscope.tr069adapter.acs.common.OperationDetails;
\r
31 import org.commscope.tr069adapter.acs.common.OperationResponse;
\r
32 import org.commscope.tr069adapter.acs.common.dto.CustomOperationCode;
\r
33 import org.commscope.tr069adapter.acs.common.dto.DeviceOperationRequestDetails;
\r
34 import org.commscope.tr069adapter.acs.common.dto.TR069DeviceDetails;
\r
35 import org.commscope.tr069adapter.acs.common.dto.TR069InformType;
\r
36 import org.commscope.tr069adapter.acs.common.dto.TR069OperationCode;
\r
37 import org.commscope.tr069adapter.acs.common.dto.TR069OperationDetails;
\r
38 import org.commscope.tr069adapter.acs.common.exception.DeviceOperationException;
\r
39 import org.commscope.tr069adapter.acs.common.exception.SessionConcurrentAccessException;
\r
40 import org.commscope.tr069adapter.acs.common.exception.SessionManagerException;
\r
41 import org.commscope.tr069adapter.acs.common.exception.TR069EventProcessingException;
\r
42 import org.commscope.tr069adapter.acs.common.faults.AcsFaultCode;
\r
43 import org.commscope.tr069adapter.acs.common.inform.BootInform;
\r
44 import org.commscope.tr069adapter.acs.common.inform.BootstrapInform;
\r
45 import org.commscope.tr069adapter.acs.common.response.DeviceInformResponse;
\r
46 import org.commscope.tr069adapter.acs.common.utils.ErrorCode;
\r
47 import org.commscope.tr069adapter.acs.requestprocessor.DeviceOperationInterface;
\r
48 import org.commscope.tr069adapter.acs.requestprocessor.dao.DeviceRPCRequestRepositoryHelper;
\r
49 import org.commscope.tr069adapter.acs.requestprocessor.dto.CustomOperationData;
\r
50 import org.commscope.tr069adapter.acs.requestprocessor.dto.SessionDTO;
\r
51 import org.commscope.tr069adapter.acs.requestprocessor.dto.SessionState;
\r
52 import org.commscope.tr069adapter.acs.requestprocessor.dto.TR069RequestProcessorData;
\r
53 import org.commscope.tr069adapter.acs.requestprocessor.entity.TR069DeviceRPCRequestEntity;
\r
54 import org.commscope.tr069adapter.acs.requestprocessor.helper.TR069RequestProcessEngineHelper;
\r
55 import org.commscope.tr069adapter.acs.requestprocessor.util.TR069RequestProcessorUtility;
\r
56 import org.slf4j.Logger;
\r
57 import org.slf4j.LoggerFactory;
\r
58 import org.springframework.beans.factory.annotation.Autowired;
\r
59 import org.springframework.stereotype.Component;
\r
62 public class TR069RequestProcessEngine extends TR069RequestProcessEngineHelper {
\r
64 private static final String PENDING_RPC_CHECK =
\r
65 "Checking if any pending Device RPC requests exists for the device";
\r
67 private static final Logger logger = LoggerFactory.getLogger(TR069RequestProcessEngine.class);
\r
70 TR069EventNotificationService tr069EventNotificationService;
\r
73 DeviceOperationInterface deviceOperationInterface;
\r
76 protected DeviceRPCRequestRepositoryHelper deviceRPCRequestRepositoryHelper;
\r
79 * @param deviceRPCRequest
\r
80 * @throws TR069EventProcessingException
\r
81 * @throws SessionConcurrentAccessException
\r
83 public void processDeviceRPCRequest(DeviceRPCRequest deviceRPCRequest)
\r
84 throws TR069EventProcessingException, SessionConcurrentAccessException {
\r
86 DeviceRPCResponse deviceRPCResponse = null;
\r
87 String deviceId = null;
\r
90 if (deviceRPCRequest == null) {
\r
91 TR069EventProcessingException ex =
\r
92 new TR069EventProcessingException(ErrorCode.INVALID_NBI_REQUEST);
\r
93 logger.error(ex.getMessage());
\r
97 Long operationId = deviceRPCRequest.getOperationId();
\r
98 logger.info("A Mapper request is received with operationID: {}", operationId);
\r
99 TR069DeviceDetails tr069DeviceDetails = null;
\r
100 deviceId = deviceRPCRequest.getDeviceDetails().getDeviceId();
\r
102 tr069DeviceDetails = deviceOperationInterface.getDeviceDetails(deviceId);
\r
103 deviceRPCResponse = checkForDeviceAvailabilityRequest(deviceRPCRequest, tr069DeviceDetails);
\r
104 if (null != deviceRPCResponse) {
\r
107 } catch (DeviceOperationException | SessionManagerException deo) {
\r
108 logger.error(deo.getMessage());
\r
109 deviceRPCResponse = tr069RequestProcessEngineUtility.buildAbortedOperationresult(
\r
110 tr069DeviceDetails, deviceRPCRequest, AcsFaultCode.FAULT_CODE_8000);
\r
115 SessionDTO sessionDTO = acquireSessionLockWithRetryOnFailure(deviceId, operationId);
\r
117 logger.debug("Persisting the Device RPC request, with operation ID: {}", operationId);
\r
118 List<TR069DeviceRPCRequestEntity> tr069DeviceRPCRequestEntities =
\r
119 TR069RequestProcessorUtility.convertToEntity(deviceRPCRequest);
\r
120 deviceRPCRequestRepositoryHelper.saveAll(tr069DeviceRPCRequestEntities);
\r
121 logger.info("Successfully persisted the Device RPC request");
\r
123 if (sessionDTO != null) {
\r
124 if (SessionState.TERMINATED.equals(sessionDTO.getSessionState())) {
\r
125 logger.debug("No active session exists, hence requesting for Connection request");
\r
126 requestForConnectionRequestInform(tr069DeviceDetails);
\r
128 // Start Request Timer
\r
129 startDeviceRPCRequestTimer(deviceId, deviceRPCRequest.getOperationId(),
\r
130 deviceRPCRequest.getOptions().getExecutionTimeout());
\r
133 "Session is in processing state, Will be notified to session manager to pick the request on session availability");
\r
137 "The device is not activated yet, hence the NBI Operation result cannot be processed!");
\r
138 deviceRPCResponse = tr069RequestProcessEngineUtility.buildAbortedOperationresult(
\r
139 tr069DeviceDetails, deviceRPCRequest, AcsFaultCode.FAULT_CODE_8001);
\r
141 } catch (SessionConcurrentAccessException scae) {
\r
143 } catch (Exception e) {
\r
144 logger.error("An unknown exception occurred while processing the NBI request, Reason: {}",
\r
146 deviceRPCResponse = tr069RequestProcessEngineUtility.buildAbortedOperationresult(
\r
147 tr069DeviceDetails, deviceRPCRequest, AcsFaultCode.FAULT_CODE_8004);
\r
150 if (deviceRPCResponse != null) {
\r
151 logger.debug("Sending failed operation result for this NBI request");
\r
152 tr069EventNotificationService.sendOperationResultToNBI(deviceRPCResponse);
\r
153 // Marking the NBI Request as processed
\r
154 deviceRPCRequestRepositoryHelper.markDeviceRPCRequestAsProcessed(deviceId,
\r
155 deviceRPCRequest.getOperationId());
\r
160 private DeviceRPCResponse checkForDeviceAvailabilityRequest(DeviceRPCRequest deviceRPCRequest,
\r
161 TR069DeviceDetails tr069DeviceDetails) throws SessionManagerException {
\r
162 DeviceRPCResponse deviceRPCResponse = null;
\r
164 if (!deviceRPCRequest.getOpDetails().getOpCode().equals(CustomOperationCode.CONNECT)) {
\r
165 return deviceRPCResponse;
\r
168 SessionDTO sessionDTO = getSession(tr069DeviceDetails.getDeviceId());
\r
170 if (null != sessionDTO && !SessionState.TERMINATED.equals(sessionDTO.getSessionState())) {
\r
171 logger.debug("Device is reachable as device tr069 session is in {} state.",
\r
172 sessionDTO.getSessionState());
\r
174 deviceRPCResponse = new DeviceRPCResponse();
\r
175 deviceRPCResponse.setDeviceDetails(tr069DeviceDetails);
\r
176 deviceRPCResponse.setOperationId(deviceRPCRequest.getOperationId());
\r
178 OperationResponse operationResponse = new OperationResponse();
\r
179 // device reachable...change value 1 to some constant or enum
\r
180 operationResponse.setStatus(TR069RequestProcessorUtility.DEVICE_REACHABLE_STATUS_CODE);
\r
181 operationResponse.setOperationCode(deviceRPCRequest.getOpDetails().getOpCode());
\r
183 deviceRPCResponse.setOperationResponse(operationResponse);
\r
186 return deviceRPCResponse;
\r
190 * Common Step 1. Since there can exist only one Inform from any device, which will be the
\r
191 * initiator of the session, following steps to be followed a. Stop the session timer for this
\r
192 * device if any running. b. Get the lock by reading the session record for this device from DB
\r
193 * and load the session object in Thread Local Cache c. Create a new session id from
\r
194 * SessionManager, and update the session object with new Session id and change the state to
\r
195 * PROCESSING. 2. Read the Device record from the DB, and load the device DTO also in the
\r
198 * Common Notification Specific Step 1. Take the connection request URL from the
\r
199 * deviceNotification object 2. Update the Device DTO object with connection request URL,
\r
200 * swVersion, hwVersion if there is a difference. Update the last updated time if updated 3. Send
\r
201 * this Inform to the NBI, by calling the ProcessDeviceInform method on TR069NBIService module. 4.
\r
202 * Create the Inform response Object and update the sessionID used for this transaction in the
\r
203 * response which will be used in the cookie of the HTTP response 5. Post the message into
\r
204 * Response Queue 6. Change the session state to LOCKED 7. Save the Session and device records
\r
205 * with the values in ThreadLocalCache 8. Start the session timer and default request timer (As
\r
206 * configured for all the requests from device) 8. All the above steps to be executed in a single
\r
209 * @param deviceNotification
\r
211 * @throws SessionConcurrentAccessException
\r
213 public DeviceInformResponse processDeviceInform(DeviceInform deviceNotification)
\r
214 throws SessionConcurrentAccessException {
\r
216 String deviceId = deviceNotification.getDeviceDetails().getDeviceId();
\r
217 TR069InformType notificationType = (TR069InformType) deviceNotification.getInformType();
\r
218 logger.info("Processing the Device Inform Event: '{}'", notificationType.getNotificationCode());
\r
219 String newSessionId = null;
\r
220 SessionDTO session = null;
\r
221 TR069DeviceDetails deviceDetails = null;
\r
222 DeviceInformResponse informResponse = null;
\r
226 SessionDTO sessionDTO = getSession(deviceId);
\r
227 if (sessionDTO != null && !SessionState.TERMINATED.equals(sessionDTO.getSessionState())) {
\r
228 String sessionId = sessionDTO.getSessionId();
\r
230 "The session with session id {} is not terminated, hence stopping the associated timer",
\r
232 stopSessionTimer(sessionDTO.getSessionId());
\r
235 // To stop the request timer if any running for this device, and send failed operation
\r
236 // result for any such pending cases. Requests pending in DB should not be cleared
\r
239 * Read any pending records in TR069_NBI_REQUEST table for this device. Send abort operation
\r
240 * result for all the pending requests Delete the records from the TR069_NBI_Request table for
\r
243 if (deviceNotification instanceof BootstrapInform
\r
244 || deviceNotification instanceof BootInform) {
\r
245 sendAbortedOperationResultForPendingRPCRequests(deviceNotification.getDeviceDetails(),
\r
249 session = acquireSessionLock(deviceId, notificationType, true);
\r
250 deviceDetails = getPersistedDeviceDetails(deviceId, deviceNotification);
\r
252 newSessionId = session.getSessionId();
\r
253 logger.debug("The session id generated to process the device notification request is: {} ",
\r
256 initThreadLocalCache(deviceDetails, session);
\r
257 TR069RequestProcessorData tr069RequestProcessorData = getTR069RequestProcessorData();
\r
258 updateSessionOnDeviceNotification(tr069RequestProcessorData, newSessionId);
\r
260 logger.debug("Sending the Device Inform Event to the Mapper");
\r
261 tr069EventNotificationService.sendDeviceInformToNBI(deviceNotification);
\r
263 updateDeviceDetailsFromInform(tr069RequestProcessorData, deviceNotification);
\r
265 logger.debug("Updating the session for the device with newly generated session id");
\r
266 changeSessionState(tr069RequestProcessorData, SessionState.LOCKED);
\r
267 updateSession(session);
\r
269 // Start session timer - Get a default timeout for session.
\r
270 startSessionTimer(session.getSessionId());
\r
273 new DeviceInformResponse(newSessionId, deviceNotification.getDeviceDetails());
\r
276 DeviceOperationException doe) {
\r
277 logger.error(doe.getMessage());
\r
278 } catch (SessionConcurrentAccessException scae) {
\r
280 } catch (Exception e) {
\r
281 throw new SessionConcurrentAccessException(ErrorCode.UNKNOWN_ERROR, e.getMessage());
\r
283 return informResponse;
\r
288 * 1. Stop the request timer for this device using the session ID received in the cookie of the
\r
289 * request 2. Read the session record from the session table into ThreadLocalCache 3. Move the
\r
290 * session state to PROCESSING and update the OPERATION_ID as null. 4a. Session Manager to check
\r
291 * if any pending request being notified for the device using in memory cache - Not planned for
\r
292 * this Drop 4. As an interim solution for drop1, Check the TR069_NBI_REQUEST table if any request
\r
295 * if (anyPendingRequestExists) { 1. Pick the request with the least created_time 2. Create the
\r
296 * response object and update the sessionID used for this transaction in the response which will
\r
297 * be used in the cookie of the HTTP response 3. Post the response object into Response Queue 4.
\r
298 * Change the session state to LOCKED and update the OPERATION_ID in the session table with the
\r
299 * NBI requests OPERATION_ID. 5. Save the Session record with the values in ThreadLocalCache 6.
\r
300 * Start the session timer and request timer (available in the request) } else { 1. Move the
\r
301 * session state to PROCESSING and update the OPERATION_ID as null. 2. Save the Session record
\r
302 * with the values in ThreadLocalCache. 3. Start the session timer. }
\r
304 * 6. All the above steps to be executed in a single transaction
\r
306 * @param deviceRPCResponse
\r
308 * @throws SessionConcurrentAccessException
\r
310 public DeviceRPCRequest processDeviceRPCResponse(DeviceRPCResponse deviceRPCResponse)
\r
311 throws SessionConcurrentAccessException {
\r
312 TR069DeviceDetails deviceDetails = (TR069DeviceDetails) deviceRPCResponse.getDeviceDetails();
\r
313 String deviceId = deviceDetails.getDeviceId();
\r
314 logger.info("Processing the operation response from device");
\r
316 SessionDTO session;
\r
317 DeviceRPCRequest deviceRPCRequest = null;
\r
319 session = acquireSessionLock(deviceId, null, false);
\r
320 String newSessionId = session.getSessionId();
\r
321 logger.debug("The session id used to process the device RPC response is: {}", newSessionId);
\r
323 initThreadLocalCache(deviceDetails, session);
\r
324 TR069RequestProcessorData tr069RequestProcessorData = getTR069RequestProcessorData();
\r
325 updateSessionOnDeviceNotification(tr069RequestProcessorData, newSessionId);
\r
327 Long operationId = deviceRPCResponse.getOperationId();
\r
329 deviceRPCRequest = getNextRPCRequest(deviceId, operationId);
\r
331 if (deviceRPCRequest != null) {
\r
332 OperationDetails opDetails = deviceRPCRequest.getOpDetails();
\r
333 if (opDetails != null) {
\r
334 OperationCode opCode = opDetails.getOpCode();
\r
335 if (opCode instanceof CustomOperationCode) {
\r
336 CustomOperationCode customOperationCode = (CustomOperationCode) opCode;
\r
337 String customOperationCodeName = customOperationCode.name();
\r
339 "The Device RPC request is of custom type, the custom operation to be performed is: {}",
\r
340 customOperationCodeName);
\r
341 String jndiName = customOperationCode.getJndiName();
\r
342 CustomOperationData customOperationData =
\r
343 new CustomOperationData(deviceDetails, deviceRPCResponse, deviceRPCRequest);
\r
344 customOperationData = executeCustomOperation(jndiName, customOperationData);
\r
346 DeviceRPCRequest operationRequest = customOperationData.getDeviceRPCRequest();
\r
347 deviceRPCResponse = customOperationData.getDeviceRPCResponse();
\r
348 if (operationRequest != null) {
\r
349 return handleOperationRequest(deviceRPCResponse, session, deviceRPCRequest,
\r
350 newSessionId, tr069RequestProcessorData, operationRequest);
\r
352 logger.debug(PENDING_RPC_CHECK);
\r
354 deviceRPCRequestRepositoryHelper.findOldestDeviceRPCRequest(deviceId);
\r
360 if (deviceRPCRequest != null) {
\r
361 logger.info("A pending Device RPC request exists for the device with operation ID: {}",
\r
362 deviceRPCRequest.getOperationId());
\r
363 updateSessionCurOpId(tr069RequestProcessorData, deviceRPCRequest.getOperationId());
\r
364 changeSessionState(tr069RequestProcessorData, SessionState.LOCKED);
\r
366 deviceRPCRequest.addContextParam(SESSION_ID, newSessionId);
\r
370 "No pending Device RPC request exists for the device, hence empty response will be sent to the device");
\r
371 logger.debug("Updating the session to terminated state");
\r
372 // To stop the session timer if any running for this device.
\r
373 stopSessionTimer(newSessionId);
\r
374 changeSessionState(tr069RequestProcessorData, SessionState.TERMINATED);
\r
377 // To stop the request timer if any running for this operation.
\r
378 stopDeviceRPCRequestTimer(deviceId, deviceRPCResponse.getOperationId());
\r
380 // Sending the operation response to NBI
\r
381 logger.debug("Sending the Device RPC Response to the Mapper");
\r
382 tr069EventNotificationService.sendOperationResultToNBI(deviceRPCResponse);
\r
384 updateSession(session);
\r
385 } catch (DeviceOperationException doe) {
\r
386 logger.error(doe.getMessage());
\r
387 } catch (SessionConcurrentAccessException scae) {
\r
391 return deviceRPCRequest;
\r
394 private DeviceRPCRequest handleOperationRequest(DeviceRPCResponse deviceRPCResponse,
\r
395 SessionDTO session, DeviceRPCRequest deviceRPCRequest, String newSessionId,
\r
396 TR069RequestProcessorData tr069RequestProcessorData, DeviceRPCRequest operationRequest) {
\r
397 operationRequest.addContextParam(SESSION_ID, newSessionId);
\r
398 updateSessionCurOpId(tr069RequestProcessorData, deviceRPCRequest.getOperationId());
\r
399 changeSessionState(tr069RequestProcessorData, SessionState.LOCKED);
\r
400 updateSession(session);
\r
401 if (deviceRPCResponse != null && operationRequest.getOperationId() != null
\r
402 && !operationRequest.getOperationId().equals(deviceRPCResponse.getOperationId())) {
\r
404 .debug("Sending the Device RPC response for a configure Multiple object prior operation");
\r
405 // Sending the operation response to NBI
\r
406 tr069EventNotificationService.sendOperationResultToNBI(deviceRPCResponse);
\r
408 return operationRequest;
\r
413 * 1. Stop the request timer for this device using the session ID received in the cookie of the
\r
414 * request 2. Read the session record from the session table into ThreadLocalCache 3. Move the
\r
415 * session state to PROCESSING and update the OPERATION_ID as null. 4a. Session Manager to check
\r
416 * if any pending request being notified for the device using in memory cache - Not planned for
\r
417 * this Drop 4. As an interim solution for drop1, Check the TR069_NBI_REQUEST table if any request
\r
420 * if (anyPendingRequestExists) { 1. Pick the request with the least created_time 2. Create the
\r
421 * response object and update the sessionID used for this transaction in the response which will
\r
422 * be used in the cookie of the HTTP response 3. Post the response object into Response Queue 4.
\r
423 * Change the session state to LOCKED and update the OPERATION_ID in the session table with the
\r
424 * NBI requests OPERATION_ID. 5. Save the Session record with the values in ThreadLocalCache 6.
\r
425 * Start the session timer and request timer (available in the request) } else { 1. Move the
\r
426 * session state to PROCESSING and update the OPERATION_ID as null. 2. Save the Session record
\r
427 * with the values in ThreadLocalCache. 3. Start the session timer. }
\r
429 * 6. All the above steps to be executed in a single transaction
\r
431 * @param deviceDetails
\r
433 * @throws SessionConcurrentAccessException
\r
435 public DeviceRPCRequest processEmptyDeviceRequest(TR069DeviceDetails deviceDetails)
\r
436 throws SessionConcurrentAccessException {
\r
437 String deviceId = deviceDetails.getDeviceId();
\r
438 logger.info("Processing the empty request from device");
\r
440 SessionDTO session;
\r
441 DeviceRPCRequest nbiDeviceOperationRequest = null;
\r
443 session = acquireSessionLock(deviceId, null, false);
\r
444 String newSessionId = session.getSessionId();
\r
445 logger.debug("The session id used to process the empty device request is: {}", newSessionId);
\r
447 initThreadLocalCache(deviceDetails, session);
\r
448 TR069RequestProcessorData tr069RequestProcessorData = getTR069RequestProcessorData();
\r
449 updateSessionOnDeviceNotification(tr069RequestProcessorData, newSessionId);
\r
451 logger.debug(PENDING_RPC_CHECK);
\r
452 nbiDeviceOperationRequest =
\r
453 deviceRPCRequestRepositoryHelper.findOldestDeviceRPCRequest(deviceId);
\r
454 if (nbiDeviceOperationRequest != null) {
\r
455 Long operationId = nbiDeviceOperationRequest.getOperationId();
\r
456 OperationDetails opDetails = nbiDeviceOperationRequest.getOpDetails();
\r
457 if (opDetails != null) {
\r
458 OperationCode opCode = opDetails.getOpCode();
\r
459 if (opCode instanceof CustomOperationCode) {
\r
460 CustomOperationCode customOperationCode = (CustomOperationCode) opCode;
\r
461 String customOperationCodeName = customOperationCode.name();
\r
463 "The Device RPC operation request is of custom type, the custom operation to be performed is: {}",
\r
464 customOperationCodeName);
\r
465 String jndiName = customOperationCode.getJndiName();
\r
466 CustomOperationData customOperationData =
\r
467 new CustomOperationData(deviceDetails, null, nbiDeviceOperationRequest);
\r
468 customOperationData = executeCustomOperation(jndiName, customOperationData);
\r
470 DeviceRPCRequest operationRequest = customOperationData.getDeviceRPCRequest();
\r
471 if (operationRequest != null) {
\r
472 operationRequest.addContextParam(SESSION_ID, newSessionId);
\r
473 updateSessionCurOpId(tr069RequestProcessorData, operationId);
\r
474 changeSessionState(tr069RequestProcessorData, SessionState.LOCKED);
\r
475 updateSession(session);
\r
476 return operationRequest;
\r
478 logger.debug(PENDING_RPC_CHECK);
\r
479 nbiDeviceOperationRequest =
\r
480 deviceRPCRequestRepositoryHelper.findOldestDeviceRPCRequest(deviceId);
\r
486 if (nbiDeviceOperationRequest != null) {
\r
487 Long operationId = nbiDeviceOperationRequest.getOperationId();
\r
488 logger.info("A pending Device RPC request exists for the device with operation ID: {}",
\r
490 updateSessionCurOpId(tr069RequestProcessorData, operationId);
\r
491 changeSessionState(tr069RequestProcessorData, SessionState.LOCKED);
\r
493 nbiDeviceOperationRequest.addContextParam(SESSION_ID, newSessionId);
\r
497 "No pending Device RPC request exists for the device, hence empty device response will be sent to the device");
\r
498 logger.debug("Updating the session to terminated state");
\r
499 // To stop the session timer if any running for this device.
\r
500 stopSessionTimer(newSessionId);
\r
501 changeSessionState(tr069RequestProcessorData, SessionState.TERMINATED);
\r
504 updateSession(session);
\r
505 } catch (DeviceOperationException doe) {
\r
506 logger.error(doe.getMessage());
\r
507 } catch (SessionConcurrentAccessException scae) {
\r
511 return nbiDeviceOperationRequest;
\r
517 * @throws SessionManagerException
\r
519 public DeviceOperationRequestDetails getOpRequestDetailsBySessionId(String sessionId)
\r
520 throws SessionManagerException {
\r
521 DeviceOperationRequestDetails deviceOperationRequestDetails =
\r
522 new DeviceOperationRequestDetails();
\r
524 logger.debug("Fetching Operation request details for session: {}", sessionId);
\r
525 SessionDTO session = getSessionBySessionId(sessionId);
\r
526 String deviceId = session.getDeviceId();
\r
527 TR069DeviceDetails deviceDetails = null;
\r
529 deviceDetails = deviceOperationInterface.getDeviceDetails(deviceId);
\r
530 if (session.getCurrentOperationId() == null) {
\r
531 logger.debug("There exists no pending operation request for the session: {}", sessionId);
\r
533 logger.debug("There exists pending operation request for the session: {}", sessionId);
\r
534 List<TR069DeviceRPCRequestEntity> tr069DeviceRPCRequestEntityList =
\r
535 deviceRPCRequestRepositoryHelper.findByDeviceIdAndOperationId(deviceId,
\r
536 session.getCurrentOperationId());
\r
537 if (tr069DeviceRPCRequestEntityList == null) {
\r
538 SessionManagerException ex =
\r
539 new SessionManagerException(ErrorCode.SESSION_EXPIRED, sessionId);
\r
540 logger.error(ex.getMessage());
\r
543 DeviceRPCRequest deviceRPCRequest =
\r
544 TR069RequestProcessorUtility.convertToDTO(tr069DeviceRPCRequestEntityList);
\r
545 OperationCode opCode = deviceRPCRequest.getOpDetails().getOpCode();
\r
547 String operationName = null;
\r
549 if (opCode instanceof TR069OperationCode) {
\r
550 operationName = ((TR069OperationCode) opCode).name();
\r
552 operationName = ((CustomOperationCode) opCode).name();
\r
553 TR069OperationDetails tr069OperationDetails =
\r
554 (TR069OperationDetails) deviceRPCRequest.getOpDetails();
\r
555 opCode = getCustomOperationCode(tr069OperationDetails);
\r
557 logger.info("The pending operation request for the session is of operation {}",
\r
559 deviceOperationRequestDetails.setOpCode(opCode);
\r
560 deviceOperationRequestDetails.setOperationId(deviceRPCRequest.getOperationId());
\r
562 deviceOperationRequestDetails.setDeviceDetails(deviceDetails);
\r
563 } catch (DeviceOperationException e) {
\r
564 SessionManagerException ex =
\r
565 new SessionManagerException(ErrorCode.DEVICE_NOT_EXISTS, deviceId);
\r
566 logger.error(ex.getMessage());
\r
568 } catch (Exception e) {
\r
569 logger.error(e.getMessage());
\r
570 SessionManagerException ex =
\r
571 new SessionManagerException(ErrorCode.SESSION_EXPIRED, sessionId);
\r
572 logger.error(ex.getMessage());
\r
575 return deviceOperationRequestDetails;
\r
581 * @throws DeviceOperationException
\r
583 public TR069DeviceDetails getDeviceDetails(String deviceId) throws DeviceOperationException {
\r
584 return deviceOperationInterface.getDeviceDetails(deviceId);
\r
589 * @param operationId
\r
591 * @throws DeviceOperationException
\r
592 * @throws SessionConcurrentAccessException
\r
593 * @throws InterruptedException
\r
595 private SessionDTO acquireSessionLockWithRetryOnFailure(String deviceId, Long operationId)
\r
596 throws DeviceOperationException, SessionConcurrentAccessException, InterruptedException {
\r
597 int sessionLockAcquireRetryCount = 0;
\r
598 SessionDTO sessionDTO = null;
\r
601 sessionDTO = acquireSessionLock(deviceId, null, false);
\r
603 "Successfully acquired the session lock for processing NBI request with operation ID: {}",
\r
606 } catch (SessionConcurrentAccessException ex) {
\r
607 sessionLockAcquireRetryCount++;
\r
608 if (sessionLockAcquireRetryCount == 3) {
\r
609 logger.error("Failed acquiring the lock after retry, rolling back the transaction");
\r
613 "Session lock acquiring failed with SessionConcurrentAccessException, hence retrying");
\r
614 Thread.sleep(1000L);
\r
616 } while (sessionLockAcquireRetryCount < 3);
\r
623 * @param deviceNotification
\r
625 * @throws DeviceOperationException
\r
627 private TR069DeviceDetails getPersistedDeviceDetails(String deviceId,
\r
628 DeviceInform deviceNotification) throws DeviceOperationException {
\r
629 TR069DeviceDetails deviceDetails = null;
\r
631 deviceDetails = deviceOperationInterface.getDeviceDetails(deviceId);
\r
632 } catch (DeviceOperationException doe) {
\r
633 if (ErrorCode.DEVICE_NOT_EXISTS.equals(doe.getErrorCode())) {
\r
635 "Creating the device record in TR069_DEVICE_ table, as the device is authenticated successfully.");
\r
636 createDevice(deviceNotification.getDeviceDetails());
\r
637 deviceDetails = deviceOperationInterface.getDeviceDetails(deviceId);
\r
641 return deviceDetails;
\r
645 * @param deviceDetails
\r
646 * @param notificationType
\r
647 * @throws TR069EventProcessingException
\r
649 private void sendAbortedOperationResultForPendingRPCRequests(DeviceDetails deviceDetails,
\r
650 TR069InformType notificationType) throws TR069EventProcessingException {
\r
651 String deviceId = deviceDetails.getDeviceId();
\r
652 String notificationName = notificationType.name();
\r
654 "Device Inform event received is {}, hence aborting all the pending operations if any exists",
\r
657 List<DeviceRPCRequest> deviceRPCRequestList =
\r
658 deviceRPCRequestRepositoryHelper.findAllDeviceRPCRequests(deviceId);
\r
660 for (DeviceRPCRequest pendingDeviceRPCRequest : deviceRPCRequestList) {
\r
661 DeviceRPCResponse deviceOpResult =
\r
662 tr069RequestProcessEngineUtility.buildAbortedOperationresult(deviceDetails,
\r
663 pendingDeviceRPCRequest, AcsFaultCode.FAULT_CODE_8002);
\r
664 String operationName = null;
\r
665 if (pendingDeviceRPCRequest.getOpDetails().getOpCode() instanceof CustomOperationCode) {
\r
666 CustomOperationCode operationCode =
\r
667 (CustomOperationCode) pendingDeviceRPCRequest.getOpDetails().getOpCode();
\r
668 operationName = operationCode.name();
\r
670 TR069OperationCode operationCode =
\r
671 (TR069OperationCode) pendingDeviceRPCRequest.getOpDetails().getOpCode();
\r
672 operationName = operationCode.name();
\r
674 Long operationId = pendingDeviceRPCRequest.getOperationId();
\r
675 logger.debug("Aborting the NBI Operation request with operation Id : {} for operation: {}",
\r
676 operationId, operationName);
\r
677 tr069EventNotificationService.sendOperationResultToNBI(deviceOpResult);
\r
678 // Marking the NBI Request as processed
\r
679 deviceRPCRequestRepositoryHelper.markDeviceRPCRequestAsProcessed(deviceId, operationId);
\r
680 stopDeviceRPCRequestTimer(deviceId, operationId);
\r
685 * @param tr069RequestProcessorData
\r
686 * @param deviceNotification
\r
688 private void updateDeviceDetailsFromInform(TR069RequestProcessorData tr069RequestProcessorData,
\r
689 DeviceInform deviceNotification) {
\r
690 Boolean isDeviceDataChanged =
\r
691 isDeviceUpdateExists(tr069RequestProcessorData, deviceNotification);
\r
692 if (isDeviceDataChanged.booleanValue()) {
\r
693 updateDeviceDetails(tr069RequestProcessorData, deviceNotification);
\r
696 "The device data like connection request URL/ Device SW/HW version has changed, hence updating the device details");
\r
697 deviceOperationInterface
\r
698 .updateDeviceDetails(tr069RequestProcessorData.getTr069DeviceDetails());
\r
699 } catch (DeviceOperationException e) {
\r
700 logger.error("Updating the device details with the notification details failed, Reason: {}",
\r
702 logger.error(e.getMessage());
\r
709 * @param operationId
\r
712 private DeviceRPCRequest getNextRPCRequest(String deviceId, Long operationId) {
\r
713 DeviceRPCRequest deviceRPCRequest = null;
\r
715 List<TR069DeviceRPCRequestEntity> entityList =
\r
716 deviceRPCRequestRepositoryHelper.findByDeviceIdAndOperationId(deviceId, operationId);
\r
717 Integer operationCode = entityList.get(0).getOpCode();
\r
718 if (CustomOperationCode.getByOperationCode(operationCode) == null) {
\r
719 logger.info("Marking the Device RPC request with operation id - {} as processed.",
\r
721 deviceRPCRequestRepositoryHelper.markDeviceRPCRequestAsProcessed(deviceId, operationId);
\r
723 logger.debug(PENDING_RPC_CHECK);
\r
724 deviceRPCRequest = deviceRPCRequestRepositoryHelper.findOldestDeviceRPCRequest(deviceId);
\r
725 } catch (TR069EventProcessingException e) {
\r
726 logger.error("An unknown exception occurred while fetching the NBI request, Reason: {}",
\r
730 return deviceRPCRequest;
\r
734 * Creates the device in the DM module if factory imported already
\r
736 * @param deviceDetails
\r
737 * @throws DeviceOperationException
\r
739 private void createDevice(DeviceDetails deviceDetails) throws DeviceOperationException {
\r
740 deviceOperationInterface.updateDeviceDetails(deviceDetails);
\r