PageRenderTime 41ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/servers/diameter/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/cca/AbstractClient.java

http://mobicents.googlecode.com/
Java | 508 lines | 137 code | 61 blank | 310 comment | 2 complexity | f23fc6dc978b0bb6f210c1e46bfd86a8 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 XXXX, Red Hat Middleware LLC, and individual contributors as indicated
  4. * by the @authors tag. All rights reserved.
  5. * See the copyright.txt in the distribution for a full listing
  6. * of individual contributors.
  7. * This copyrighted material is made available to anyone wishing to use,
  8. * modify, copy, or redistribute it subject to the terms and conditions
  9. * of the GNU General Public License, v. 2.0.
  10. * This program is distributed in the hope that it will be useful, but WITHOUT A
  11. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12. * PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. * You should have received a copy of the GNU General Public License,
  14. * v. 2.0 along with this distribution; if not, write to the Free Software
  15. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16. * MA 02110-1301, USA.
  17. */
  18. package org.mobicents.diameter.stack.functional.cca;
  19. import java.io.InputStream;
  20. import java.util.ArrayList;
  21. import java.util.List;
  22. import java.util.UUID;
  23. import java.util.concurrent.TimeUnit;
  24. import org.jdiameter.api.Answer;
  25. import org.jdiameter.api.ApplicationId;
  26. import org.jdiameter.api.Avp;
  27. import org.jdiameter.api.AvpSet;
  28. import org.jdiameter.api.IllegalDiameterStateException;
  29. import org.jdiameter.api.InternalException;
  30. import org.jdiameter.api.Message;
  31. import org.jdiameter.api.Mode;
  32. import org.jdiameter.api.Request;
  33. import org.jdiameter.api.cca.ClientCCASession;
  34. import org.jdiameter.api.cca.ClientCCASessionListener;
  35. import org.jdiameter.api.cca.ServerCCASession;
  36. import org.jdiameter.api.cca.events.JCreditControlRequest;
  37. import org.jdiameter.client.api.ISessionFactory;
  38. import org.jdiameter.common.api.app.cca.ClientCCASessionState;
  39. import org.jdiameter.common.api.app.cca.IClientCCASessionContext;
  40. import org.jdiameter.common.impl.app.cca.CCASessionFactoryImpl;
  41. import org.jdiameter.common.impl.app.cca.JCreditControlRequestImpl;
  42. import org.mobicents.diameter.stack.functional.StateChange;
  43. import org.mobicents.diameter.stack.functional.TBase;
  44. /**
  45. * @author baranowb
  46. *
  47. */
  48. public abstract class AbstractClient extends TBase implements ClientCCASessionListener, IClientCCASessionContext {
  49. // NOTE: implementing NetworkReqListener since its required for stack to
  50. // know we support it... ech.
  51. protected static final int CC_REQUEST_TYPE_INITIAL = 1;
  52. protected static final int CC_REQUEST_TYPE_INTERIM = 2;
  53. protected static final int CC_REQUEST_TYPE_TERMINATE = 3;
  54. protected static final int CC_REQUEST_TYPE_EVENT = 4;
  55. protected ClientCCASession clientCCASession;
  56. protected int ccRequestNumber = 0;
  57. protected List<StateChange<ClientCCASessionState>> stateChanges = new ArrayList<StateChange<ClientCCASessionState>>(); // state changes
  58. public void init(InputStream configStream, String clientID) throws Exception {
  59. try {
  60. super.init(configStream, clientID, ApplicationId.createByAuthAppId(0, 4));
  61. CCASessionFactoryImpl creditControlSessionFactory = new CCASessionFactoryImpl(this.sessionFactory);
  62. ((ISessionFactory) sessionFactory).registerAppFacory(ServerCCASession.class, creditControlSessionFactory);
  63. ((ISessionFactory) sessionFactory).registerAppFacory(ClientCCASession.class, creditControlSessionFactory);
  64. creditControlSessionFactory.setStateListener(this);
  65. creditControlSessionFactory.setClientSessionListener(this);
  66. creditControlSessionFactory.setClientContextListener(this);
  67. this.clientCCASession = ((ISessionFactory) this.sessionFactory).getNewAppSession(this.sessionFactory.getSessionId("xxTESTxx"), getApplicationId(), ClientCCASession.class, (Object) null);
  68. }
  69. finally {
  70. try {
  71. configStream.close();
  72. }
  73. catch (Exception e) {
  74. e.printStackTrace();
  75. }
  76. }
  77. }
  78. // ----------- delegate methods so
  79. public void start() throws IllegalDiameterStateException, InternalException {
  80. stack.start();
  81. }
  82. public void start(Mode mode, long timeOut, TimeUnit timeUnit) throws IllegalDiameterStateException, InternalException {
  83. stack.start(mode, timeOut, timeUnit);
  84. }
  85. public void stop(long timeOut, TimeUnit timeUnit, int disconnectCause) throws IllegalDiameterStateException, InternalException {
  86. stack.stop(timeOut, timeUnit, disconnectCause);
  87. }
  88. public void stop(int disconnectCause) {
  89. stack.stop(disconnectCause);
  90. }
  91. // ----------- conf parts
  92. /*
  93. * (non-Javadoc)
  94. *
  95. * @see org.jdiameter.common.api.app.cca.IClientCCASessionContext# getDefaultTxTimerValue()
  96. */
  97. public long getDefaultTxTimerValue() {
  98. return 10;
  99. }
  100. /*
  101. * (non-Javadoc)
  102. *
  103. * @see org.jdiameter.api.cca.ClientCCASessionListener#getDefaultDDFHValue()
  104. */
  105. public int getDefaultDDFHValue() {
  106. // DDFH_CONTINUE: 1
  107. return 1;
  108. }
  109. /*
  110. * (non-Javadoc)
  111. *
  112. * @see org.jdiameter.api.cca.ClientCCASessionListener#getDefaultCCFHValue()
  113. */
  114. public int getDefaultCCFHValue() {
  115. // CCFH_CONTINUE: 1
  116. return 1;
  117. }
  118. // ----------- should not be called..
  119. public void receivedSuccessMessage(Request request, Answer answer) {
  120. fail("Received \"SuccessMessage\" event, request[" + request + "], answer[" + answer + "]", null);
  121. }
  122. public void timeoutExpired(Request request) {
  123. fail("Received \"Timoeout\" event, request[" + request + "]", null);
  124. }
  125. public Answer processRequest(Request request) {
  126. fail("Received \"Request\" event, request[" + request + "]", null);
  127. return null;
  128. }
  129. // ------------ leave those
  130. /*
  131. * (non-Javadoc)
  132. *
  133. * @see org.jdiameter.common.api.app.cca.IClientCCASessionContext#txTimerExpired (org.jdiameter.api.cca.ClientCCASession)
  134. */
  135. public void txTimerExpired(ClientCCASession session) {
  136. // NOP
  137. }
  138. /*
  139. * (non-Javadoc)
  140. *
  141. * @see org.jdiameter.common.api.app.cca.IClientCCASessionContext# grantAccessOnDeliverFailure(org.jdiameter.api.cca.ClientCCASession,
  142. * org.jdiameter.api.Message)
  143. */
  144. public void grantAccessOnDeliverFailure(ClientCCASession clientCCASessionImpl, Message request) {
  145. // NOP
  146. }
  147. /*
  148. * (non-Javadoc)
  149. *
  150. * @see org.jdiameter.common.api.app.cca.IClientCCASessionContext# denyAccessOnDeliverFailure(org.jdiameter.api.cca.ClientCCASession,
  151. * org.jdiameter.api.Message)
  152. */
  153. public void denyAccessOnDeliverFailure(ClientCCASession clientCCASessionImpl, Message request) {
  154. // NOP
  155. }
  156. /*
  157. * (non-Javadoc)
  158. *
  159. * @see org.jdiameter.common.api.app.cca.IClientCCASessionContext# grantAccessOnTxExpire(org.jdiameter.api.cca.ClientCCASession)
  160. */
  161. public void grantAccessOnTxExpire(ClientCCASession clientCCASessionImpl) {
  162. // NOP
  163. }
  164. /*
  165. * (non-Javadoc)
  166. *
  167. * @see org.jdiameter.common.api.app.cca.IClientCCASessionContext# denyAccessOnTxExpire(org.jdiameter.api.cca.ClientCCASession)
  168. */
  169. public void denyAccessOnTxExpire(ClientCCASession clientCCASessionImpl) {
  170. // NOP
  171. }
  172. /*
  173. * (non-Javadoc)
  174. *
  175. * @see org.jdiameter.common.api.app.cca.IClientCCASessionContext# grantAccessOnFailureMessage(org.jdiameter.api.cca.ClientCCASession)
  176. */
  177. public void grantAccessOnFailureMessage(ClientCCASession clientCCASessionImpl) {
  178. // NOP
  179. }
  180. /*
  181. * (non-Javadoc)
  182. *
  183. * @see org.jdiameter.common.api.app.cca.IClientCCASessionContext# denyAccessOnFailureMessage(org.jdiameter.api.cca.ClientCCASession)
  184. */
  185. public void denyAccessOnFailureMessage(ClientCCASession clientCCASessionImpl) {
  186. // NOP
  187. }
  188. /*
  189. * (non-Javadoc)
  190. *
  191. * @see org.jdiameter.common.api.app.cca.IClientCCASessionContext# indicateServiceError(org.jdiameter.api.cca.ClientCCASession)
  192. */
  193. public void indicateServiceError(ClientCCASession clientCCASessionImpl) {
  194. // NOP
  195. }
  196. // ---------- some helper methods.
  197. protected JCreditControlRequest createCCR(int ccRequestType, int requestNumber, ClientCCASession ccaSession) throws Exception {
  198. // Create Credit-Control-Request
  199. JCreditControlRequest ccr = new JCreditControlRequestImpl(ccaSession.getSessions().get(0).createRequest(JCreditControlRequest.code, getApplicationId(), getServerRealmName()));
  200. // AVPs present by default: Origin-Host, Origin-Realm, Session-Id,
  201. // Vendor-Specific-Application-Id, Destination-Realm
  202. AvpSet ccrAvps = ccr.getMessage().getAvps();
  203. // Add remaining AVPs ... from RFC 4006:
  204. // <CCR> ::= < Diameter Header: 272, REQ, PXY >
  205. // < Session-Id >
  206. // ccrAvps.addAvp(Avp.SESSION_ID, s.getSessionId());
  207. // { Origin-Host }
  208. ccrAvps.removeAvp(Avp.ORIGIN_HOST);
  209. ccrAvps.addAvp(Avp.ORIGIN_HOST, getClientURI(), true);
  210. // { Origin-Realm }
  211. // ccrAvps.addAvp(Avp.ORIGIN_REALM, realmName, true);
  212. // { Destination-Realm }
  213. // ccrAvps.addAvp(Avp.DESTINATION_REALM, realmName, true);
  214. // { Auth-Application-Id }
  215. ccrAvps.addAvp(Avp.AUTH_APPLICATION_ID, 4);
  216. // { Service-Context-Id }
  217. // 8.42. Service-Context-Id AVP
  218. //
  219. // The Service-Context-Id AVP is of type UTF8String (AVP Code 461) and
  220. // contains a unique identifier of the Diameter credit-control service
  221. // specific document that applies to the request (as defined in section
  222. // 4.1.2). This is an identifier allocated by the service provider, by
  223. // the service element manufacturer, or by a standardization body, and
  224. // MUST uniquely identify a given Diameter credit-control service
  225. // specific document. The format of the Service-Context-Id is:
  226. //
  227. // "service-context" "@" "domain"
  228. //
  229. // service-context = Token
  230. //
  231. // The Token is an arbitrary string of characters and digits.
  232. //
  233. // 'domain' represents the entity that allocated the Service-Context-Id.
  234. // It can be ietf.org, 3gpp.org, etc., if the identifier is allocated by
  235. // a standardization body, or it can be the FQDN of the service provider
  236. // (e.g., provider.example.com) or of the vendor (e.g.,
  237. // vendor.example.com) if the identifier is allocated by a private
  238. // entity.
  239. //
  240. // This AVP SHOULD be placed as close to the Diameter header as
  241. // possible.
  242. //
  243. // Service-specific documents that are for private use only (i.e., to
  244. // one provider's own use, where no interoperability is deemed useful)
  245. // may define private identifiers without need of coordination.
  246. // However, when interoperability is wanted, coordination of the
  247. // identifiers via, for example, publication of an informational RFC is
  248. // RECOMMENDED in order to make Service-Context-Id globally available.
  249. String serviceContextId = getServiceContextId();
  250. if (serviceContextId == null) {
  251. serviceContextId = UUID.randomUUID().toString().replaceAll("-", "") + "@mss.mobicents.org";
  252. }
  253. ccrAvps.addAvp(Avp.SERVICE_CONTEXT_ID, serviceContextId, false);
  254. // { CC-Request-Type }
  255. // 8.3. CC-Request-Type AVP
  256. //
  257. // The CC-Request-Type AVP (AVP Code 416) is of type Enumerated and
  258. // contains the reason for sending the credit-control request message.
  259. // It MUST be present in all Credit-Control-Request messages. The
  260. // following values are defined for the CC-Request-Type AVP:
  261. //
  262. // INITIAL_REQUEST 1
  263. // An Initial request is used to initiate a credit-control session,
  264. // and contains credit control information that is relevant to the
  265. // initiation.
  266. //
  267. // UPDATE_REQUEST 2
  268. // An Update request contains credit-control information for an
  269. // existing credit-control session. Update credit-control requests
  270. // SHOULD be sent every time a credit-control re-authorization is
  271. // needed at the expiry of the allocated quota or validity time.
  272. // Further, additional service-specific events MAY trigger a
  273. // spontaneous Update request.
  274. //
  275. // TERMINATION_REQUEST 3
  276. // A Termination request is sent to terminate a credit-control
  277. // session and contains credit-control information relevant to the
  278. // existing session.
  279. //
  280. // EVENT_REQUEST 4
  281. // An Event request is used when there is no need to maintain any
  282. // credit-control session state in the credit-control server. This
  283. // request contains all information relevant to the service, and is
  284. // the only request of the service. The reason for the Event request
  285. // is further detailed in the Requested-Action AVP. The Requested-
  286. // Action AVP MUST be included in the Credit-Control-Request message
  287. // when CC-Request-Type is set to EVENT_REQUEST.
  288. ccrAvps.addAvp(Avp.CC_REQUEST_TYPE, ccRequestType);
  289. // { CC-Request-Number }
  290. // 8.2. CC-Request-Number AVP
  291. //
  292. // The CC-Request-Number AVP (AVP Code 415) is of type Unsigned32 and
  293. // identifies this request within one session. As Session-Id AVPs are
  294. // globally unique, the combination of Session-Id and CC-Request-Number
  295. // AVPs is also globally unique and can be used in matching credit-
  296. // control messages with confirmations. An easy way to produce unique
  297. // numbers is to set the value to 0 for a credit-control request of type
  298. // INITIAL_REQUEST and EVENT_REQUEST and to set the value to 1 for the
  299. // first UPDATE_REQUEST, to 2 for the second, and so on until the value
  300. // for TERMINATION_REQUEST is one more than for the last UPDATE_REQUEST.
  301. ccrAvps.addAvp(Avp.CC_REQUEST_NUMBER, requestNumber);
  302. // [ Destination-Host ]
  303. ccrAvps.removeAvp(Avp.DESTINATION_HOST);
  304. // ccrAvps.addAvp(Avp.DESTINATION_HOST, ccRequestType == 2 ?
  305. // serverURINode1 : serverURINode1, false);
  306. // [ User-Name ]
  307. // [ CC-Sub-Session-Id ]
  308. // [ Acct-Multi-Session-Id ]
  309. // [ Origin-State-Id ]
  310. // [ Event-Timestamp ]
  311. // *[ Subscription-Id ]
  312. // 8.46. Subscription-Id AVP
  313. //
  314. // The Subscription-Id AVP (AVP Code 443) is used to identify the end
  315. // user's subscription and is of type Grouped. The Subscription-Id AVP
  316. // includes a Subscription-Id-Data AVP that holds the identifier and a
  317. // Subscription-Id-Type AVP that defines the identifier type.
  318. //
  319. // It is defined as follows (per the grouped-avp-def of RFC 3588
  320. // [DIAMBASE]):
  321. //
  322. // Subscription-Id ::= < AVP Header: 443 >
  323. // { Subscription-Id-Type }
  324. // { Subscription-Id-Data }
  325. AvpSet subscriptionId = ccrAvps.addGroupedAvp(Avp.SUBSCRIPTION_ID);
  326. // 8.47. Subscription-Id-Type AVP
  327. //
  328. // The Subscription-Id-Type AVP (AVP Code 450) is of type Enumerated,
  329. // and it is used to determine which type of identifier is carried by
  330. // the Subscription-Id AVP.
  331. //
  332. // This specification defines the following subscription identifiers.
  333. // However, new Subscription-Id-Type values can be assigned by an IANA
  334. // designated expert, as defined in section 12. A server MUST implement
  335. // all the Subscription-Id-Types required to perform credit
  336. // authorization for the services it supports, including possible future
  337. // values. Unknown or unsupported Subscription-Id-Types MUST be treated
  338. // according to the 'M' flag rule, as defined in [DIAMBASE].
  339. //
  340. // END_USER_E164 0
  341. // The identifier is in international E.164 format (e.g., MSISDN),
  342. // according to the ITU-T E.164 numbering plan defined in [E164] and
  343. // [CE164].
  344. //
  345. // END_USER_IMSI 1
  346. // The identifier is in international IMSI format, according to the
  347. // ITU-T E.212 numbering plan as defined in [E212] and [CE212].
  348. //
  349. // END_USER_SIP_URI 2
  350. // The identifier is in the form of a SIP URI, as defined in [SIP].
  351. //
  352. // END_USER_NAI 3
  353. // The identifier is in the form of a Network Access Identifier, as
  354. // defined in [NAI].
  355. //
  356. // END_USER_PRIVATE 4
  357. // The Identifier is a credit-control server private identifier.
  358. subscriptionId.addAvp(Avp.SUBSCRIPTION_ID_TYPE, 2);
  359. // 8.48. Subscription-Id-Data AVP
  360. //
  361. // The Subscription-Id-Data AVP (AVP Code 444) is used to identify the
  362. // end user and is of type UTF8String. The Subscription-Id-Type AVP
  363. // defines which type of identifier is used.
  364. subscriptionId.addAvp(Avp.SUBSCRIPTION_ID_DATA, "sip:alexandre@mobicents.org", false);
  365. // [ Service-Identifier ]
  366. // [ Termination-Cause ]
  367. // [ Requested-Service-Unit ]
  368. // 8.18. Requested-Service-Unit AVP
  369. //
  370. // The Requested-Service-Unit AVP (AVP Code 437) is of type Grouped and
  371. // contains the amount of requested units specified by the Diameter
  372. // credit-control client. A server is not required to implement all the
  373. // unit types, and it must treat unknown or unsupported unit types as
  374. // invalid AVPs.
  375. //
  376. // The Requested-Service-Unit AVP is defined as follows (per the
  377. // grouped-avp-def of RFC 3588 [DIAMBASE]):
  378. //
  379. // Requested-Service-Unit ::= < AVP Header: 437 >
  380. // [ CC-Time ]
  381. // [ CC-Money ]
  382. // [ CC-Total-Octets ]
  383. // [ CC-Input-Octets ]
  384. // [ CC-Output-Octets ]
  385. // [ CC-Service-Specific-Units ]
  386. // *[ AVP ]
  387. AvpSet rsuAvp = ccrAvps.addGroupedAvp(Avp.REQUESTED_SERVICE_UNIT);
  388. // 8.21. CC-Time AVP
  389. //
  390. // The CC-Time AVP (AVP Code 420) is of type Unsigned32 and indicates
  391. // the length of the requested, granted, or used time in seconds.
  392. rsuAvp.addAvp(Avp.CC_TIME, getChargingUnitsTime());
  393. // [ Requested-Action ]
  394. // *[ Used-Service-Unit ]
  395. // 8.19. Used-Service-Unit AVP
  396. //
  397. // The Used-Service-Unit AVP is of type Grouped (AVP Code 446) and
  398. // contains the amount of used units measured from the point when the
  399. // service became active or, if interim interrogations are used during
  400. // the session, from the point when the previous measurement ended.
  401. //
  402. // The Used-Service-Unit AVP is defined as follows (per the grouped-
  403. // avp-def of RFC 3588 [DIAMBASE]):
  404. //
  405. // Used-Service-Unit ::= < AVP Header: 446 >
  406. // [ Tariff-Change-Usage ]
  407. // [ CC-Time ]
  408. // [ CC-Money ]
  409. // [ CC-Total-Octets ]
  410. // [ CC-Input-Octets ]
  411. // [ CC-Output-Octets ]
  412. // [ CC-Service-Specific-Units ]
  413. // *[ AVP ]
  414. // FIXME: alex :) ?
  415. // if(ccRequestNumber >= 1) {
  416. // AvpSet usedServiceUnit = ccrAvps.addGroupedAvp(Avp.USED_SERVICE_UNIT);
  417. // usedServiceUnit.addAvp(Avp.CC_TIME, this.partialCallDurationCounter);
  418. // System.out.println("USED SERVICE UNITS ==============================>"
  419. // + partialCallDurationCounter);
  420. // }
  421. // [ AoC-Request-Type ]
  422. // [ Multiple-Services-Indicator ]
  423. // *[ Multiple-Services-Credit-Control ]
  424. // *[ Service-Parameter-Info ]
  425. // [ CC-Correlation-Id ]
  426. // [ User-Equipment-Info ]
  427. // *[ Proxy-Info ]
  428. // *[ Route-Record ]
  429. // [ Service-Information ]
  430. // *[ AVP ]
  431. return ccr;
  432. }
  433. public String getSessionId() {
  434. return this.clientCCASession.getSessionId();
  435. }
  436. public void fetchSession(String sessionId) throws InternalException {
  437. this.clientCCASession = stack.getSession(sessionId, ClientCCASession.class);
  438. }
  439. public ClientCCASession getSession() {
  440. return this.clientCCASession;
  441. }
  442. public List<StateChange<ClientCCASessionState>> getStateChanges() {
  443. return stateChanges;
  444. }
  445. protected abstract int getChargingUnitsTime();
  446. protected abstract String getServiceContextId();
  447. }