PageRenderTime 28ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/auth/ClientAuthSessionImpl.java

http://mobicents.googlecode.com/
Java | 705 lines | 494 code | 56 blank | 155 comment | 73 complexity | d43b4de7fbe11ec68b1e6efd3e145bee 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
  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2011, Red Hat, Inc. and/or its affiliates, and individual
  4. * contributors as indicated by the @authors tag. All rights reserved.
  5. * See the copyright.txt in the distribution for a full listing
  6. * of individual contributors.
  7. *
  8. * This copyrighted material is made available to anyone wishing to use,
  9. * modify, copy, or redistribute it subject to the terms and conditions
  10. * of the GNU General Public License, v. 2.0.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License,
  18. * v. 2.0 along with this distribution; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  20. * MA 02110-1301, USA.
  21. */
  22. package org.jdiameter.client.impl.app.auth;
  23. import static org.jdiameter.api.Message.SESSION_TERMINATION_REQUEST;
  24. import static org.jdiameter.common.api.app.auth.ClientAuthSessionState.DISCONNECTED;
  25. import static org.jdiameter.common.api.app.auth.ClientAuthSessionState.IDLE;
  26. import static org.jdiameter.common.api.app.auth.ClientAuthSessionState.OPEN;
  27. import static org.jdiameter.common.api.app.auth.ClientAuthSessionState.PENDING;
  28. import java.io.Serializable;
  29. import java.util.concurrent.locks.Lock;
  30. import java.util.concurrent.locks.ReentrantLock;
  31. import org.jdiameter.api.Answer;
  32. import org.jdiameter.api.Avp;
  33. import org.jdiameter.api.AvpSet;
  34. import org.jdiameter.api.EventListener;
  35. import org.jdiameter.api.IllegalDiameterStateException;
  36. import org.jdiameter.api.InternalException;
  37. import org.jdiameter.api.NetworkReqListener;
  38. import org.jdiameter.api.OverloadException;
  39. import org.jdiameter.api.Request;
  40. import org.jdiameter.api.RouteException;
  41. import org.jdiameter.api.app.AppAnswerEvent;
  42. import org.jdiameter.api.app.AppEvent;
  43. import org.jdiameter.api.app.AppRequestEvent;
  44. import org.jdiameter.api.app.AppSession;
  45. import org.jdiameter.api.app.StateChangeListener;
  46. import org.jdiameter.api.app.StateEvent;
  47. import org.jdiameter.api.auth.ClientAuthSession;
  48. import org.jdiameter.api.auth.ClientAuthSessionListener;
  49. import org.jdiameter.api.auth.events.AbortSessionAnswer;
  50. import org.jdiameter.api.auth.events.AbortSessionRequest;
  51. import org.jdiameter.api.auth.events.ReAuthAnswer;
  52. import org.jdiameter.api.auth.events.ReAuthRequest;
  53. import org.jdiameter.api.auth.events.SessionTermAnswer;
  54. import org.jdiameter.api.auth.events.SessionTermRequest;
  55. import org.jdiameter.client.api.ISessionFactory;
  56. import org.jdiameter.common.api.app.IAppSessionState;
  57. import org.jdiameter.common.api.app.auth.ClientAuthSessionState;
  58. import org.jdiameter.common.api.app.auth.IAuthMessageFactory;
  59. import org.jdiameter.common.api.app.auth.IClientAuthActionContext;
  60. import org.jdiameter.common.impl.app.AppAnswerEventImpl;
  61. import org.jdiameter.common.impl.app.AppRequestEventImpl;
  62. import org.jdiameter.common.impl.app.auth.AbortSessionAnswerImpl;
  63. import org.jdiameter.common.impl.app.auth.AbortSessionRequestImpl;
  64. import org.jdiameter.common.impl.app.auth.AppAuthSessionImpl;
  65. import org.jdiameter.common.impl.app.auth.ReAuthAnswerImpl;
  66. import org.jdiameter.common.impl.app.auth.ReAuthRequestImpl;
  67. import org.jdiameter.common.impl.app.auth.SessionTermAnswerImpl;
  68. import org.jdiameter.common.impl.app.auth.SessionTermRequestImpl;
  69. import org.slf4j.Logger;
  70. import org.slf4j.LoggerFactory;
  71. /**
  72. * Client Authorization session implementation
  73. *
  74. * @author erick.svenson@yahoo.com
  75. * @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a>
  76. * @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
  77. */
  78. public class ClientAuthSessionImpl extends AppAuthSessionImpl implements ClientAuthSession, EventListener<Request, Answer>, NetworkReqListener {
  79. protected static final Logger logger = LoggerFactory.getLogger(ClientAuthSessionImpl.class);
  80. // Session State Handling ---------------------------------------------------
  81. //protected boolean stateless = false;
  82. //protected ClientAuthSessionState state = IDLE;
  83. protected Lock sendAndStateLock = new ReentrantLock();
  84. // Factories and Listeners --------------------------------------------------
  85. protected transient IAuthMessageFactory factory;
  86. protected transient IClientAuthActionContext context;
  87. protected transient ClientAuthSessionListener listener;
  88. //protected String destHost, destRealm;
  89. //protected ScheduledFuture sessionTimer;
  90. //protected Serializable timerId_ts;
  91. protected static final String TIMER_NAME_TS="AUTH_TS";
  92. protected IClientAuthSessionData sessionData;
  93. // Constructors -------------------------------------------------------------
  94. public ClientAuthSessionImpl(IClientAuthSessionData sessionData,ISessionFactory sf,ClientAuthSessionListener lst, IAuthMessageFactory fct, StateChangeListener<AppSession> scListener,IClientAuthActionContext context, boolean stateless) {
  95. super(sf, sessionData);
  96. if (lst == null) {
  97. throw new IllegalArgumentException("Listener can not be null");
  98. }
  99. if (fct.getApplicationId() == null) {
  100. throw new IllegalArgumentException("ApplicationId can not be null");
  101. }
  102. super.appId = fct.getApplicationId();
  103. this.listener = lst;
  104. this.factory = fct;
  105. this.context = context;
  106. this.sessionData = sessionData;
  107. this.sessionData.setStateless(stateless);
  108. super.addStateChangeNotification(scListener);
  109. }
  110. // ClientAuthSession Implementation methods ---------------------------------
  111. public void sendAbortSessionAnswer(AbortSessionAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException {
  112. send(Event.Type.SEND_SESSION_ABORT_ANSWER, answer);
  113. }
  114. public void sendAuthRequest(AppRequestEvent request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException {
  115. send(Event.Type.SEND_AUTH_REQUEST, request);
  116. }
  117. public void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException {
  118. send(Event.Type.SEND_AUTH_ANSWER, answer);
  119. }
  120. public void sendSessionTerminationRequest(SessionTermRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException {
  121. send(Event.Type.SEND_SESSION_TERMINATION_REQUEST, request);
  122. }
  123. protected void send(Event.Type type, AppEvent event) throws InternalException {
  124. //This is called from app thread, it may be due to callback from our delivery thread, but we dont care
  125. try {
  126. sendAndStateLock.lock();
  127. if (type != null) {
  128. handleEvent(new Event(type, event));
  129. }
  130. session.send(event.getMessage(), this);
  131. // Store last destination information
  132. AvpSet avps = event.getMessage().getAvps();
  133. Avp destRealmAvp = avps.getAvp(Avp.DESTINATION_REALM);
  134. if(destRealmAvp != null) {
  135. sessionData.setDestinationRealm(destRealmAvp.getDiameterIdentity());
  136. }
  137. Avp destHostAvp = avps.getAvp(Avp.DESTINATION_HOST);
  138. if(destHostAvp != null) {
  139. sessionData.setDestinationHost(destHostAvp.getDiameterIdentity());
  140. }
  141. }
  142. catch (Exception e) {
  143. throw new InternalException(e);
  144. }
  145. finally {
  146. sendAndStateLock.unlock();
  147. }
  148. }
  149. public boolean isStateless() {
  150. return this.sessionData.isStateless();
  151. }
  152. @SuppressWarnings("unchecked")
  153. protected void setState(ClientAuthSessionState newState) {
  154. IAppSessionState oldState = sessionData.getClientAuthSessionState();
  155. sessionData.setClientAuthSessionState(newState);
  156. for (StateChangeListener i : stateListeners) {
  157. i.stateChanged(this,(Enum) oldState, (Enum) newState);
  158. }
  159. }
  160. @SuppressWarnings("unchecked")
  161. public <E> E getState(Class<E> eClass) {
  162. return eClass == ClientAuthSessionState.class ? (E) sessionData.getClientAuthSessionState() : null;
  163. }
  164. public boolean handleEvent(StateEvent event) throws InternalException, OverloadException {
  165. return sessionData.isStateless() ? handleEventForStatelessSession(event) : handleEventForStatefulSession(event);
  166. }
  167. public boolean handleEventForStatelessSession(StateEvent event) throws InternalException, OverloadException {
  168. try {
  169. ClientAuthSessionState state = sessionData.getClientAuthSessionState();
  170. ClientAuthSessionState oldState = state;
  171. switch (state) {
  172. case IDLE:
  173. switch ((Event.Type) event.getType()) {
  174. case SEND_AUTH_REQUEST:
  175. // Current State: IDLE
  176. // Event: Client or Device Requests access
  177. // Action: Send service specific auth req
  178. // New State: PENDING
  179. setState(PENDING);
  180. break;
  181. default:
  182. logger.debug("Unknown event {}", event.getType());
  183. break;
  184. }
  185. break;
  186. case PENDING:
  187. switch ((Event.Type) event.getType()) {
  188. case RECEIVE_AUTH_ANSWER:
  189. try {
  190. // Current State: PENDING
  191. // Event: Successful service-specific authorization answer received with Auth-Session-State set to NO_STATE_MAINTAINED
  192. // Action: Grant Access
  193. // New State: OPEN
  194. setState(OPEN);
  195. listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData());
  196. }
  197. catch (Exception e) {
  198. // Current State: PENDING
  199. // Event: Failed service-specific authorization answer received
  200. // Action: Cleanup
  201. // New State: IDLE
  202. setState(IDLE);
  203. }
  204. break;
  205. default:
  206. logger.debug("Unknown event {}", event.getType());
  207. break;
  208. }
  209. break;
  210. case OPEN:
  211. switch ((Event.Type) event.getType()) {
  212. case SEND_SESSION_ABORT_ANSWER:
  213. case SEND_SESSION_TERMINATION_REQUEST:
  214. // Current State: OPEN
  215. // Event: Service to user is terminated
  216. // Action: Disconnect User/Device
  217. // New State: IDLE
  218. setState(IDLE);
  219. break;
  220. case TIMEOUT_EXPIRES:
  221. // Current State: OPEN
  222. // Event: Session-Timeout Expires on Access Device
  223. // Action: Send STR
  224. // New State: DISCON
  225. try {
  226. if (context != null) {
  227. context.accessTimeoutElapses(this);
  228. Request str = createSessionTermRequest();
  229. context.disconnectUserOrDev(this, str);
  230. session.send(str, this);
  231. }
  232. }
  233. finally {
  234. // IDLE is the same as DISCON
  235. setState(IDLE);
  236. }
  237. break;
  238. default:
  239. logger.debug("Unknown event {}", event.getType());
  240. break;
  241. }
  242. break;
  243. }
  244. // post processing
  245. if (oldState != state) {
  246. if (DISCONNECTED.equals(state) || IDLE.equals(state)) {
  247. cancelTsTimer();
  248. }
  249. else if (OPEN.equals(state) && context != null && context.getAccessTimeout() > 0) {
  250. // sessionTimer = scheduler.schedule(new Runnable() {
  251. // public void run() {
  252. // if (context != null) {
  253. // try {
  254. // handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, null));
  255. // }
  256. // catch (Exception e) {
  257. // logger.debug("Can not handle event", e);
  258. // }
  259. // }
  260. // }
  261. // }, context.createAccessTimer(), TimeUnit.MILLISECONDS);
  262. cancelTsTimer();
  263. startTsTimer();
  264. }
  265. }
  266. }
  267. catch (Throwable t) {
  268. throw new InternalException(t);
  269. }
  270. return true;
  271. }
  272. public boolean handleEventForStatefulSession(StateEvent event) throws InternalException, OverloadException {
  273. ClientAuthSessionState state = sessionData.getClientAuthSessionState();
  274. ClientAuthSessionState oldState = state;
  275. try {
  276. switch (state) {
  277. case IDLE: {
  278. switch ((Event.Type) event.getType()) {
  279. case SEND_AUTH_REQUEST:
  280. // Current State: IDLE
  281. // Event: Client or Device Requests access
  282. // Action: Send service specific auth req
  283. // New State: PENDING
  284. setState(PENDING);
  285. break;
  286. case RECEIVE_ABORT_SESSION_REQUEST:
  287. // Current State: IDLE
  288. // Event: ASR Received for unknown session
  289. // Action: Send ASA with Result-Code = UNKNOWN_SESSION_ID
  290. // New State: IDLE
  291. // FIXME: Should send ASA with UNKNOWN_SESSION_ID instead ?
  292. listener.doAbortSessionRequestEvent(this, (AbortSessionRequest) event.getData());
  293. break;
  294. default:
  295. logger.debug("Unknown event {}", event.getType());
  296. break;
  297. }
  298. break;
  299. }
  300. case PENDING: {
  301. switch ((Event.Type) event.getType()) {
  302. case RECEIVE_AUTH_ANSWER:
  303. try {
  304. // Current State: PENDING
  305. // Event: Successful service-specific authorization answer received with default Auth-Session-State value
  306. // Action: Grant Access
  307. // New State: OPEN
  308. setState(OPEN);
  309. listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData());
  310. }
  311. catch (InternalException e) {
  312. // Current State: PENDING
  313. // Event: Successful service-specific authorization answer received but service not provided
  314. // Action: Send STR
  315. // New State: DISCON
  316. // Current State: PENDING
  317. // Event: Error Processing successful service-specific authorization answer
  318. // Action: Send STR
  319. // New State: DISCON
  320. setState(DISCONNECTED);
  321. }
  322. catch (Exception e) {
  323. // Current State: PENDING
  324. // Event: Failed service-specific authorization answer received
  325. // Action: Cleanup
  326. // New State: IDLE
  327. setState(IDLE);
  328. }
  329. break;
  330. default:
  331. logger.debug("Unknown event {}", event.getType());
  332. break;
  333. }
  334. break;
  335. }
  336. case OPEN: {
  337. switch ((Event.Type) event.getType()) {
  338. case SEND_AUTH_REQUEST:
  339. // Current State: OPEN
  340. // Event: User or client device requests access to service
  341. // Action: Send service specific auth req
  342. // New State: OPEN
  343. break;
  344. case RECEIVE_AUTH_ANSWER:
  345. try {
  346. // Current State: OPEN
  347. // Event: Successful service-specific authorization answer received
  348. // Action: Provide Service
  349. // New State: OPEN
  350. listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData());
  351. }
  352. catch (Exception e) {
  353. // Current State: OPEN
  354. // Event: ASR Received, client will comply with request to end the session
  355. // Action: Send ASA with Result-Code = SUCCESS, Send STR
  356. // New State: DISCON
  357. setState(DISCONNECTED);
  358. }
  359. break;
  360. case RECEIVE_FAILED_AUTH_ANSWER:
  361. // Current State: OPEN
  362. // Event: Failed Service-specific authorization answer received
  363. // Action: Disconnect User/Device
  364. // New State: IDLE
  365. try {
  366. if (context != null) {
  367. Request str = createSessionTermRequest();
  368. context.disconnectUserOrDev(this, str);
  369. session.send(str, this);
  370. }
  371. }
  372. finally {
  373. setState(IDLE);
  374. listener.doAuthAnswerEvent(this, null, (AppAnswerEvent) event.getData());
  375. }
  376. break;
  377. case RECEIVE_ABORT_SESSION_REQUEST:
  378. // Current State: OPEN
  379. // Event: ASR Received (client to take comply or not)
  380. // Action: TBD
  381. // New State: TBD (comply = DISCON, !comply = OPEN)
  382. listener.doAbortSessionRequestEvent(this, (AbortSessionRequestImpl) event.getData());
  383. break;
  384. case SEND_SESSION_TERMINATION_REQUEST:
  385. setState(DISCONNECTED);
  386. break;
  387. case TIMEOUT_EXPIRES:
  388. // Current State: OPEN
  389. // Event: Session-Timeout Expires on Access Device
  390. // Action: Send STR
  391. // New State: DISCON
  392. // Current State: OPEN
  393. // Event: Authorization-Lifetime + Auth-Grace-Period expires on access device
  394. // Action: Send STR
  395. // New State: DISCON
  396. try {
  397. if (context != null) {
  398. context.accessTimeoutElapses(this);
  399. Request str = createSessionTermRequest();
  400. context.disconnectUserOrDev(this, str);
  401. session.send(str, this);
  402. }
  403. }
  404. finally {
  405. setState(DISCONNECTED);
  406. }
  407. break;
  408. }
  409. break;
  410. }
  411. case DISCONNECTED: {
  412. switch ((Event.Type) event.getType()) {
  413. case RECEIVE_ABORT_SESSION_REQUEST:
  414. // Current State: DISCON
  415. // Event: ASR Received
  416. // Action: Send ASA
  417. // New State: DISCON
  418. listener.doAbortSessionRequestEvent(this, (AbortSessionRequest) event.getData());
  419. break;
  420. case RECEIVE_SESSION_TERINATION_ANSWER:
  421. // Current State: DISCON
  422. // Event: STA Received
  423. // Action: Disconnect User/Device
  424. // New State: IDLE
  425. listener.doSessionTerminationAnswerEvent(this, ((SessionTermAnswerImpl) event.getData()));
  426. setState(IDLE);
  427. break;
  428. default:
  429. logger.debug("Unknown event {}", event.getType());
  430. break;
  431. }
  432. break;
  433. }
  434. default: {
  435. logger.debug("Unknown state {}", state);
  436. break;
  437. }
  438. }
  439. // post processing
  440. if (oldState != state) {
  441. if (OPEN.equals(state) && context != null && context.getAccessTimeout() > 0) {
  442. // scheduler.schedule(new Runnable() {
  443. // public void run() {
  444. // if (context != null) {
  445. // try {
  446. // handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, null));
  447. // }
  448. // catch (Exception e) {
  449. // logger.debug("Can not handle event", e);
  450. // }
  451. // }
  452. // }
  453. // }, context.createAccessTimer(), TimeUnit.MILLISECONDS);
  454. cancelTsTimer();
  455. startTsTimer();
  456. }
  457. }
  458. }
  459. catch (Throwable t) {
  460. throw new InternalException(t);
  461. }
  462. return true;
  463. }
  464. public void receivedSuccessMessage(Request request, Answer answer) {
  465. AnswerDelivery ad = new AnswerDelivery();
  466. ad.session = this;
  467. ad.request = request;
  468. ad.answer = answer;
  469. super.scheduler.execute(ad);
  470. }
  471. public void timeoutExpired(Request request) {
  472. try {
  473. sendAndStateLock.lock();
  474. //FIXME: should this also be async ?
  475. handleEvent(new Event(Event.Type.RECEIVE_FAILED_AUTH_ANSWER, new AppRequestEventImpl(request)));
  476. }
  477. catch (Exception e) {
  478. logger.debug("Can not handle timeout event", e);
  479. }
  480. finally {
  481. sendAndStateLock.unlock();
  482. }
  483. }
  484. public Answer processRequest(Request request) {
  485. RequestDelivery rd = new RequestDelivery();
  486. rd.session = this;
  487. rd.request = request;
  488. super.scheduler.execute(rd);
  489. return null;
  490. }
  491. /* (non-Javadoc)
  492. * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable()
  493. */
  494. @Override
  495. public boolean isReplicable() {
  496. return true;
  497. }
  498. protected void startTsTimer() throws IllegalArgumentException, InternalException {
  499. try {
  500. sendAndStateLock.lock();
  501. sessionData.setTsTimerId(super.timerFacility.schedule(sessionData.getSessionId(), TIMER_NAME_TS, context.getAccessTimeout()));
  502. }
  503. finally {
  504. sendAndStateLock.unlock();
  505. }
  506. }
  507. protected void cancelTsTimer() {
  508. try {
  509. sendAndStateLock.lock();
  510. Serializable timerId = sessionData.getTsTimerId();
  511. if(timerId != null) {
  512. super.timerFacility.cancel(timerId);
  513. sessionData.setTsTimerId(null);
  514. }
  515. }
  516. finally {
  517. sendAndStateLock.unlock();
  518. }
  519. }
  520. /* (non-Javadoc)
  521. * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String)
  522. */
  523. @Override
  524. public void onTimer(String timerName) {
  525. if(timerName.equals(TIMER_NAME_TS)) {
  526. try {
  527. sendAndStateLock.lock();
  528. sessionData.setTsTimerId(null);
  529. if (context != null) {
  530. try {
  531. handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, null));
  532. }
  533. catch (Exception e) {
  534. logger.debug("Can not handle event", e);
  535. }
  536. }
  537. }
  538. finally {
  539. sendAndStateLock.unlock();
  540. }
  541. }
  542. }
  543. protected AbortSessionAnswer createAbortSessionAnswer(Answer answer) {
  544. return new AbortSessionAnswerImpl(answer);
  545. }
  546. protected AbortSessionRequest createAbortSessionRequest(Request request) {
  547. return new AbortSessionRequestImpl(request);
  548. }
  549. protected ReAuthAnswer createReAuthAnswer(Answer answer) {
  550. return new ReAuthAnswerImpl(answer);
  551. }
  552. protected ReAuthRequest createReAuthRequest(Request request) {
  553. return new ReAuthRequestImpl(request);
  554. }
  555. protected SessionTermAnswer createSessionTermAnswer(Answer answer) {
  556. return new SessionTermAnswerImpl(answer);
  557. }
  558. protected SessionTermRequest createSessionTermRequest(Request request) {
  559. return new SessionTermRequestImpl(request);
  560. }
  561. protected Request createSessionTermRequest() {
  562. return session.createRequest(SESSION_TERMINATION_REQUEST, appId, sessionData.getDestinationRealm(), sessionData.getDestinationHost());
  563. }
  564. @Override
  565. public int hashCode() {
  566. final int prime = 31;
  567. int result = super.hashCode();
  568. result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode());
  569. return result;
  570. }
  571. @Override
  572. public boolean equals(Object obj) {
  573. if (this == obj)
  574. return true;
  575. if (!super.equals(obj))
  576. return false;
  577. if (getClass() != obj.getClass())
  578. return false;
  579. ClientAuthSessionImpl other = (ClientAuthSessionImpl) obj;
  580. if (sessionData == null) {
  581. if (other.sessionData != null)
  582. return false;
  583. }
  584. else if (!sessionData.equals(other.sessionData))
  585. return false;
  586. return true;
  587. }
  588. @Override
  589. public void release() {
  590. if (isValid()) {
  591. try {
  592. sendAndStateLock.lock();
  593. super.release();
  594. }
  595. catch (Exception e) {
  596. logger.debug("Failed to release session", e);
  597. }
  598. finally {
  599. sendAndStateLock.unlock();
  600. }
  601. }
  602. else {
  603. logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId());
  604. }
  605. }
  606. private class RequestDelivery implements Runnable {
  607. ClientAuthSession session;
  608. Request request;
  609. public void run() {
  610. try {
  611. if (request.getCommandCode() == AbortSessionRequestImpl.code) {
  612. handleEvent(new Event(Event.Type.RECEIVE_ABORT_SESSION_REQUEST, createAbortSessionRequest(request)));
  613. } else if (request.getCommandCode() == ReAuthRequestImpl.code) {
  614. listener.doReAuthRequestEvent(session, createReAuthRequest(request));
  615. } else {
  616. listener.doOtherEvent(session, factory.createAuthRequest(request), null);
  617. }
  618. }
  619. catch (Exception e) {
  620. logger.debug("Can not process received request", e);
  621. }
  622. }
  623. }
  624. private class AnswerDelivery implements Runnable {
  625. ClientAuthSession session;
  626. Answer answer;
  627. Request request;
  628. public void run() {
  629. try {
  630. sendAndStateLock.lock();
  631. // FIXME: baranowb: this shouldn't be like that?
  632. if (answer.getCommandCode() == factory.getAuthMessageCommandCode()) {
  633. handleEvent(new Event(Event.Type.RECEIVE_AUTH_ANSWER, factory.createAuthAnswer(answer)));
  634. } else if (answer.getCommandCode() == SessionTermAnswerImpl.code) {
  635. handleEvent(new Event(Event.Type.RECEIVE_SESSION_TERINATION_ANSWER, createSessionTermAnswer(answer)));
  636. }
  637. else {
  638. listener.doOtherEvent(session, factory.createAuthRequest(request), new AppAnswerEventImpl(answer));
  639. }
  640. }
  641. catch (Exception e) {
  642. logger.debug("Can not process received message", e);
  643. }
  644. finally {
  645. sendAndStateLock.unlock();
  646. }
  647. }
  648. }
  649. }