PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/servers/jain-slee/resources/diameter-rx/ra/src/main/java/org/mobicents/slee/resource/diameter/rx/RxMessageFactoryImpl.java

http://mobicents.googlecode.com/
Java | 503 lines | 363 code | 83 blank | 57 comment | 85 complexity | 12e1bbdf2a893f1dac910299037430ae 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 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.mobicents.slee.resource.diameter.rx;
  23. import java.util.Collections;
  24. import java.util.HashSet;
  25. import java.util.Set;
  26. import net.java.slee.resource.diameter.base.DiameterMessageFactory;
  27. import net.java.slee.resource.diameter.base.events.DiameterHeader;
  28. import net.java.slee.resource.diameter.base.events.DiameterMessage;
  29. import net.java.slee.resource.diameter.base.events.avp.AvpNotAllowedException;
  30. import net.java.slee.resource.diameter.base.events.avp.DiameterAvp;
  31. import net.java.slee.resource.diameter.base.events.avp.DiameterAvpCodes;
  32. import net.java.slee.resource.diameter.base.events.avp.DiameterIdentity;
  33. import net.java.slee.resource.diameter.base.events.avp.GroupedAvp;
  34. import net.java.slee.resource.diameter.rx.RxMessageFactory;
  35. import net.java.slee.resource.diameter.rx.events.AAAnswer;
  36. import net.java.slee.resource.diameter.rx.events.AARequest;
  37. import net.java.slee.resource.diameter.rx.events.AbortSessionAnswer;
  38. import net.java.slee.resource.diameter.rx.events.AbortSessionRequest;
  39. import net.java.slee.resource.diameter.rx.events.ReAuthAnswer;
  40. import net.java.slee.resource.diameter.rx.events.ReAuthRequest;
  41. import net.java.slee.resource.diameter.rx.events.SessionTerminationAnswer;
  42. import net.java.slee.resource.diameter.rx.events.SessionTerminationRequest;
  43. import org.apache.log4j.Logger;
  44. import org.jdiameter.api.ApplicationId;
  45. import org.jdiameter.api.AvpSet;
  46. import org.jdiameter.api.Message;
  47. import org.jdiameter.api.Stack;
  48. import org.mobicents.slee.resource.diameter.rx.events.AAAnswerImpl;
  49. import org.mobicents.slee.resource.diameter.rx.events.AARequestImpl;
  50. import org.mobicents.slee.resource.diameter.rx.events.AbortSessionAnswerImpl;
  51. import org.mobicents.slee.resource.diameter.rx.events.AbortSessionRequestImpl;
  52. import org.mobicents.slee.resource.diameter.rx.events.ReAuthAnswerImpl;
  53. import org.mobicents.slee.resource.diameter.rx.events.ReAuthRequestImpl;
  54. import org.mobicents.slee.resource.diameter.rx.events.SessionTerminationAnswerImpl;
  55. import org.mobicents.slee.resource.diameter.rx.events.SessionTerminationRequestImpl;
  56. import org.mobicents.slee.resource.diameter.rx.events.avp.DiameterRxAvpCodes;
  57. /**
  58. * Implementation of {@link RxMessageFactory}.
  59. *
  60. * @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
  61. * @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a>
  62. * @author <a href="mailto:richard.good@smilecoms.com"> Richard Good </a>
  63. */
  64. public class RxMessageFactoryImpl implements RxMessageFactory {
  65. protected Logger logger = Logger.getLogger(RxMessageFactoryImpl.class);
  66. private static final DiameterAvp[] EMPTY_AVP_ARRAY = new DiameterAvp[]{};
  67. protected final static Set<Integer> ids;
  68. static {
  69. final Set<Integer> _ids = new HashSet<Integer>();
  70. //_ids.add(Avp.SESSION_ID);
  71. //_ids.add(Avp.AUTH_APPLICATION_ID);
  72. //_ids.add(Avp.VENDOR_SPECIFIC_APPLICATION_ID);
  73. ids = Collections.unmodifiableSet(_ids);
  74. }
  75. protected DiameterMessageFactory baseFactory = null;
  76. protected String sessionId;
  77. protected Stack stack;
  78. private ApplicationId rxAppId = ApplicationId.createByAuthAppId(DiameterRxAvpCodes.RX_APPLICATION_ID);
  79. public RxMessageFactoryImpl(final DiameterMessageFactory baseFactory, final String sessionId, final Stack stack) {
  80. super();
  81. this.baseFactory = baseFactory;
  82. this.sessionId = sessionId;
  83. this.stack = stack;
  84. }
  85. public void setApplicationId(long vendorId, long applicationId) {
  86. this.rxAppId = ApplicationId.createByAuthAppId(vendorId, applicationId);
  87. }
  88. public ApplicationId getApplicationId() {
  89. return this.rxAppId;
  90. }
  91. /**
  92. * {@inheritDoc}
  93. */
  94. @Override
  95. public AARequest createAARequest() {
  96. final AARequest aar = (AARequest) createDiameterMessage(null,new DiameterAvp[]{},AARequest.commandCode, rxAppId);
  97. if (sessionId != null) {
  98. aar.setSessionId(sessionId);
  99. }
  100. return aar;
  101. }
  102. /**
  103. * {@inheritDoc}
  104. */
  105. @Override
  106. public AARequest createAARequest(String sessionId) {
  107. final AARequest aar = this.createAARequest();
  108. aar.setSessionId(sessionId);
  109. return aar;
  110. }
  111. public AAAnswer createAAAnswer(final AARequest request) {
  112. // Create the answer from the request
  113. final AAAnswerImpl msg = (AAAnswerImpl) createDiameterMessage(request.getHeader(), EMPTY_AVP_ARRAY, 0, rxAppId);
  114. msg.getGenericData().getAvps().removeAvp(DiameterAvpCodes.DESTINATION_HOST);
  115. msg.getGenericData().getAvps().removeAvp(DiameterAvpCodes.DESTINATION_REALM);
  116. msg.getGenericData().getAvps().removeAvp(DiameterAvpCodes.ORIGIN_HOST);
  117. msg.getGenericData().getAvps().removeAvp(DiameterAvpCodes.ORIGIN_REALM);
  118. msg.setSessionId(request.getSessionId());
  119. // Now copy the needed AVPs
  120. final DiameterAvp[] messageAvps = request.getAvps();
  121. if (messageAvps != null) {
  122. for (DiameterAvp a : messageAvps) {
  123. try {
  124. if (ids.contains(a.getCode())) {
  125. msg.addAvp(a);
  126. }
  127. }
  128. catch (Exception e) {
  129. logger.error("Failed to add AVP to answer. Code[" + a.getCode() + "]", e);
  130. }
  131. }
  132. }
  133. return msg;
  134. }
  135. public AbortSessionAnswer createAbortSessionAnswer(AbortSessionRequest request, DiameterAvp[] avps) throws AvpNotAllowedException {
  136. AbortSessionAnswer msg = (AbortSessionAnswer) this.createDiameterMessage(request.getHeader(), avps, Message.ABORT_SESSION_ANSWER, getApplicationId(request));
  137. // Add Session-Id AVP if not present
  138. if (msg.getSessionId() == null) {
  139. String reqSessionId = request.getSessionId();
  140. if (reqSessionId != null) {
  141. msg.setSessionId(reqSessionId);
  142. }
  143. else if (sessionId != null) {
  144. msg.setSessionId(sessionId);
  145. }
  146. }
  147. return msg;
  148. }
  149. public AbortSessionAnswer createAbortSessionAnswer(AbortSessionRequest request) {
  150. try {
  151. return createAbortSessionAnswer(request, new DiameterAvp[0]);
  152. }
  153. catch (AvpNotAllowedException e) {
  154. logger.error("Unexpected failure while trying to create ASA message.", e);
  155. }
  156. return null;
  157. }
  158. public AbortSessionRequest createAbortSessionRequest(DiameterAvp[] avps) throws AvpNotAllowedException {
  159. AbortSessionRequest msg = (AbortSessionRequest) this.createDiameterMessage(null, avps, Message.ABORT_SESSION_REQUEST, rxAppId);
  160. // Add Session-Id AVP if not present
  161. if (msg.getSessionId() == null) {
  162. if (sessionId != null) {
  163. msg.setSessionId(sessionId);
  164. }
  165. }
  166. return msg;
  167. }
  168. public AbortSessionRequest createAbortSessionRequest() {
  169. try {
  170. return createAbortSessionRequest(new DiameterAvp[0]);
  171. }
  172. catch (AvpNotAllowedException e) {
  173. logger.error("Unexpected failure while trying to create ASR message.", e);
  174. }
  175. return null;
  176. }
  177. public ReAuthAnswer createReAuthAnswer(ReAuthRequest request, DiameterAvp[] avps) throws AvpNotAllowedException {
  178. ReAuthAnswer msg = (ReAuthAnswer) this.createDiameterMessage(request.getHeader(), avps, Message.RE_AUTH_ANSWER, getApplicationId(request));
  179. // Add Session-Id AVP if not present
  180. if (msg.getSessionId() == null) {
  181. String reqSessionId = request.getSessionId();
  182. if (reqSessionId != null) {
  183. msg.setSessionId(reqSessionId);
  184. }
  185. else if (sessionId != null) {
  186. msg.setSessionId(sessionId);
  187. }
  188. }
  189. return msg;
  190. }
  191. public ReAuthAnswer createReAuthAnswer(ReAuthRequest request) {
  192. try {
  193. return createReAuthAnswer(request, new DiameterAvp[0]);
  194. }
  195. catch (AvpNotAllowedException e) {
  196. logger.error("Unexpected failure while trying to create RAA message.", e);
  197. }
  198. return null;
  199. }
  200. public ReAuthRequest createReAuthRequest(DiameterAvp[] avps) throws AvpNotAllowedException {
  201. ReAuthRequest msg = (ReAuthRequest) this.createDiameterMessage(null, avps, Message.RE_AUTH_REQUEST, rxAppId);
  202. // Add Session-Id AVP if not present
  203. if (msg.getSessionId() == null) {
  204. if (sessionId != null) {
  205. msg.setSessionId(sessionId);
  206. }
  207. }
  208. return msg;
  209. }
  210. public ReAuthRequest createReAuthRequest() {
  211. try {
  212. return createReAuthRequest(new DiameterAvp[0]);
  213. }
  214. catch (AvpNotAllowedException e) {
  215. logger.error("Unexpected failure while trying to create RAR message.", e);
  216. }
  217. return null;
  218. }
  219. public SessionTerminationAnswer createSessionTerminationAnswer(SessionTerminationRequest request, DiameterAvp[] avps) throws AvpNotAllowedException {
  220. SessionTerminationAnswer msg = (SessionTerminationAnswer) this.createDiameterMessage(request.getHeader(), avps, Message.SESSION_TERMINATION_REQUEST, rxAppId);
  221. // Add Session-Id AVP if not present
  222. if (msg.getSessionId() == null) {
  223. String reqSessionId = request.getSessionId();
  224. if (reqSessionId != null) {
  225. msg.setSessionId(reqSessionId);
  226. }
  227. else if (sessionId != null) {
  228. msg.setSessionId(sessionId);
  229. }
  230. }
  231. return msg;
  232. }
  233. public SessionTerminationAnswer createSessionTerminationAnswer(SessionTerminationRequest request) {
  234. try {
  235. return createSessionTerminationAnswer(request, EMPTY_AVP_ARRAY);
  236. }
  237. catch (AvpNotAllowedException e) {
  238. logger.error("Unexpected failure while trying to create STA message.", e);
  239. }
  240. return null;
  241. }
  242. public SessionTerminationRequest createSessionTerminationRequest(DiameterAvp[] avps) throws AvpNotAllowedException {
  243. SessionTerminationRequest msg = (SessionTerminationRequest) this.createDiameterMessage(null, avps, Message.SESSION_TERMINATION_REQUEST, rxAppId);
  244. // Add Session-Id AVP if not present
  245. if (msg.getSessionId() == null) {
  246. if (sessionId != null) {
  247. msg.setSessionId(sessionId);
  248. }
  249. }
  250. return msg;
  251. }
  252. public SessionTerminationRequest createSessionTerminationRequest() {
  253. try {
  254. return createSessionTerminationRequest(new DiameterAvp[0]);
  255. }
  256. catch (AvpNotAllowedException e) {
  257. logger.error("Unexpected failure while trying to create STR message.", e);
  258. return null;
  259. }
  260. }
  261. protected DiameterMessage createDiameterMessage(DiameterHeader diameterHeader, DiameterAvp[] avps, int _commandCode, ApplicationId appId) throws IllegalArgumentException {
  262. boolean creatingRequest = diameterHeader == null;
  263. Message msg = null;
  264. if (!creatingRequest) {
  265. Message raw = createMessage(diameterHeader, avps, 0, appId);
  266. raw.setRequest(false);
  267. raw.setReTransmitted(false); // just in case. answers never have T flag set
  268. msg = raw;
  269. }
  270. else {
  271. Message raw = createMessage(diameterHeader, avps, _commandCode, appId);
  272. raw.setRequest(true);
  273. msg = raw;
  274. }
  275. int commandCode = creatingRequest ? _commandCode : diameterHeader.getCommandCode();
  276. DiameterMessage diamMessage = null;
  277. switch (commandCode) {
  278. case AARequest.commandCode:
  279. diamMessage = creatingRequest ? new AARequestImpl(msg) : new AAAnswerImpl(msg);
  280. break;
  281. case Message.ABORT_SESSION_REQUEST:
  282. diamMessage = creatingRequest ? new AbortSessionRequestImpl(msg) : new AbortSessionAnswerImpl(msg);
  283. break;
  284. case Message.RE_AUTH_REQUEST:
  285. diamMessage = creatingRequest ? new ReAuthRequestImpl(msg) : new ReAuthAnswerImpl(msg);
  286. break;
  287. case Message.SESSION_TERMINATION_REQUEST:
  288. diamMessage = creatingRequest ? new SessionTerminationRequestImpl(msg) : new SessionTerminationAnswerImpl(msg);
  289. break;
  290. default:
  291. throw new IllegalArgumentException();
  292. }
  293. // Finally, add Origin-Host and Origin-Realm, if not present.
  294. addOriginHostAndRealm(diamMessage);
  295. return diamMessage;
  296. }
  297. /**
  298. * {@inheritDoc}
  299. */
  300. @Override
  301. public DiameterMessageFactory getBaseMessageFactory() {
  302. return this.baseFactory;
  303. }
  304. protected Message createMessage(DiameterHeader header, DiameterAvp[] avps,int _commandCode, ApplicationId appId) throws AvpNotAllowedException {
  305. try {
  306. Message msg = createRawMessage(header, _commandCode, appId);
  307. if(avps != null && avps.length > 0) {
  308. AvpSet set = msg.getAvps();
  309. for (DiameterAvp avp : avps) {
  310. if(appId != null && (avp.getCode() == DiameterAvpCodes.VENDOR_SPECIFIC_APPLICATION_ID || avp.getCode() == DiameterAvpCodes.ACCT_APPLICATION_ID || avp.getCode() == DiameterAvpCodes.AUTH_APPLICATION_ID)) {
  311. continue;
  312. }
  313. addAvp(avp, set);
  314. }
  315. }
  316. return msg;
  317. }
  318. catch (Exception e) {
  319. logger.error("Failure trying to create Diameter message.", e);
  320. }
  321. return null;
  322. }
  323. protected Message createRawMessage(DiameterHeader header, int _commandCode, ApplicationId appId) {
  324. int commandCode = 0;
  325. long endToEndId = 0;
  326. long hopByHopId = 0;
  327. boolean isRequest = true;
  328. boolean isProxiable = true;
  329. boolean isError = false;
  330. boolean isPotentiallyRetransmitted = false;
  331. if (header != null) {
  332. commandCode = header.getCommandCode();
  333. endToEndId = header.getEndToEndId();
  334. hopByHopId = header.getHopByHopId();
  335. isRequest = header.isRequest();
  336. isProxiable = header.isProxiable();
  337. isError = header.isError();
  338. isPotentiallyRetransmitted = header.isPotentiallyRetransmitted();
  339. }
  340. else {
  341. commandCode = _commandCode;
  342. }
  343. try {
  344. Message msg = stack.getSessionFactory().getNewRawSession().createMessage(commandCode, appId != null ? appId : rxAppId, hopByHopId, endToEndId);
  345. // Set the message flags from header (or default)
  346. msg.setRequest(isRequest);
  347. msg.setProxiable(isProxiable);
  348. msg.setError(isError);
  349. msg.setReTransmitted(isRequest && isPotentiallyRetransmitted);
  350. return msg;
  351. }
  352. catch (Exception e) {
  353. logger.error( "Failure while trying to create raw message.", e );
  354. }
  355. return null;
  356. }
  357. protected void addAvp(DiameterAvp avp, AvpSet set) {
  358. if (avp instanceof GroupedAvp) {
  359. AvpSet avpSet = set.addGroupedAvp(avp.getCode(), avp.getVendorId(), avp.getMandatoryRule() != DiameterAvp.FLAG_RULE_MUSTNOT, avp.getProtectedRule() == DiameterAvp.FLAG_RULE_MUST);
  360. DiameterAvp[] groupedAVPs = ((GroupedAvp) avp).getExtensionAvps();
  361. for (DiameterAvp avpFromGroup : groupedAVPs) {
  362. addAvp(avpFromGroup, avpSet);
  363. }
  364. }
  365. else if (avp != null) {
  366. set.addAvp(avp.getCode(), avp.byteArrayValue(), avp.getVendorId(), avp.getMandatoryRule() != DiameterAvp.FLAG_RULE_MUSTNOT, avp.getProtectedRule() == DiameterAvp.FLAG_RULE_MUST);
  367. }
  368. }
  369. /**
  370. *
  371. */
  372. public void clean() {
  373. }
  374. /* (non-Javadoc)
  375. * @see net.java.slee.resource.diameter.base.DiameterMessageFactory#createMessage(net.java.slee.resource.diameter.base.events.DiameterHeader, net.java.slee.resource.diameter.base.events.avp.DiameterAvp[])
  376. */
  377. public DiameterMessage createMessage(DiameterHeader header, DiameterAvp[] avps) throws AvpNotAllowedException {
  378. return this.createDiameterMessage(header, avps, header.getCommandCode(), rxAppId);
  379. }
  380. private void addOriginHostAndRealm(DiameterMessage msg) {
  381. if(!msg.hasOriginHost()) {
  382. msg.setOriginHost(new DiameterIdentity(stack.getMetaData().getLocalPeer().getUri().getFQDN().toString()));
  383. }
  384. if(!msg.hasOriginRealm()) {
  385. msg.setOriginRealm(new DiameterIdentity(stack.getMetaData().getLocalPeer().getRealmName()));
  386. }
  387. }
  388. private ApplicationId getApplicationId(DiameterMessage msg) {
  389. ApplicationId applicationId = getApplicationId(msg.getAvps());
  390. if (applicationId == null) {
  391. applicationId = rxAppId;
  392. }
  393. return applicationId;
  394. }
  395. private ApplicationId getApplicationId(DiameterAvp[] avps) {
  396. ApplicationId applicationId = null;
  397. long vendorId = 0L;
  398. // Try to get Application-Id from Message AVPs
  399. if (avps != null) {
  400. for (DiameterAvp avp : avps) {
  401. if(avp.getCode() == DiameterAvpCodes.VENDOR_ID) {
  402. vendorId = avp.intValue();
  403. }
  404. if(avp.getCode() == DiameterAvpCodes.VENDOR_SPECIFIC_APPLICATION_ID) {
  405. applicationId = getApplicationId(((GroupedAvp)avp).getExtensionAvps());
  406. break;
  407. }
  408. if (avp.getCode() == DiameterAvpCodes.ACCT_APPLICATION_ID) {
  409. applicationId = ApplicationId.createByAccAppId(vendorId, avp.intValue());
  410. break;
  411. }
  412. else if (avp.getCode() == DiameterAvpCodes.AUTH_APPLICATION_ID) {
  413. applicationId = ApplicationId.createByAuthAppId(vendorId, avp.intValue());
  414. break;
  415. }
  416. }
  417. }
  418. return applicationId;
  419. }
  420. }