PageRenderTime 140ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/servers/diameter/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/ro/ClientRoSessionImpl.java

http://mobicents.googlecode.com/
Java | 1356 lines | 943 code | 111 blank | 302 comment | 179 complexity | ff1038e194bc83aff6f47bf1b818a04a 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

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2010, Red Hat, Inc. and individual contributors
  4. * by the @authors tag. See the copyright.txt in the distribution for a
  5. * full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software 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. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jdiameter.client.impl.app.ro;
  23. import java.io.Serializable;
  24. import java.nio.ByteBuffer;
  25. import java.util.ArrayList;
  26. import java.util.Collections;
  27. import java.util.HashSet;
  28. import java.util.Set;
  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.AvpDataException;
  33. import org.jdiameter.api.EventListener;
  34. import org.jdiameter.api.IllegalDiameterStateException;
  35. import org.jdiameter.api.InternalException;
  36. import org.jdiameter.api.Message;
  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.AppSession;
  44. import org.jdiameter.api.app.StateChangeListener;
  45. import org.jdiameter.api.app.StateEvent;
  46. import org.jdiameter.api.auth.events.ReAuthAnswer;
  47. import org.jdiameter.api.auth.events.ReAuthRequest;
  48. import org.jdiameter.api.ro.ClientRoSession;
  49. import org.jdiameter.api.ro.ClientRoSessionListener;
  50. import org.jdiameter.api.ro.events.RoCreditControlAnswer;
  51. import org.jdiameter.api.ro.events.RoCreditControlRequest;
  52. import org.jdiameter.client.api.IContainer;
  53. import org.jdiameter.client.api.IMessage;
  54. import org.jdiameter.client.api.ISessionFactory;
  55. import org.jdiameter.client.api.parser.IMessageParser;
  56. import org.jdiameter.client.api.parser.ParseException;
  57. import org.jdiameter.client.impl.app.ro.Event.Type;
  58. import org.jdiameter.common.api.app.IAppSessionState;
  59. import org.jdiameter.common.api.app.ro.ClientRoSessionState;
  60. import org.jdiameter.common.api.app.ro.IClientRoSessionContext;
  61. import org.jdiameter.common.api.app.ro.IRoMessageFactory;
  62. import org.jdiameter.common.impl.app.AppAnswerEventImpl;
  63. import org.jdiameter.common.impl.app.AppRequestEventImpl;
  64. import org.jdiameter.common.impl.app.auth.ReAuthAnswerImpl;
  65. import org.jdiameter.common.impl.app.ro.AppRoSessionImpl;
  66. import org.slf4j.Logger;
  67. import org.slf4j.LoggerFactory;
  68. /**
  69. * Client Credit-Control Application session implementation
  70. *
  71. * @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
  72. * @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a>
  73. */
  74. public class ClientRoSessionImpl extends AppRoSessionImpl implements ClientRoSession, NetworkReqListener, EventListener<Request, Answer> {
  75. private static final Logger logger = LoggerFactory.getLogger(ClientRoSessionImpl.class);
  76. // Session State Handling ---------------------------------------------------
  77. protected IClientRoSessionData sessionData;
  78. protected Lock sendAndStateLock = new ReentrantLock();
  79. // Factories and Listeners --------------------------------------------------
  80. protected transient IRoMessageFactory factory;
  81. protected transient ClientRoSessionListener listener;
  82. protected transient IClientRoSessionContext context;
  83. protected transient IMessageParser parser;
  84. // Tx Timer -----------------------------------------------------------------
  85. protected final static String TX_TIMER_NAME = "Ro_CLIENT_TX_TIMER";
  86. protected static final long TX_TIMER_DEFAULT_VALUE = 30 * 60 * 1000; // miliseconds
  87. protected long[] authAppIds = new long[] { 4 };
  88. // Requested Action + Credit-Control and Direct-Debiting Failure-Handling ---
  89. public static final int NON_INITIALIZED = -300;
  90. protected static final int CCFH_TERMINATE = 0;
  91. protected static final int CCFH_CONTINUE = 1;
  92. protected static final int CCFH_RETRY_AND_TERMINATE = 2;
  93. private static final int DDFH_TERMINATE_OR_BUFFER = 0;
  94. private static final int DDFH_CONTINUE = 1;
  95. // CC-Request-Type Values ---------------------------------------------------
  96. private static final int DIRECT_DEBITING = 0;
  97. private static final int REFUND_ACCOUNT = 1;
  98. private static final int CHECK_BALANCE = 2;
  99. private static final int PRICE_ENQUIRY = 3;
  100. private static final int EVENT_REQUEST = 4;
  101. // Error Codes --------------------------------------------------------------
  102. private static final long END_USER_SERVICE_DENIED = 4010;
  103. private static final long CREDIT_CONTROL_NOT_APPLICABLE = 4011;
  104. private static final long USER_UNKNOWN = 5030;
  105. private static final long DIAMETER_UNABLE_TO_DELIVER = 3002L;
  106. private static final long DIAMETER_TOO_BUSY = 3004L;
  107. private static final long DIAMETER_LOOP_DETECTED = 3005L;
  108. protected static final Set<Long> temporaryErrorCodes;
  109. static {
  110. HashSet<Long> tmp = new HashSet<Long>();
  111. tmp.add(DIAMETER_UNABLE_TO_DELIVER);
  112. tmp.add(DIAMETER_TOO_BUSY);
  113. tmp.add(DIAMETER_LOOP_DETECTED);
  114. temporaryErrorCodes = Collections.unmodifiableSet(tmp);
  115. }
  116. // Session Based Queue
  117. protected ArrayList<Event> eventQueue = new ArrayList<Event>();
  118. public ClientRoSessionImpl(IClientRoSessionData sessionData, IRoMessageFactory fct, ISessionFactory sf, ClientRoSessionListener lst,IClientRoSessionContext ctx, StateChangeListener<AppSession> stLst) {
  119. super(sf,sessionData);
  120. if (lst == null) {
  121. throw new IllegalArgumentException("Listener can not be null");
  122. }
  123. if (fct.getApplicationIds() == null) {
  124. throw new IllegalArgumentException("ApplicationId can not be less than zero");
  125. }
  126. if (sessionData == null) {
  127. throw new IllegalArgumentException("SessionData can not be null");
  128. }
  129. this.context = (IClientRoSessionContext)ctx;
  130. this.sessionData = sessionData;
  131. this.authAppIds = fct.getApplicationIds();
  132. this.listener = lst;
  133. this.factory = fct;
  134. IContainer icontainer = sf.getContainer();
  135. this.parser = icontainer.getAssemblerFacility().getComponentInstance(IMessageParser.class);
  136. super.addStateChangeNotification(stLst);
  137. }
  138. protected int getLocalCCFH() {
  139. return sessionData.getGatheredCCFH() >= 0 ? sessionData.getGatheredCCFH() : context.getDefaultCCFHValue();
  140. }
  141. protected int getLocalDDFH() {
  142. return sessionData.getGatheredDDFH() >= 0 ? sessionData.getGatheredDDFH() : context.getDefaultDDFHValue();
  143. }
  144. public void sendCreditControlRequest(RoCreditControlRequest request) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException {
  145. try {
  146. extractFHAVPs(request, null);
  147. this.handleEvent(new Event(true, request, null));
  148. }
  149. catch (AvpDataException e) {
  150. throw new InternalException(e);
  151. }
  152. }
  153. public void sendReAuthAnswer(ReAuthAnswer answer) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException {
  154. this.handleEvent(new Event(Event.Type.SEND_RAA, null, answer));
  155. }
  156. public boolean isStateless() {
  157. return false;
  158. }
  159. public boolean isEventBased() {
  160. return sessionData.isEventBased();
  161. }
  162. @SuppressWarnings("unchecked")
  163. public <E> E getState(Class<E> stateType) {
  164. return stateType == ClientRoSessionState.class ? (E) sessionData.getClientRoSessionState() : null;
  165. }
  166. public boolean handleEvent(StateEvent event) throws InternalException, OverloadException {
  167. return this.isEventBased() ? handleEventForEventBased(event) : handleEventForSessionBased(event);
  168. }
  169. protected boolean handleEventForEventBased(StateEvent event) throws InternalException, OverloadException {
  170. try {
  171. sendAndStateLock.lock();
  172. ClientRoSessionState state = sessionData.getClientRoSessionState();
  173. Event localEvent = (Event) event;
  174. Event.Type eventType = (Type) localEvent.getType();
  175. switch (state) {
  176. case IDLE:
  177. switch (eventType) {
  178. case SEND_EVENT_REQUEST:
  179. // Current State: IDLE
  180. // Event: Client or device requests a one-time service
  181. // Action: Send CC event request, start Tx
  182. // New State: PENDING_E
  183. startTx((RoCreditControlRequest) localEvent.getRequest());
  184. setState(ClientRoSessionState.PENDING_EVENT);
  185. try {
  186. dispatchEvent(localEvent.getRequest());
  187. }
  188. catch (Exception e) {
  189. // This handles failure to send in PendingI state in FSM table
  190. logger.debug("Failure handling send event request", e);
  191. handleSendFailure(e, eventType, localEvent.getRequest().getMessage());
  192. }
  193. break;
  194. default:
  195. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  196. break;
  197. }
  198. break;
  199. case PENDING_EVENT:
  200. switch (eventType) {
  201. case RECEIVE_EVENT_ANSWER:
  202. AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer();
  203. try {
  204. long resultCode = answer.getResultCodeAvp().getUnsigned32();
  205. if (isSuccess(resultCode)) {
  206. // Current State: PENDING_E
  207. // Event: Successful CC event answer received
  208. // Action: Grant service to end user
  209. // New State: IDLE
  210. setState(ClientRoSessionState.IDLE, false);
  211. }
  212. if (isProvisional(resultCode) || isFailure(resultCode)) {
  213. handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType);
  214. }
  215. deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer());
  216. }
  217. catch (AvpDataException e) {
  218. logger.debug("Failure handling received answer event", e);
  219. setState(ClientRoSessionState.IDLE, false);
  220. }
  221. break;
  222. case Tx_TIMER_FIRED:
  223. handleTxExpires(localEvent.getRequest().getMessage());
  224. break;
  225. default:
  226. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  227. break;
  228. }
  229. break;
  230. case PENDING_BUFFERED:
  231. switch (eventType) {
  232. case RECEIVE_EVENT_ANSWER:
  233. // Current State: PENDING_B
  234. // Event: Successful CC answer received
  235. // Action: Delete request
  236. // New State: IDLE
  237. setState(ClientRoSessionState.IDLE, false);
  238. sessionData.setBuffer(null);
  239. deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer());
  240. break;
  241. default:
  242. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  243. break;
  244. }
  245. break;
  246. default:
  247. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  248. break;
  249. }
  250. dispatch();
  251. return true;
  252. }
  253. catch (Exception e) {
  254. throw new InternalException(e);
  255. }
  256. finally {
  257. sendAndStateLock.unlock();
  258. }
  259. }
  260. protected boolean handleEventForSessionBased(StateEvent event) throws InternalException, OverloadException {
  261. try {
  262. sendAndStateLock.lock();
  263. ClientRoSessionState state = sessionData.getClientRoSessionState();
  264. Event localEvent = (Event) event;
  265. Event.Type eventType = (Type) localEvent.getType();
  266. switch (state) {
  267. case IDLE:
  268. switch (eventType) {
  269. case SEND_INITIAL_REQUEST:
  270. // Current State: IDLE
  271. // Event: Client or device requests access/service
  272. // Action: Send CC initial request, start Tx
  273. // New State: PENDING_I
  274. startTx((RoCreditControlRequest) localEvent.getRequest());
  275. setState(ClientRoSessionState.PENDING_INITIAL);
  276. try {
  277. dispatchEvent(localEvent.getRequest());
  278. }
  279. catch (Exception e) {
  280. // This handles failure to send in PendingI state in FSM table
  281. handleSendFailure(e, eventType, localEvent.getRequest().getMessage());
  282. }
  283. break;
  284. default:
  285. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  286. break;
  287. }
  288. break;
  289. case PENDING_INITIAL:
  290. AppAnswerEvent answer = (AppAnswerEvent) localEvent.getAnswer();
  291. switch (eventType) {
  292. case RECEIVED_INITIAL_ANSWER:
  293. long resultCode = answer.getResultCodeAvp().getUnsigned32();
  294. if (isSuccess(resultCode)) {
  295. // Current State: PENDING_I
  296. // Event: Successful CC initial answer received
  297. // Action: Stop Tx
  298. // New State: OPEN
  299. stopTx();
  300. setState(ClientRoSessionState.OPEN);
  301. }
  302. else if (isProvisional(resultCode) || isFailure(resultCode)) {
  303. handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType);
  304. }
  305. deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer());
  306. break;
  307. case Tx_TIMER_FIRED:
  308. handleTxExpires(localEvent.getRequest().getMessage());
  309. break;
  310. case SEND_UPDATE_REQUEST:
  311. case SEND_TERMINATE_REQUEST:
  312. // Current State: PENDING_I
  313. // Event: User service terminated
  314. // Action: Queue termination event
  315. // New State: PENDING_I
  316. // Current State: PENDING_I
  317. // Event: Change in rating condition
  318. // Action: Queue changed rating condition event
  319. // New State: PENDING_I
  320. eventQueue.add(localEvent);
  321. break;
  322. default:
  323. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  324. break;
  325. }
  326. break;
  327. case OPEN:
  328. switch (eventType) {
  329. case SEND_UPDATE_REQUEST:
  330. // Current State: OPEN
  331. // Event: Granted unit elapses and no final unit indication received
  332. // Action: Send CC update request, start Tx
  333. // New State: PENDING_U
  334. // Current State: OPEN
  335. // Event: Change in rating condition in queue
  336. // Action: Send CC update request, start Tx
  337. // New State: PENDING_U
  338. // Current State: OPEN
  339. // Event: Change in rating condition or Validity-Time elapses
  340. // Action: Send CC update request, start Tx
  341. // New State: PENDING_U
  342. // Current State: OPEN
  343. // Event: RAR received
  344. // Action: Send RAA followed by CC update request, start Tx
  345. // New State: PENDING_U
  346. startTx((RoCreditControlRequest) localEvent.getRequest());
  347. setState(ClientRoSessionState.PENDING_UPDATE);
  348. try {
  349. dispatchEvent(localEvent.getRequest());
  350. }
  351. catch (Exception e) {
  352. // This handles failure to send in PendingI state in FSM table
  353. handleSendFailure(e, eventType, localEvent.getRequest().getMessage());
  354. }
  355. break;
  356. case SEND_TERMINATE_REQUEST:
  357. // Current State: OPEN
  358. // Event: Granted unit elapses and final unit action equal to TERMINATE received
  359. // Action: Terminate end user?s service, send CC termination request
  360. // New State: PENDING_T
  361. // Current State: OPEN
  362. // Event: Service terminated in queue
  363. // Action: Send CC termination request
  364. // New State: PENDING_T
  365. // Current State: OPEN
  366. // Event: User service terminated
  367. // Action: Send CC termination request
  368. // New State: PENDING_T
  369. setState(ClientRoSessionState.PENDING_TERMINATION);
  370. try {
  371. dispatchEvent(localEvent.getRequest());
  372. }
  373. catch (Exception e) {
  374. handleSendFailure(e, eventType, localEvent.getRequest().getMessage());
  375. }
  376. break;
  377. case RECEIVED_RAR:
  378. deliverRAR((ReAuthRequest) localEvent.getRequest());
  379. break;
  380. case SEND_RAA:
  381. try {
  382. dispatchEvent(localEvent.getAnswer());
  383. }
  384. catch (Exception e) {
  385. handleSendFailure(e, eventType, localEvent.getRequest().getMessage());
  386. }
  387. break;
  388. default:
  389. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  390. break;
  391. }
  392. break;
  393. case PENDING_UPDATE:
  394. answer = (AppAnswerEvent) localEvent.getAnswer();
  395. switch (eventType) {
  396. case RECEIVED_UPDATE_ANSWER:
  397. long resultCode = answer.getResultCodeAvp().getUnsigned32();
  398. if (isSuccess(resultCode)) {
  399. // Current State: PENDING_U
  400. // Event: Successful CC update answer received
  401. // Action: Stop Tx
  402. // New State: OPEN
  403. stopTx();
  404. setState(ClientRoSessionState.OPEN);
  405. }
  406. else if (isProvisional(resultCode) || isFailure(resultCode)) {
  407. handleFailureMessage((RoCreditControlAnswer) answer, (RoCreditControlRequest) localEvent.getRequest(), eventType);
  408. }
  409. deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer());
  410. break;
  411. case Tx_TIMER_FIRED:
  412. handleTxExpires(localEvent.getRequest().getMessage());
  413. break;
  414. case SEND_UPDATE_REQUEST:
  415. case SEND_TERMINATE_REQUEST:
  416. // Current State: PENDING_U
  417. // Event: User service terminated
  418. // Action: Queue termination event
  419. // New State: PENDING_U
  420. // Current State: PENDING_U
  421. // Event: Change in rating condition
  422. // Action: Queue changed rating condition event
  423. // New State: PENDING_U
  424. eventQueue.add(localEvent);
  425. break;
  426. case RECEIVED_RAR:
  427. deliverRAR((ReAuthRequest) localEvent.getRequest());
  428. break;
  429. case SEND_RAA:
  430. // Current State: PENDING_U
  431. // Event: RAR received
  432. // Action: Send RAA
  433. // New State: PENDING_U
  434. try {
  435. dispatchEvent(localEvent.getAnswer());
  436. }
  437. catch (Exception e) {
  438. handleSendFailure(e, eventType, localEvent.getRequest().getMessage());
  439. }
  440. break;
  441. }
  442. break;
  443. case PENDING_TERMINATION:
  444. switch (eventType) {
  445. case SEND_UPDATE_REQUEST:
  446. try {
  447. // Current State: PENDING_T
  448. // Event: Change in rating condition
  449. // Action: -
  450. // New State: PENDING_T
  451. dispatchEvent(localEvent.getRequest());
  452. // No transition
  453. }
  454. catch (Exception e) {
  455. // This handles failure to send in PendingI state in FSM table
  456. // handleSendFailure(e, eventType);
  457. }
  458. break;
  459. case RECEIVED_TERMINATED_ANSWER:
  460. // Current State: PENDING_T
  461. // Event: Successful CC termination answer received
  462. // Action: -
  463. // New State: IDLE
  464. // Current State: PENDING_T
  465. // Event: Failure to send, temporary error, or failed answer
  466. // Action: -
  467. // New State: IDLE
  468. //FIXME: Alex broke this, setting back "true" ?
  469. //setState(ClientRoSessionState.IDLE, false);
  470. deliverRoAnswer((RoCreditControlRequest) localEvent.getRequest(), (RoCreditControlAnswer) localEvent.getAnswer());
  471. setState(ClientRoSessionState.IDLE, true);
  472. break;
  473. default:
  474. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  475. break;
  476. }
  477. break;
  478. default:
  479. // any other state is bad
  480. setState(ClientRoSessionState.IDLE, true);
  481. }
  482. dispatch();
  483. return true;
  484. }
  485. catch (Exception e) {
  486. throw new InternalException(e);
  487. }
  488. finally {
  489. sendAndStateLock.unlock();
  490. }
  491. }
  492. public Answer processRequest(Request request) {
  493. RequestDelivery rd = new RequestDelivery();
  494. rd.session = this;
  495. rd.request = request;
  496. super.scheduler.execute(rd);
  497. return null;
  498. }
  499. public void receivedSuccessMessage(Request request, Answer answer) {
  500. AnswerDelivery ad = new AnswerDelivery();
  501. ad.session = this;
  502. ad.request = request;
  503. ad.answer = answer;
  504. super.scheduler.execute(ad);
  505. }
  506. public void timeoutExpired(Request request) {
  507. if(request.getCommandCode()== RoCreditControlAnswer.code) {
  508. try {
  509. sendAndStateLock.lock();
  510. handleSendFailure(null, null, request);
  511. }
  512. catch (Exception e) {
  513. logger.debug("Failure processing timeout message for request", e);
  514. }
  515. finally {
  516. sendAndStateLock.unlock();
  517. }
  518. }
  519. }
  520. protected void startTx(RoCreditControlRequest request) {
  521. long txTimerValue = context.getDefaultTxTimerValue();
  522. if (txTimerValue < 0) {
  523. txTimerValue = TX_TIMER_DEFAULT_VALUE;
  524. }
  525. stopTx();
  526. logger.debug("Scheduling TX Timer {}", txTimerValue);
  527. //this.txFuture = scheduler.schedule(new TxTimerTask(this, request), txTimerValue, TimeUnit.SECONDS);
  528. try {
  529. sessionData.setTxTimerRequest((Request) request.getMessage());
  530. sessionData.setTxTimerId(this.timerFacility.schedule(this.sessionData.getSessionId(), TX_TIMER_NAME, TX_TIMER_DEFAULT_VALUE));
  531. }
  532. catch (Exception e) {
  533. throw new IllegalArgumentException("Failed to store request.", e);
  534. }
  535. }
  536. protected void stopTx() {
  537. Serializable txTimerId = this.sessionData.getTxTimerId();
  538. if(txTimerId != null) {
  539. timerFacility.cancel(txTimerId);
  540. sessionData.setTxTimerId(null);
  541. sessionData.setTxTimerRequest(null);
  542. }
  543. }
  544. /* (non-Javadoc)
  545. * @see org.jdiameter.common.impl.app.AppSessionImpl#onTimer(java.lang.String)
  546. */
  547. @Override
  548. public void onTimer(String timerName) {
  549. if(timerName.equals(TX_TIMER_NAME)) {
  550. new TxTimerTask(this, sessionData.getTxTimerRequest()).run();
  551. }
  552. }
  553. protected void setState(ClientRoSessionState newState) {
  554. setState(newState, true);
  555. }
  556. @SuppressWarnings("unchecked")
  557. protected void setState(ClientRoSessionState newState, boolean release) {
  558. try {
  559. IAppSessionState state = sessionData.getClientRoSessionState();
  560. IAppSessionState oldState = state;
  561. sessionData.setClientRoSessionState(newState);
  562. for (StateChangeListener i : stateListeners) {
  563. i.stateChanged(this,(Enum) oldState, (Enum) newState);
  564. }
  565. if (newState == ClientRoSessionState.IDLE) {
  566. if (release) {
  567. this.release();
  568. }
  569. stopTx();
  570. }
  571. }
  572. catch (Exception e) {
  573. if(logger.isDebugEnabled()) {
  574. logger.debug("Failure switching to state " + sessionData.getClientRoSessionState() + " (release=" + release + ")", e);
  575. }
  576. }
  577. }
  578. @Override
  579. public void release() {
  580. if (isValid()) {
  581. try {
  582. this.sendAndStateLock.lock();
  583. this.stopTx();
  584. super.release();
  585. }
  586. catch (Exception e) {
  587. logger.debug("Failed to release session", e);
  588. }
  589. finally {
  590. this.sendAndStateLock.unlock();
  591. }
  592. }
  593. else {
  594. logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId());
  595. }
  596. }
  597. protected void handleSendFailure(Exception e, Event.Type eventType, Message request) throws Exception {
  598. logger.debug("Failed to send message, type: {} message: {}, failure: {}", new Object[]{eventType, request, e != null ? e.getLocalizedMessage() : ""});
  599. try {
  600. ClientRoSessionState state = sessionData.getClientRoSessionState();
  601. int gatheredRequestedAction = sessionData.getGatheredRequestedAction();
  602. // Event Based ----------------------------------------------------------
  603. if (isEventBased()) {
  604. switch (state) {
  605. case PENDING_EVENT:
  606. if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) {
  607. // Current State: PENDING_E
  608. // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY
  609. // Action: Indicate service error
  610. // New State: IDLE
  611. setState(ClientRoSessionState.IDLE);
  612. context.indicateServiceError(this);
  613. }
  614. else if (gatheredRequestedAction == DIRECT_DEBITING) {
  615. switch(getLocalDDFH()) {
  616. case DDFH_TERMINATE_OR_BUFFER:
  617. // Current State: PENDING_E
  618. // Event: Failure to send; request action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER
  619. // Action: Store request with T-flag
  620. // New State: IDLE
  621. request.setReTransmitted(true);
  622. sessionData.setBuffer((Request) request);
  623. setState(ClientRoSessionState.IDLE, false);
  624. break;
  625. case DDFH_CONTINUE:
  626. // Current State: PENDING_E
  627. // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE
  628. // Action: Grant service to end user
  629. // New State: IDLE
  630. context.grantAccessOnDeliverFailure(this, request);
  631. break;
  632. default:
  633. logger.warn("Invalid Direct-Debiting-Failure-Handling AVP value {}", getLocalDDFH());
  634. }
  635. }
  636. else if (gatheredRequestedAction == REFUND_ACCOUNT) {
  637. // Current State: PENDING_E
  638. // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT
  639. // Action: Store request with T-flag
  640. // New State: IDLE
  641. setState(ClientRoSessionState.IDLE, false);
  642. request.setReTransmitted(true);
  643. sessionData.setBuffer((Request) request);
  644. }
  645. else {
  646. logger.warn("Invalid Requested-Action AVP value {}", gatheredRequestedAction);
  647. }
  648. break;
  649. case PENDING_BUFFERED:
  650. // Current State: PENDING_B
  651. // Event: Failure to send or temporary error
  652. // Action: -
  653. // New State: IDLE
  654. setState(ClientRoSessionState.IDLE, false);
  655. sessionData.setBuffer(null);// FIXME: Action does not mention, but ...
  656. break;
  657. default:
  658. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  659. break;
  660. }
  661. }
  662. // Session Based --------------------------------------------------------
  663. else {
  664. switch (getLocalCCFH()) {
  665. case CCFH_CONTINUE:
  666. // Current State: PENDING_I
  667. // Event: Failure to send, or temporary error and CCFH equal to CONTINUE
  668. // Action: Grant service to end user
  669. // New State: IDLE
  670. // Current State: PENDING_U
  671. // Event: Failure to send, or temporary error and CCFH equal to CONTINUE
  672. // Action: Grant service to end user
  673. // New State: IDLE
  674. setState(ClientRoSessionState.IDLE, false);
  675. this.context.grantAccessOnDeliverFailure(this, request);
  676. break;
  677. default:
  678. // Current State: PENDING_I
  679. // Event: Failure to send, or temporary error and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE
  680. // Action: Terminate end user?s service
  681. // New State: IDLE
  682. // Current State: PENDING_U
  683. // Event: Failure to send, or temporary error and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE
  684. // Action: Terminate end user?s service
  685. // New State: IDLE
  686. this.context.denyAccessOnDeliverFailure(this, request);
  687. setState(ClientRoSessionState.IDLE, true);
  688. break;
  689. }
  690. }
  691. }
  692. finally {
  693. dispatch();
  694. }
  695. }
  696. protected void handleFailureMessage(RoCreditControlAnswer event, RoCreditControlRequest request, Event.Type eventType) {
  697. try {
  698. // Event Based ----------------------------------------------------------
  699. long resultCode = event.getResultCodeAvp().getUnsigned32();
  700. ClientRoSessionState state = sessionData.getClientRoSessionState();
  701. int gatheredRequestedAction = sessionData.getGatheredRequestedAction();
  702. Serializable txTimerId = sessionData.getTxTimerId();
  703. if (isEventBased()) {
  704. switch (state) {
  705. case PENDING_EVENT:
  706. if (resultCode == END_USER_SERVICE_DENIED || resultCode == USER_UNKNOWN) {
  707. if(txTimerId != null) {
  708. // Current State: PENDING_E
  709. // Event: CC event answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN and Tx running
  710. // Action: Terminate end user?s service
  711. // New State: IDLE
  712. context.denyAccessOnFailureMessage(this);
  713. deliverRoAnswer(request, event);
  714. setState(ClientRoSessionState.IDLE);
  715. }
  716. else if(gatheredRequestedAction == DIRECT_DEBITING && txTimerId == null) {
  717. // Current State: PENDING_E
  718. // Event: Failed answer or answer received with result code END_USER_SERVICE DENIED or USER_UNKNOWN; requested action DIRECT_DEBITING; Tx expired
  719. // Action: -
  720. // New State: IDLE
  721. setState(ClientRoSessionState.IDLE);
  722. }
  723. }
  724. else if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE && gatheredRequestedAction == DIRECT_DEBITING) {
  725. // Current State: PENDING_E
  726. // Event: CC event answer received with result code CREDIT_CONTROL_NOT_APPLICABLE; requested action DIRECT_DEBITING
  727. // Action: Grant service to end user
  728. // New State: IDLE
  729. context.grantAccessOnFailureMessage(this);
  730. deliverRoAnswer(request, event);
  731. setState(ClientRoSessionState.IDLE);
  732. }
  733. else if (temporaryErrorCodes.contains(resultCode)) {
  734. if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) {
  735. // Current State: PENDING_E
  736. // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY
  737. // Action: Indicate service error
  738. // New State: IDLE
  739. context.indicateServiceError(this);
  740. deliverRoAnswer(request, event);
  741. setState(ClientRoSessionState.IDLE);
  742. }
  743. else if (gatheredRequestedAction == DIRECT_DEBITING) {
  744. if(getLocalDDFH() == DDFH_CONTINUE) {
  745. // Current State: PENDING_E
  746. // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE
  747. // Action: Grant service to end user
  748. // New State: IDLE
  749. context.grantAccessOnFailureMessage(this);
  750. deliverRoAnswer(request, event);
  751. setState(ClientRoSessionState.IDLE);
  752. }
  753. else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) {
  754. // Current State: PENDING_E
  755. // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running
  756. // Action: Terminate end user?s service
  757. // New State: IDLE
  758. context.denyAccessOnFailureMessage(this);
  759. deliverRoAnswer(request, event);
  760. setState(ClientRoSessionState.IDLE);
  761. }
  762. }
  763. else if (gatheredRequestedAction == REFUND_ACCOUNT) {
  764. // Current State: PENDING_E
  765. // Event: Temporary error, and requested action REFUND_ACCOUNT
  766. // Action: Store request
  767. // New State: IDLE
  768. sessionData.setBuffer((Request) request);
  769. setState(ClientRoSessionState.IDLE, false);
  770. }
  771. else {
  772. logger.warn("Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId});
  773. }
  774. }
  775. else { // Failure
  776. if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) {
  777. // Current State: PENDING_E
  778. // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY
  779. // Action: Indicate service error
  780. // New State: IDLE
  781. context.indicateServiceError(this);
  782. deliverRoAnswer(request, event);
  783. setState(ClientRoSessionState.IDLE);
  784. }
  785. else if (gatheredRequestedAction == DIRECT_DEBITING) {
  786. if(getLocalDDFH() == DDFH_CONTINUE) {
  787. // Current State: PENDING_E
  788. // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action DIRECT_DEBITING; DDFH equal to CONTINUE
  789. // Action: Grant service to end user
  790. // New State: IDLE
  791. context.grantAccessOnFailureMessage(this);
  792. deliverRoAnswer(request, event);
  793. setState(ClientRoSessionState.IDLE);
  794. }
  795. else if (getLocalDDFH() == DDFH_TERMINATE_OR_BUFFER && txTimerId != null) {
  796. // Current State: PENDING_E
  797. // Event: Failed CC event answer received or temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER and Tx running
  798. // Action: Terminate end user?s service
  799. // New State: IDLE
  800. context.denyAccessOnFailureMessage(this);
  801. deliverRoAnswer(request, event);
  802. setState(ClientRoSessionState.IDLE);
  803. }
  804. }
  805. else if (gatheredRequestedAction == REFUND_ACCOUNT) {
  806. // Current State: PENDING_E
  807. // Event: Failed CC event answer received; requested action REFUND_ACCOUNT
  808. // Action: Indicate service error and delete request
  809. // New State: IDLE
  810. sessionData.setBuffer(null);
  811. context.indicateServiceError(this);
  812. deliverRoAnswer(request, event);
  813. setState(ClientRoSessionState.IDLE);
  814. }
  815. else {
  816. logger.warn("Invalid combination for Ro Client FSM: State {}, Result-Code {}, Requested-Action {}, DDFH {}, Tx {}", new Object[]{state, resultCode, gatheredRequestedAction, getLocalDDFH(), txTimerId});
  817. }
  818. }
  819. break;
  820. case PENDING_BUFFERED:
  821. // Current State: PENDING_B
  822. // Event: Failed CC answer received
  823. // Action: Delete request
  824. // New State: IDLE
  825. sessionData.setBuffer(null);
  826. setState(ClientRoSessionState.IDLE, false);
  827. break;
  828. default:
  829. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  830. }
  831. }
  832. // Session Based --------------------------------------------------------
  833. else {
  834. switch (state) {
  835. case PENDING_INITIAL:
  836. if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE) {
  837. // Current State: PENDING_I
  838. // Event: CC initial answer received with result code equal to CREDIT_CONTROL_NOT_APPLICABLE
  839. // Action: Grant service to end user
  840. // New State: IDLE
  841. context.grantAccessOnFailureMessage(this);
  842. setState(ClientRoSessionState.IDLE, false);
  843. }
  844. else if ((resultCode == END_USER_SERVICE_DENIED) || (resultCode == USER_UNKNOWN)) {
  845. // Current State: PENDING_I
  846. // Event: CC initial answer received with result code END_USER_SERVICE_DENIED or USER_UNKNOWN
  847. // Action: Terminate end user?s service
  848. // New State: IDLE
  849. context.denyAccessOnFailureMessage(this);
  850. setState(ClientRoSessionState.IDLE, false);
  851. }
  852. else {
  853. // Temporary errors and others
  854. switch (getLocalCCFH()) {
  855. case CCFH_CONTINUE:
  856. // Current State: PENDING_I
  857. // Event: Failed CC initial answer received and CCFH equal to CONTINUE
  858. // Action: Grant service to end user
  859. // New State: IDLE
  860. context.grantAccessOnFailureMessage(this);
  861. setState(ClientRoSessionState.IDLE, false);
  862. break;
  863. case CCFH_TERMINATE:
  864. case CCFH_RETRY_AND_TERMINATE:
  865. // Current State: PENDING_I
  866. // Event: Failed CC initial answer received and CCFH equal to TERMINATE or to RETRY_AND_TERMINATE
  867. // Action: Terminate end user?s service
  868. // New State: IDLE
  869. context.denyAccessOnFailureMessage(this);
  870. setState(ClientRoSessionState.IDLE, false);
  871. break;
  872. default:
  873. logger.warn("Invalid value for CCFH: {}", getLocalCCFH());
  874. break;
  875. }
  876. }
  877. break;
  878. case PENDING_UPDATE:
  879. if (resultCode == CREDIT_CONTROL_NOT_APPLICABLE) {
  880. // Current State: PENDING_U
  881. // Event: CC update answer received with result code equal to CREDIT_CONTROL_NOT_APPLICABLE
  882. // Action: Grant service to end user
  883. // New State: IDLE
  884. context.grantAccessOnFailureMessage(this);
  885. setState(ClientRoSessionState.IDLE, false);
  886. }
  887. else if (resultCode == END_USER_SERVICE_DENIED) {
  888. // Current State: PENDING_U
  889. // Event: CC update answer received with result code END_USER_SERVICE_DENIED
  890. // Action: Terminate end user?s service
  891. // New State: IDLE
  892. context.denyAccessOnFailureMessage(this);
  893. setState(ClientRoSessionState.IDLE, false);
  894. }
  895. else {
  896. // Temporary errors and others
  897. switch (getLocalCCFH()) {
  898. case CCFH_CONTINUE:
  899. // Current State: PENDING_U
  900. // Event: Failed CC update answer received and CCFH equal to CONTINUE
  901. // Action: Grant service to end user
  902. // New State: IDLE
  903. context.grantAccessOnFailureMessage(this);
  904. setState(ClientRoSessionState.IDLE, false);
  905. break;
  906. case CCFH_TERMINATE:
  907. case CCFH_RETRY_AND_TERMINATE:
  908. // Current State: PENDING_U
  909. // Event: Failed CC update answer received and CCFH equal to CONTINUE or to RETRY_AND_CONTINUE
  910. // Action: Terminate end user?s service
  911. // New State: IDLE
  912. context.denyAccessOnFailureMessage(this);
  913. setState(ClientRoSessionState.IDLE, false);
  914. break;
  915. default:
  916. logger.warn("Invalid value for CCFH: " + getLocalCCFH());
  917. break;
  918. }
  919. }
  920. break;
  921. default:
  922. logger.warn("Wrong event type ({}) on state {}", eventType, state);
  923. }
  924. }
  925. }
  926. catch (Exception e) {
  927. if(logger.isDebugEnabled()) {
  928. logger.debug("Failure handling failure message for Event " + event + " (" + eventType + ") and Request " + request, e);
  929. }
  930. }
  931. }
  932. protected void handleTxExpires(Message message) {
  933. // Event Based ----------------------------------------------------------
  934. ClientRoSessionState state = sessionData.getClientRoSessionState();
  935. int gatheredRequestedAction = sessionData.getGatheredRequestedAction();
  936. if (isEventBased()) {
  937. if (gatheredRequestedAction == CHECK_BALANCE || gatheredRequestedAction == PRICE_ENQUIRY) {
  938. // Current State: PENDING_E
  939. // Event: Failure to send, temporary error, failed CC event answer received or Tx expired; requested action CHECK_BALANCE or PRICE_ENQUIRY
  940. // Action: Indicate service error
  941. // New State: IDLE
  942. context.indicateServiceError(this);
  943. setState(ClientRoSessionState.IDLE);
  944. }
  945. else if (gatheredRequestedAction == DIRECT_DEBITING) {
  946. if(sessionData.getGatheredDDFH() == DDFH_TERMINATE_OR_BUFFER) {
  947. // Current State: PENDING_E
  948. // Event: Temporary error; requested action DIRECT_DEBITING; DDFH equal to TERMINATE_OR_BUFFER; Tx expired
  949. // Action: Store request
  950. // New State: IDLE
  951. sessionData.setBuffer((Request) message);
  952. setState(ClientRoSessionState.IDLE, false);
  953. }
  954. else {
  955. // Current State: PENDING_E
  956. // Event: Tx expired; requested action DIRECT_DEBITING
  957. // Action: Grant service to end user
  958. // New State: PENDING_E
  959. context.grantAccessOnTxExpire(this);
  960. setState(ClientRoSessionState.PENDING_EVENT);
  961. }
  962. }
  963. else if (gatheredRequestedAction == REFUND_ACCOUNT) {
  964. // Current State: PENDING_E
  965. // Event: Failure to send or Tx expired; requested action REFUND_ACCOUNT
  966. // Action: Store request with T-flag
  967. // New State: IDLE
  968. message.setReTransmitted(true);
  969. sessionData.setBuffer((Request) message);
  970. setState(ClientRoSessionState.IDLE, false);
  971. }
  972. }
  973. // Session Based --------------------------------------------------------
  974. else {
  975. switch (state) {
  976. case PENDING_INITIAL:
  977. switch (getLocalCCFH()) {
  978. case CCFH_CONTINUE:
  979. case CCFH_RETRY_AND_TERMINATE:
  980. // Current State: PENDING_I
  981. // Event: Tx expired and CCFH equal to CONTINUE or to RETRY_AND_TERMINATE
  982. // Action: Grant service to end user
  983. // New State: PENDING_I
  984. context.grantAccessOnTxExpire(this);
  985. break;
  986. case CCFH_TERMINATE:
  987. // Current State: PENDING_I
  988. // Event: Tx expired and CCFH equal to TERMINATE
  989. // Action: Terminate end user?s service
  990. // New State: IDLE
  991. context.denyAccessOnTxExpire(this);
  992. setState(ClientRoSessionState.IDLE, true);
  993. break;
  994. default:
  995. logger.warn("Invalid value for CCFH: " + getLocalCCFH());
  996. break;
  997. }
  998. break;
  999. case PENDING_UPDATE:
  1000. switch (getLocalCCFH()) {
  1001. case CCFH_CONTINUE:
  1002. case CCFH_RETRY_AND_TERMINATE:
  1003. // Current State: PENDING_U
  1004. // Event: Tx expired and CCFH equal to CONTINUE or to RETRY_AND_TERMINATE
  1005. // Action: Grant service to end user
  1006. // New State: PENDING_U
  1007. context.grantAccessOnTxExpire(this);
  1008. break;
  1009. case CCFH_TERMINATE:
  1010. // Current State: PENDING_U
  1011. // Event: Tx expired and CCFH equal to TERMINATE
  1012. // Action: Terminate end user?s service
  1013. // New State: IDLE
  1014. context.denyAccessOnTxExpire(this);
  1015. setState(ClientRoSessionState.IDLE, true);
  1016. break;
  1017. default:
  1018. logger.error("Bad value of CCFH: " + getLocalCCFH());
  1019. break;
  1020. }
  1021. break;
  1022. default:
  1023. logger.error("Unknown state (" + sessionData.getClientRoSessionState() + ") on txExpire");
  1024. break;
  1025. }
  1026. }
  1027. }
  1028. /**
  1029. * This makes checks on queue, moves it to proper state if event there is
  1030. * present on Open state ;]
  1031. */
  1032. protected void dispatch() {
  1033. // Event Based ----------------------------------------------------------
  1034. if (isEventBased()) {
  1035. // Current State: IDLE
  1036. // Event: Request in storage
  1037. // Action: Send stored request
  1038. // New State: PENDING_B
  1039. Request buffer = sessionData.getBuffer();
  1040. if (buffer != null) {
  1041. setState(ClientRoSessionState.PENDING_BUFFERED);
  1042. try {
  1043. dispatchEvent(new AppRequestEventImpl(buffer));
  1044. }
  1045. catch (Exception e) {
  1046. try {
  1047. handleSendFailure(e, Event.Type.SEND_EVENT_REQUEST,buffer);
  1048. }
  1049. catch (Exception e1) {
  1050. logger.error("Failure handling buffer send failure", e1);
  1051. }
  1052. }
  1053. }
  1054. }
  1055. // Session Based --------------------------------------------------------
  1056. else {
  1057. if (sessionData.getClientRoSessionState() == ClientRoSessionState.OPEN && eventQueue.size() > 0) {
  1058. try {
  1059. this.handleEvent(eventQueue.remove(0));
  1060. }
  1061. catch (Exception e) {
  1062. logger.error("Failure handling queued event", e);
  1063. }
  1064. }
  1065. }
  1066. }
  1067. protected void deliverRoAnswer(RoCreditControlRequest request, RoCreditControlAnswer answer) {
  1068. try {
  1069. if(isValid()) {
  1070. listener.doCreditControlAnswer(this, request, answer);
  1071. }
  1072. }
  1073. catch (Exception e) {
  1074. logger.warn("Failure delivering Ro Answer", e);
  1075. }
  1076. }
  1077. protected void extractFHAVPs(RoCreditControlRequest request, RoCreditControlAnswer answer) throws AvpDataException {
  1078. if (answer != null) {
  1079. try {
  1080. if (answer.isCreditControlFailureHandlingAVPPresent()) {
  1081. sessionData.setGatheredCCFH(answer.getCredidControlFailureHandlingAVPValue());
  1082. }
  1083. }
  1084. catch (Exception e) {
  1085. logger.debug("Failure trying to obtain Credit-Control-Failure-Handling AVP value", e);
  1086. }
  1087. try {
  1088. if (answer.isDirectDebitingFailureHandlingAVPPresent()) {
  1089. sessionData.setGatheredDDFH(answer.getDirectDebitingFailureHandlingAVPValue());
  1090. }
  1091. }
  1092. catch (Exception e) {
  1093. logger.debug("Failure trying to obtain Direct-Debit-Failure-Handling AVP value", e);
  1094. }
  1095. if(!sessionData.isRequestTypeSet()) {
  1096. sessionData.setRequestTypeSet(true);
  1097. // No need to check if it exists.. it must, if not fail with exception
  1098. sessionData.setEventBased(answer.getRequestTypeAVPValue() == EVENT_REQUEST);
  1099. }
  1100. }
  1101. else if (request != null) {
  1102. try {
  1103. if (request.isRequestedActionAVPPresent()) {
  1104. sessionData.setGatheredRequestedAction(request.getRequestedActionAVPValue());
  1105. }
  1106. }
  1107. catch (Exception e) {
  1108. logger.debug("Failure trying to obtain Request-Action AVP value", e);
  1109. }
  1110. if(!sessionData.isRequestTypeSet()) {
  1111. sessionData.setRequestTypeSet(true);
  1112. // No need to check if it exists.. it must, if not fail with exception
  1113. sessionData.setEventBased(request.getRequestTypeAVPValue() == EVENT_REQUEST);
  1114. }
  1115. }
  1116. }
  1117. protected void deliverRAR(ReAuthRequest request) {
  1118. try {
  1119. listener.doReAuthRequest(this, request);
  1120. }
  1121. catch (Exception e) {
  1122. logger.debug("Failure delivering RAR", e);
  1123. }
  1124. }
  1125. protected void dispatchEvent(AppEvent event) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException {
  1126. session.send(event.getMessage(), this);
  1127. }
  1128. protected boolean isProvisional(long resultCode) {
  1129. return resultCode >= 1000 && resultCode < 2000;
  1130. }
  1131. protected boolean isSuccess(long resultCode) {
  1132. return resultCode >= 2000 && resultCode < 3000;
  1133. }
  1134. protected boolean isFailure(long code) {
  1135. return (!isProvisional(code) && !isSuccess(code) && ((code >= 3000 && /*code < 4000) || (code >= 5000 &&*/ code < 6000)) && !temporaryErrorCodes.contains(code));
  1136. }
  1137. /* (non-Javadoc)
  1138. * @see org.jdiameter.common.impl.app.AppSessionImpl#isReplicable()
  1139. */
  1140. @Override
  1141. public boolean isReplicable() {
  1142. return true;
  1143. }
  1144. private class TxTimerTask implements Runnable {
  1145. private ClientRoSession session = null;
  1146. private Request request = null;
  1147. private TxTimerTask(ClientRoSession session, Request request) {
  1148. super();
  1149. this.session = session;
  1150. this.request = request;
  1151. }
  1152. public void run() {
  1153. try {
  1154. sendAndStateLock.lock();
  1155. logger.debug("Fired TX Timer");
  1156. session

Large files files are truncated, but you can click here to view the full file