/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/acc/ClientAccSessionImpl.java
Java | 768 lines | 502 code | 42 blank | 224 comment | 111 complexity | 761d1614ef52a148a5294497c616e278 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, GPL-2.0, CC-BY-SA-3.0, CC0-1.0, Apache-2.0, BSD-3-Clause
- /*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
- package org.jdiameter.client.impl.app.acc;
-
- import static org.jdiameter.api.Avp.ACCOUNTING_REALTIME_REQUIRED;
- import static org.jdiameter.common.api.app.acc.ClientAccSessionState.IDLE;
- import static org.jdiameter.common.api.app.acc.ClientAccSessionState.OPEN;
- import static org.jdiameter.common.api.app.acc.ClientAccSessionState.PENDING_BUFFERED;
- import static org.jdiameter.common.api.app.acc.ClientAccSessionState.PENDING_CLOSE;
- import static org.jdiameter.common.api.app.acc.ClientAccSessionState.PENDING_EVENT;
- import static org.jdiameter.common.api.app.acc.ClientAccSessionState.PENDING_INTERIM;
- import static org.jdiameter.common.api.app.acc.ClientAccSessionState.PENDING_START;
-
- import java.io.Serializable;
-
- import org.jdiameter.api.Answer;
- import org.jdiameter.api.Avp;
- import org.jdiameter.api.EventListener;
- import org.jdiameter.api.InternalException;
- import org.jdiameter.api.Message;
- import org.jdiameter.api.OverloadException;
- import org.jdiameter.api.Request;
- import org.jdiameter.api.RouteException;
- import org.jdiameter.api.acc.ClientAccSession;
- import org.jdiameter.api.acc.ClientAccSessionListener;
- import org.jdiameter.api.acc.events.AccountAnswer;
- import org.jdiameter.api.acc.events.AccountRequest;
- import org.jdiameter.api.app.AppSession;
- import org.jdiameter.api.app.StateChangeListener;
- import org.jdiameter.api.app.StateEvent;
- import org.jdiameter.client.api.ISessionFactory;
- import org.jdiameter.common.api.app.IAppSessionState;
- import org.jdiameter.common.api.app.acc.ClientAccSessionState;
- import org.jdiameter.common.api.app.acc.IClientAccActionContext;
- import org.jdiameter.common.impl.app.AppEventImpl;
- import org.jdiameter.common.impl.app.acc.AppAccSessionImpl;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
- /**
- * Client Accounting session implementation
- *
- * @author erick.svenson@yahoo.com
- * @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a>
- * @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
- */
- public class ClientAccSessionImpl extends AppAccSessionImpl implements EventListener<Request, Answer>, ClientAccSession {
-
- private static final Logger logger = LoggerFactory.getLogger(ClientAccSessionImpl.class);
-
- // Constants ----------------------------------------------------------------
- public static final int DELIVER_AND_GRANT = 1;
- public static final int GRANT_AND_LOSE = 3;
-
- // Session State Handling ---------------------------------------------------
- //protected ClientAccSessionState state = IDLE;
-
- // Factories and Listeners --------------------------------------------------
- protected IClientAccActionContext context;
- protected ClientAccSessionListener listener;
- //protected transient IMessageParser parser;
- //protected Serializable timerId_interim;
- protected static final String TIMER_NAME_INTERIM = "CLIENT_INTERIM";
-
- //protected String destHost, destRealm;
- //protected AccountRequest buffer;
- protected IClientAccSessionData sessionData;
- public ClientAccSessionImpl(IClientAccSessionData sessionData, ISessionFactory sessionFactory,ClientAccSessionListener clientAccSessionListener, IClientAccActionContext iClientAccActionContext,
- StateChangeListener<AppSession> stateChangeListener) {
- super(sessionFactory,sessionData);
- this.sessionData = sessionData;
- this.listener = clientAccSessionListener;
- this.context = iClientAccActionContext;
-
- super.addStateChangeNotification(stateChangeListener);
- }
-
- public void sendAccountRequest(AccountRequest accountRequest) throws InternalException, IllegalStateException, RouteException, OverloadException {
- try {
- sendAndStateLock.lock();
- handleEvent(new Event(accountRequest));
- try {
- session.send(accountRequest.getMessage(), this);
- // Store last destination information
- sessionData.setDestinationRealm(accountRequest.getMessage().getAvps().getAvp(Avp.DESTINATION_REALM).getDiameterIdentity());
- Avp destHostAvp = accountRequest.getMessage().getAvps().getAvp(Avp.DESTINATION_HOST);
- if(destHostAvp != null) {
- sessionData.setDestinationHost(destHostAvp.getDiameterIdentity());
- }
- }
- catch (Throwable t) {
- logger.debug("Failed to send ACR.", t);
- handleEvent(new Event(Event.Type.FAILED_SEND_RECORD, accountRequest));
- }
- }
- catch (Exception exc) {
- throw new InternalException(exc);
- }
- finally {
- sendAndStateLock.unlock();
- }
- }
-
- protected synchronized void storeToBuffer(Request accountRequest) {
- sessionData.setBuffer(accountRequest);
-
- }
-
- protected synchronized boolean checkBufferSpace() {
- //TODO: make this different op, so it does not have to fetch data.
- return sessionData.getBuffer() == null;
- }
-
- @SuppressWarnings("unchecked")
- protected void setState(IAppSessionState newState) {
- IAppSessionState oldState = sessionData.getClientAccSessionState();
- sessionData.setClientAccSessionState((ClientAccSessionState) newState);
-
- for (StateChangeListener i : stateListeners) {
- i.stateChanged(this,(Enum) oldState, (Enum) newState);
- }
- }
-
- public boolean isStateless() {
- return false;
- }
-
- public boolean handleEvent(StateEvent event) throws InternalException, OverloadException {
-
- ClientAccSessionState oldState = sessionData.getClientAccSessionState();
-
- try {
- switch (oldState) {
- // Idle ==========
- case IDLE: {
- switch ((Event.Type) event.getType()) {
- // Client or device requests access
- case SEND_START_RECORD:
- // Current State: IDLE
- // Event: Client or Device Requests access
- // Action: Send accounting start req.
- // New State: PENDING_S
- setState(PENDING_START);
- break;
- case SEND_EVENT_RECORD:
- // Current State: IDLE
- // Event: Client or device requests a one-time service
- // Action: Send accounting event req
- // New State: PENDING_E
- setState(PENDING_EVENT);
- break;
- // Send buffered message action in other section of this method see below
- default:
- throw new IllegalStateException("Current state " + oldState + " action " + event.getType());
- }
- break;
- }
- // PendingS ==========
- case PENDING_START: {
- switch ((Event.Type) event.getType()) {
- case FAILED_SEND_RECORD:
- AccountRequest request = (AccountRequest) event.getData();
- Avp accRtReq = request.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED);
-
- // Current State: PENDING_S
- // Event: Failure to send and buffer space available and realtime not equal to DELIVER_AND_GRANT
- // Action: Store Start Record
- // New State: OPEN
- if (checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != DELIVER_AND_GRANT) {
- //... cast overkill...
- storeToBuffer((Request) ((AppEventImpl)request).getMessage());
- setState(OPEN);
- }
- else {
- // Current State: PENDING_S
- // Event: Failure to send and no buffer space available and realtime equal to GRANT_AND_LOSE
- // Action: -
- // New State: OPEN
- if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) {
- setState(OPEN);
- }
- else {
- // Current State: PENDING_S
- // Event: Failure to send and no buffer space available and realtime not equal to GRANT_AND_LOSE
- // Action: Disconnect User/Device
- // New State: IDLE
- if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) {
- try {
- if (context != null) {
- Request str = createSessionTermRequest();
- context.disconnectUserOrDev(this, str);
- session.send(str, this);
- }
- }
- finally {
- setState(IDLE);
- }
- }
- }
- }
- break;
- case RECEIVED_RECORD:
- // Current State: PENDING_S
- // Event: Successful accounting start answer received
- // Action: -
- // New State: OPEN
- processInterimIntervalAvp(event);
- setState(OPEN);
- break;
- case FAILED_RECEIVE_RECORD:
- try {
- AccountAnswer answer = (AccountAnswer) event.getData();
- accRtReq = answer.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED);
- // Current State: PENDING_S
- // Event: Failed accounting start answer received and realtime equal to GRANT_AND_LOSE
- // Action: -
- // New State: OPEN
- if (accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) {
- setState(OPEN);
- }
- else {
- // Current State: PENDING_S
- // Event: Failed accounting start answer received and realtime not equal to GRANT_AND_LOSE
- // Action: Disconnect User/Device
- // New State: IDLE
- if (accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) {
- try{
- if (context != null) {
- Request str = createSessionTermRequest();
- context.disconnectUserOrDev(this, str);
- session.send(str, this);
- }
- }
- finally {
- setState(IDLE);
- }
- }
- }
- }
- catch (Exception e) {
- logger.debug("Can not process answer", e);
- setState(IDLE);
- }
- break;
- case SEND_STOP_RECORD:
- // Current State: PENDING_S
- // Event: User service terminated
- // Action: Store stop record
- // New State: PENDING_S
- if (context != null) {
- Request str = createSessionTermRequest();
- context.disconnectUserOrDev(this,str);
- storeToBuffer(str);
- }
- break;
- }
- break;
- }
- // OPEN ==========
- case OPEN: {
- switch ((Event.Type) event.getType()) {
- // User service terminated
- case SEND_STOP_RECORD:
- // Current State: OPEN
- // Event: User service terminated
- // Action: Send accounting stop request
- // New State: PENDING_L
- setState(PENDING_CLOSE);
- break;
- case SEND_INTERIM_RECORD:
- // FIXME: Shouldn't this be different ?
- // Current State: OPEN
- // Event: Interim interval elapses
- // Action: Send accounting interim record
- // New State: PENDING_I
- setState(PENDING_INTERIM);
- break;
-
- // Create timer for "Interim interval elapses" event
- case RECEIVED_RECORD:
- processInterimIntervalAvp(event);
- break;
- }
- }
- break;
- //FIXME: add check for abnormal
- // PendingI ==========
- case PENDING_INTERIM: {
- switch ((Event.Type) event.getType()) {
- case RECEIVED_RECORD:
- // Current State: PENDING_I
- // Event: Successful accounting interim answer received
- // Action: -
- // New State: OPEN
- processInterimIntervalAvp(event);
- setState(OPEN);
- break;
- case FAILED_SEND_RECORD:
- AccountRequest request = (AccountRequest) event.getData();
- Avp accRtReq = ((Message) event.getData()).getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED);
-
- // Current State: PENDING_I
- // Event: Failure to send and buffer space available (or old record interim can be overwritten) and realtime not equal to DELIVER_AND_GRANT
- // Action: Store interim record
- // New State: OPEN
- if (checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != DELIVER_AND_GRANT) {
- //... cast overkill...
- storeToBuffer((Request) ((AppEventImpl)request).getMessage());
- setState(OPEN);
- }
- else {
- // Current State: PENDING_I
- // Event: Failure to send and no buffer space available and realtime equal to GRANT_AND_LOSE
- // Action: -
- // New State: OPEN
- if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) {
- setState(OPEN);
- }
- else {
- // Current State: PENDING_I
- // Event: Failure to send and no buffer space available and realtime not equal to GRANT_AND_LOSE
- // Action: Disconnect User/Device
- // New State: IDLE
- if (!checkBufferSpace() && accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) {
- try{
- if (context != null) {
- Request str = createSessionTermRequest();
- context.disconnectUserOrDev(this, str);
- session.send(str, this);
- }
- }
- finally {
- setState(IDLE);
- }
- }
- }
- }
- break;
- case FAILED_RECEIVE_RECORD:
- try {
- AccountAnswer answer = (AccountAnswer) event.getData();
- accRtReq = answer.getMessage().getAvps().getAvp(ACCOUNTING_REALTIME_REQUIRED);
-
- // Current State: PENDING_I
- // Event: Failed accounting interim answer received and realtime equal to GRANT_AND_LOSE
- // Action: -
- // New State: OPEN
- if (accRtReq != null && accRtReq.getInteger32() == GRANT_AND_LOSE) {
- setState(OPEN);
- }
- else {
- // Current State: PENDING_I
- // Event: Failed account interim answer received and realtime not equal to GRANT_AND_LOSE
- // Action: Disconnect User/Device
- // New State: IDLE
- if (accRtReq != null && accRtReq.getInteger32() != GRANT_AND_LOSE) {
- try {
- if (context != null) {
- Request str = createSessionTermRequest();
- context.disconnectUserOrDev(this, str);
- session.send(str, this);
- }
- }
- finally {
- setState(IDLE);
- }
- }
- }
- }
- catch (Exception e) {
- logger.debug("Can not process received request", e);
- setState(IDLE);
- }
- break;
- case SEND_STOP_RECORD:
- // Current State: PENDING_I
- // Event: User service terminated
- // Action: Store stop record
- // New State: PENDING_I
- if (context != null) {
- Request str = createSessionTermRequest();
- context.disconnectUserOrDev(this,str);
- storeToBuffer(str);
- }
- break;
- }
- break;
- }
- // PendingE ==========
- case PENDING_EVENT: {
- switch ((Event.Type) event.getType()) {
- case RECEIVED_RECORD:
- // Current State: PENDING_E
- // Event: Successful accounting event answer received
- // Action: -
- // New State: IDLE
- setState(IDLE);
- break;
- case FAILED_SEND_RECORD:
- if (checkBufferSpace()) {
- // Current State: PENDING_E
- // Event: Failure to send and buffer space available
- // Action: Store event record
- // New State: IDLE
- AccountRequest data = (AccountRequest) event.getData();
- //... cast overkill...
- storeToBuffer((Request) ((AppEventImpl)data).getMessage());
- }
-
- // Current State: PENDING_E
- // Event: Failure to send and no buffer space available
- // Action: -
- // New State: IDLE
- setState(IDLE);
- break;
- case FAILED_RECEIVE_RECORD:
- // Current State: PENDING_E
- // Event: Failed accounting event answer received
- // Action: -
- // New State: IDLE
- setState(IDLE);
- break;
- }
- break;
- }
- // PendingB ==========
- case PENDING_BUFFERED: {
- switch ((Event.Type) event.getType()) {
- case RECEIVED_RECORD:
- // Current State: PENDING_B
- // Event: Successful accounting answer received
- // Action: Delete record
- // New State: IDLE
- synchronized (this) {
- storeToBuffer(null);
- }
- setState(IDLE);
- break;
- // Failure to send
- case FAILED_SEND_RECORD:
- // Current State: PENDING_B
- // Event: Failure to send
- // Action: -
- // New State: IDLE
- setState(IDLE);
- break;
- // Failed accounting answer received
- case FAILED_RECEIVE_RECORD:
- // Current State: PENDING_B
- // Event: Failed accounting answer received
- // Action: Delete record
- // New State: IDLE
- synchronized (this) {
- storeToBuffer(null);
- }
- setState(IDLE);
- break;
- }
- break;
- }
- // PendingL ==========
- case PENDING_CLOSE: {
- switch ((Event.Type) event.getType()) {
- case RECEIVED_RECORD:
- // Current State: PENDING_L
- // Event: Successful accounting stop answer received
- // Action: -
- // New State: IDLE
- setState(IDLE);
- break;
- case FAILED_SEND_RECORD:
- if (checkBufferSpace()) {
- // Current State: PENDING_L
- // Event: Failure to send and buffer space available
- // Action: Store stop record
- // New State: IDLE
- AccountRequest data = (AccountRequest) event.getData();
- //... cast overkill...
- storeToBuffer((Request) ((AppEventImpl)data).getMessage());
- }
- // Current State: PENDING_L
- // Event: Failure to send and no buffer space available
- // Action: -
- // New State: IDLE
- setState(IDLE);
- break;
- // Failed accounting stop answer received
- case FAILED_RECEIVE_RECORD:
- // Current State: PENDING_L
- // Event: Failed accounting stop answer received
- // Action: -
- // New State: IDLE
- setState(IDLE);
- break;
- }
- break;
- }
- }
- ClientAccSessionState state = sessionData.getClientAccSessionState();
- // Post processing
- if (oldState != state) {
- switch (state) {
- // IDLE ===========
- case IDLE:
- {
- // Current State: IDLE
- // Event: Records in storage
- // Action: Send record
- // New State: PENDING_B
- try {
- synchronized (this) {
- if (!checkBufferSpace()) {
- session.send(sessionData.getBuffer(), this);
- setState(PENDING_BUFFERED);
- }
- }
- }
- catch (Exception e) {
- logger.debug("can not send buffered message", e);
- synchronized (this) {
- if (context != null && !checkBufferSpace()) {
- if (!context.failedSendRecord(this,(Request) sessionData.getBuffer())) {
- storeToBuffer(null);
- }
- }
- }
- }
- }
- }
- }
- }
- catch (Throwable t) {
- throw new InternalException(t);
- }
- return true;
- }
-
- protected void processInterimIntervalAvp(StateEvent event) throws InternalException {
- // Avp interval = ((AppEvent) event.getData()).getMessage().getAvps().getAvp(Avp.ACCT_INTERIM_INTERVAL);
- // if (interval != null) {
- // // create timer
- // try {
- // long v = interval.getUnsigned32();
- // if (v != 0) {
- // // scheduler.schedule(
- // // new Runnable() {
- // // public void run() {
- // // if (context != null) {
- // // try {
- // // Request interimRecord = createInterimRecord();
- // // context.interimIntervalElapses(interimRecord);
- // // sendAndStateLock.lock();
- // // session.send(interimRecord, ClientAccSessionImpl.this);
- // // setState(PENDING_INTERIM);
- // // }
- // // catch (Exception e) {
- // // logger.debug("Can not process Interim Interval AVP", e);
- // // }
- // // finally {
- // // sendAndStateLock.unlock();
- // // }
- // // }
- // // }
- // // },
- // // v, TimeUnit.SECONDS
- // // );
- // cancelInterimTimer();
- // this.timerId_interim = startInterimTimer(v);
- // }
- // }
- // catch (AvpDataException e) {
- // logger.debug("Unable to retrieve Acct-Interim-Interval AVP value", e);
- // }
- // }
- }
-
- /* (non-Javadoc)
- * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String)
- */
- @Override
- public void onTimer(String timerName) {
- if(timerName.equals(TIMER_NAME_INTERIM)) {
- if (context != null) {
- try {
- Request interimRecord = createInterimRecord();
- context.interimIntervalElapses(this,interimRecord);
- sendAndStateLock.lock();
- session.send(interimRecord, ClientAccSessionImpl.this);
- setState(PENDING_INTERIM);
- sessionData.setInterimTimerId(null);
- }
- catch (Exception e) {
- logger.debug("Can not process Interim Interval AVP", e);
- }
- finally {
- sendAndStateLock.unlock();
- }
- }
- }
- else {
- //....?
- }
- }
-
- private Serializable startInterimTimer(long v) {
- try{
- sendAndStateLock.lock();
- Serializable interimTimerId = super.timerFacility.schedule(sessionData.getSessionId(), TIMER_NAME_INTERIM, v);
- sessionData.setInterimTimerId(interimTimerId);
-
- return interimTimerId;
- }
- finally {
- sendAndStateLock.unlock();
- }
- }
-
- private void cancelInterimTimer() {
- try{
- sendAndStateLock.lock();
- Serializable interimTimerId = sessionData.getInterimTimerId();
- if(interimTimerId != null) {
- super.timerFacility.cancel(interimTimerId);
- sessionData.setInterimTimerId(null);
- }
- }
- finally {
- sendAndStateLock.unlock();
- }
- }
-
- @SuppressWarnings("unchecked")
- public <E> E getState(Class<E> eClass) {
- return eClass == ClientAccSessionState.class ? (E) sessionData.getClientAccSessionState() : null;
- }
-
- public void receivedSuccessMessage(Request request, Answer answer) {
- if (request.getCommandCode() == AccountRequest.code) {
- // state should be changed before event listener call
- try {
- sendAndStateLock.lock();
- handleEvent(new Event(createAccountAnswer(answer)));
- }
- catch (Exception e) {
- logger.debug("Can not process received request", e);
- }
- finally {
- sendAndStateLock.unlock();
- }
- try {
- listener.doAccAnswerEvent(this, createAccountRequest(request), createAccountAnswer(answer));
- }
- catch (Exception e) {
- logger.debug("Unable to deliver message to listener.", e);
- }
- }
- else {
- try {
- listener.doOtherEvent(this, createAccountRequest(request), createAccountAnswer(answer));
- }
- catch (Exception e) {
- logger.debug("Can not process received request", e);
- }
- }
- }
-
- public void timeoutExpired(Request request) {
- try {
- sendAndStateLock.lock();
- handleEvent(new Event(Event.Type.FAILED_RECEIVE_RECORD, createAccountRequest(request)));
- }
- catch (Exception e) {
- logger.debug("Can not handle timeout event", e);
- }
- finally {
- sendAndStateLock.unlock();
- }
- }
-
- public Answer processRequest(Request request) {
- Answer a = request.createAnswer(5001);
- return a;
- }
-
- /* (non-Javadoc)
- * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable()
- */
- @Override
- public boolean isReplicable() {
- return true;
- }
-
- protected Request createInterimRecord() {
- Request interimRecord = session.createRequest(AccountRequest.code, sessionData.getApplicationId(), sessionData.getDestinationRealm(), sessionData.getDestinationHost());
- interimRecord.getAvps().addAvp(Avp.ACC_RECORD_TYPE, 3);
- return interimRecord;
- }
-
- protected Request createSessionTermRequest() {
- return session.createRequest(Message.SESSION_TERMINATION_REQUEST, sessionData.getApplicationId(), sessionData.getDestinationRealm(), sessionData.getDestinationHost());
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- ClientAccSessionImpl other = (ClientAccSessionImpl) obj;
- if (sessionData == null) {
- if (other.sessionData != null)
- return false;
- }
- else if (!sessionData.equals(other.sessionData))
- return false;
- return true;
- }
-
- @Override
- public void release() {
- if (isValid()) {
- try {
- sendAndStateLock.lock();
- super.release();
- }
- catch (Exception e) {
- logger.debug("Failed to release session", e);
- }
- finally {
- sendAndStateLock.unlock();
- }
- }
- else {
- logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId());
- }
- }
-
- }