PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

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

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