PageRenderTime 60ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/servers/jain-slee/resources/diameter-ro/ra/src/main/java/org/mobicents/slee/resource/diameter/ro/DiameterRoResourceAdaptor.java

http://mobicents.googlecode.com/
Java | 1206 lines | 730 code | 211 blank | 265 comment | 93 complexity | 39663ba5b64f4cb37b3f6ee5f4727f40 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.ro;
  23. import java.io.IOException;
  24. import java.util.ArrayList;
  25. import java.util.List;
  26. import javax.management.ObjectName;
  27. import javax.naming.OperationNotSupportedException;
  28. import javax.slee.Address;
  29. import javax.slee.facilities.EventLookupFacility;
  30. import javax.slee.facilities.Tracer;
  31. import javax.slee.resource.ActivityFlags;
  32. import javax.slee.resource.ActivityHandle;
  33. import javax.slee.resource.ConfigProperties;
  34. import javax.slee.resource.EventFlags;
  35. import javax.slee.resource.FailureReason;
  36. import javax.slee.resource.FireableEventType;
  37. import javax.slee.resource.InvalidConfigurationException;
  38. import javax.slee.resource.Marshaler;
  39. import javax.slee.resource.ReceivableService;
  40. import javax.slee.resource.ResourceAdaptor;
  41. import javax.slee.resource.ResourceAdaptorContext;
  42. import javax.slee.resource.SleeEndpoint;
  43. import net.java.slee.resource.diameter.Validator;
  44. import net.java.slee.resource.diameter.base.CreateActivityException;
  45. import net.java.slee.resource.diameter.base.DiameterActivity;
  46. import net.java.slee.resource.diameter.base.DiameterAvpFactory;
  47. import net.java.slee.resource.diameter.base.DiameterException;
  48. import net.java.slee.resource.diameter.base.events.AbortSessionAnswer;
  49. import net.java.slee.resource.diameter.base.events.AccountingAnswer;
  50. import net.java.slee.resource.diameter.base.events.DiameterMessage;
  51. import net.java.slee.resource.diameter.base.events.ReAuthAnswer;
  52. import net.java.slee.resource.diameter.base.events.SessionTerminationAnswer;
  53. import net.java.slee.resource.diameter.base.events.avp.DiameterIdentity;
  54. import net.java.slee.resource.diameter.ro.RoAvpFactory;
  55. import net.java.slee.resource.diameter.ro.RoClientSessionActivity;
  56. import net.java.slee.resource.diameter.ro.RoMessageFactory;
  57. import net.java.slee.resource.diameter.ro.RoProvider;
  58. import net.java.slee.resource.diameter.ro.RoServerSessionActivity;
  59. import net.java.slee.resource.diameter.ro.events.RoCreditControlAnswer;
  60. import net.java.slee.resource.diameter.ro.events.RoCreditControlRequest;
  61. import org.jboss.mx.util.MBeanServerLocator;
  62. import org.jdiameter.api.Answer;
  63. import org.jdiameter.api.ApplicationId;
  64. import org.jdiameter.api.Avp;
  65. import org.jdiameter.api.AvpDataException;
  66. import org.jdiameter.api.AvpSet;
  67. import org.jdiameter.api.Message;
  68. import org.jdiameter.api.Peer;
  69. import org.jdiameter.api.PeerTable;
  70. import org.jdiameter.api.Request;
  71. import org.jdiameter.api.Session;
  72. import org.jdiameter.api.SessionFactory;
  73. import org.jdiameter.api.Stack;
  74. import org.jdiameter.api.ro.ClientRoSession;
  75. import org.jdiameter.api.ro.ServerRoSession;
  76. import org.jdiameter.client.api.ISessionFactory;
  77. import org.jdiameter.server.impl.app.ro.ServerRoSessionImpl;
  78. import org.mobicents.diameter.stack.DiameterListener;
  79. import org.mobicents.diameter.stack.DiameterStackMultiplexerMBean;
  80. import org.mobicents.slee.resource.cluster.FaultTolerantResourceAdaptorContext;
  81. import org.mobicents.slee.resource.diameter.AbstractClusteredDiameterActivityManagement;
  82. import org.mobicents.slee.resource.diameter.DiameterActivityManagement;
  83. import org.mobicents.slee.resource.diameter.LocalDiameterActivityManagement;
  84. import org.mobicents.slee.resource.diameter.ValidatorImpl;
  85. import org.mobicents.slee.resource.diameter.base.DiameterActivityHandle;
  86. import org.mobicents.slee.resource.diameter.base.DiameterActivityImpl;
  87. import org.mobicents.slee.resource.diameter.base.DiameterAvpFactoryImpl;
  88. import org.mobicents.slee.resource.diameter.base.DiameterBaseMarshaler;
  89. import org.mobicents.slee.resource.diameter.base.DiameterMessageFactoryImpl;
  90. import org.mobicents.slee.resource.diameter.base.EventIDFilter;
  91. import org.mobicents.slee.resource.diameter.base.events.AbortSessionAnswerImpl;
  92. import org.mobicents.slee.resource.diameter.base.events.AbortSessionRequestImpl;
  93. import org.mobicents.slee.resource.diameter.base.events.AccountingAnswerImpl;
  94. import org.mobicents.slee.resource.diameter.base.events.AccountingRequestImpl;
  95. import org.mobicents.slee.resource.diameter.base.events.DiameterMessageImpl;
  96. import org.mobicents.slee.resource.diameter.base.events.ErrorAnswerImpl;
  97. import org.mobicents.slee.resource.diameter.base.events.ExtensionDiameterMessageImpl;
  98. import org.mobicents.slee.resource.diameter.base.events.ReAuthAnswerImpl;
  99. import org.mobicents.slee.resource.diameter.base.events.ReAuthRequestImpl;
  100. import org.mobicents.slee.resource.diameter.base.events.SessionTerminationAnswerImpl;
  101. import org.mobicents.slee.resource.diameter.base.events.SessionTerminationRequestImpl;
  102. import org.mobicents.slee.resource.diameter.base.handlers.DiameterRAInterface;
  103. import org.mobicents.slee.resource.diameter.ro.events.RoCreditControlAnswerImpl;
  104. import org.mobicents.slee.resource.diameter.ro.events.RoCreditControlRequestImpl;
  105. import org.mobicents.slee.resource.diameter.ro.handlers.RoSessionFactory;
  106. /**
  107. * Diameter Ro Resource Adaptor
  108. *
  109. * @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
  110. */
  111. public class DiameterRoResourceAdaptor implements ResourceAdaptor, DiameterListener, DiameterRAInterface ,org.mobicents.slee.resource.cluster.FaultTolerantResourceAdaptor<String, DiameterActivity> {
  112. private static final long serialVersionUID = 1L;
  113. // Config Properties Names ---------------------------------------------
  114. private static final String AUTH_APPLICATION_IDS = "authApplicationIds";
  115. // Config Properties Values --------------------------------------------
  116. private List<ApplicationId> authApplicationIds;
  117. /**
  118. * caches the eventIDs, avoiding lookup in container
  119. */
  120. public final EventIDCache eventIdCache = new EventIDCache();
  121. /**
  122. * tells the RA if an event with a specified ID should be filtered or not
  123. */
  124. private final EventIDFilter eventIDFilter = new EventIDFilter();
  125. /**
  126. * The ResourceAdaptorContext interface is implemented by the SLEE. It provides the Resource
  127. * Adaptor with the required capabilities in the SLEE to execute its work. The ResourceAdaptorCon-
  128. * text object holds references to a number of objects that are of interest to many Resource Adaptors. A
  129. * resource adaptor object is provided with a ResourceAdaptorContext object when the setResour-
  130. * ceAdaptorContext method of the ResourceAdaptor interface is invoked on the resource adaptor
  131. * object.
  132. */
  133. private ResourceAdaptorContext raContext;
  134. /**
  135. * FT/HA version of RA context.
  136. */
  137. private FaultTolerantResourceAdaptorContext<String, DiameterActivity> ftRAContext;
  138. /**
  139. * The SLEE endpoint defines the contract between the SLEE and the resource
  140. * adaptor that enables the resource adaptor to deliver events
  141. * asynchronously to SLEE endpoints residing in the SLEE. This contract
  142. * serves as a generic contract that allows a wide range of resources to be
  143. * plugged into a SLEE environment via the resource adaptor architecture.
  144. * For further information see JSLEE v1.1 Specification Page 307 The
  145. * sleeEndpoint will be initialized in entityCreated() method.
  146. */
  147. private transient SleeEndpoint sleeEndpoint = null;
  148. /**
  149. * A tracer is represented in the SLEE by the Tracer interface. Notification sources access the Tracer Facil-
  150. * ity through a Tracer object that implements the Tracer interface. A Tracer object can be obtained by
  151. * SBBs via the SbbContext interface, by resource adaptor entities via the ResourceAdaptorContext
  152. * interface, and by profiles via the ProfileContext interface.
  153. */
  154. private Tracer tracer;
  155. protected DiameterBaseMarshaler marshaler = new DiameterBaseMarshaler();
  156. // Diameter Specific Properties ----------------------------------------
  157. private Stack stack;
  158. private ObjectName diameterMultiplexerObjectName = null;
  159. private DiameterStackMultiplexerMBean diameterMux = null;
  160. // Default Failure Handling
  161. protected int defaultDirectDebitingFailureHandling = 0;
  162. protected int defaultCreditControlFailureHandling = 0;
  163. // Validity and TxTimer values (in seconds)
  164. protected long defaultValidityTime = 30;
  165. protected long defaultTxTimerValue = 10;
  166. protected long activityRemoveDelay = 30000;
  167. // Base Factories
  168. private DiameterAvpFactory baseAvpFactory = null;
  169. private DiameterMessageFactoryImpl baseMessageFactory;
  170. private SessionFactory sessionFactory = null;
  171. // Ro RA Factories
  172. protected RoSessionFactory ccaSessionFactory = null;
  173. protected RoAvpFactory roAvpFactory = null;
  174. protected RoMessageFactory roMessageFactory;
  175. /**
  176. * the EventLookupFacility is used to look up the event id of incoming
  177. * events
  178. */
  179. private transient EventLookupFacility eventLookup = null;
  180. /**
  181. * The list of activities stored in this resource adaptor. If this resource
  182. * adaptor were a distributed and highly available solution, this storage
  183. * were one of the candidates for distribution.
  184. */
  185. //private transient ConcurrentHashMap<ActivityHandle, DiameterActivity> activities = null;
  186. private transient DiameterActivityManagement activities = null;
  187. /**
  188. * A link to the DiameterProvider which then will be exposed to Sbbs
  189. */
  190. protected transient RoProviderImpl raProvider = null;
  191. /**
  192. * for all events we are interested in knowing when the event failed to be processed
  193. */
  194. private static final int EVENT_FLAGS = getEventFlags();
  195. private static int getEventFlags() {
  196. int eventFlags = EventFlags.REQUEST_EVENT_UNREFERENCED_CALLBACK;
  197. eventFlags = EventFlags.setRequestProcessingFailedCallback(eventFlags);
  198. eventFlags = EventFlags.setRequestProcessingSuccessfulCallback(eventFlags);
  199. return eventFlags;
  200. }
  201. private static final int DEFAULT_ACTIVITY_FLAGS = ActivityFlags.REQUEST_ENDED_CALLBACK;
  202. private static final int MARSHALABLE_ACTIVITY_FLAGS = ActivityFlags.setSleeMayMarshal(DEFAULT_ACTIVITY_FLAGS);
  203. public DiameterRoResourceAdaptor() {
  204. // TODO: Initialize any default values.
  205. }
  206. // Lifecycle methods ---------------------------------------------------
  207. public void setResourceAdaptorContext(ResourceAdaptorContext context) {
  208. this.raContext = context;
  209. this.tracer = context.getTracer("DiameterRoResourceAdaptor");
  210. this.sleeEndpoint = context.getSleeEndpoint();
  211. this.eventLookup = context.getEventLookupFacility();
  212. this.raProvider = new RoProviderImpl(this);
  213. }
  214. public void unsetResourceAdaptorContext() {
  215. this.raContext = null;
  216. this.tracer = null;
  217. this.sleeEndpoint = null;
  218. this.eventLookup = null;
  219. this.raProvider = null;
  220. }
  221. // FT Lifecycle methods ------------------------------------------------
  222. /*
  223. * (non-Javadoc)
  224. * @see org.mobicents.slee.resource.cluster.FaultTolerantResourceAdaptor#setFaultTolerantResourceAdaptorContext
  225. * (org.mobicents.slee.resource.cluster.FaultTolerantResourceAdaptorContext)
  226. */
  227. public void setFaultTolerantResourceAdaptorContext(FaultTolerantResourceAdaptorContext<String, DiameterActivity> ctx) {
  228. this.ftRAContext = ctx;
  229. }
  230. /*
  231. * (non-Javadoc)
  232. * @see org.mobicents.slee.resource.cluster.FaultTolerantResourceAdaptor#unsetFaultTolerantResourceAdaptorContext()
  233. */
  234. public void unsetFaultTolerantResourceAdaptorContext() {
  235. this.ftRAContext = null;
  236. //clear this.activities ??
  237. }
  238. // FT methods ----------------------------------------------------------
  239. /*
  240. * (non-Javadoc)
  241. * @see org.mobicents.slee.resource.cluster.FaultTolerantResourceAdaptor#dataRemoved(java.io.Serializable)
  242. */
  243. public void dataRemoved(String arg0) {
  244. this.activities.remove(getActivityHandle(arg0));
  245. }
  246. /* (non-Javadoc)
  247. * @see org.mobicents.slee.resource.cluster.FaultTolerantResourceAdaptor#failOver(java.io.Serializable)
  248. */
  249. public void failOver(String arg0) {
  250. throw new UnsupportedOperationException();
  251. }
  252. @Override
  253. public ApplicationId[] getSupportedApplications() {
  254. //FIXME: fill this , Alex what should go here?
  255. return null;
  256. }
  257. public void raActive() {
  258. if(tracer.isFineEnabled()) {
  259. tracer.fine("Diameter Ro RA :: raActive.");
  260. }
  261. try {
  262. if(tracer.isInfoEnabled()) {
  263. tracer.info("Activating Diameter Ro RA Entity");
  264. }
  265. this.diameterMultiplexerObjectName = new ObjectName("diameter.mobicents:service=DiameterStackMultiplexer");
  266. Object object = MBeanServerLocator.locateJBoss().invoke(this.diameterMultiplexerObjectName, "getMultiplexerMBean", new Object[]{}, new String[]{});
  267. if(object instanceof DiameterStackMultiplexerMBean) {
  268. this.diameterMux = (DiameterStackMultiplexerMBean) object;
  269. }
  270. //this.activities = new ConcurrentHashMap<ActivityHandle, DiameterActivity>();
  271. // Initialize the protocol stack
  272. initStack();
  273. //Initialize activities mgmt
  274. initActivitiesMgmt();
  275. // Initialize factories
  276. this.baseAvpFactory = new DiameterAvpFactoryImpl();
  277. this.baseMessageFactory = new DiameterMessageFactoryImpl(stack);
  278. this.roAvpFactory = new RoAvpFactoryImpl(baseAvpFactory);
  279. this.roMessageFactory = new RoMessageFactoryImpl(baseMessageFactory, null, stack);
  280. // Set the first configured Application-Id as default for message factory
  281. ApplicationId firstAppId = authApplicationIds.get(0);
  282. ((RoMessageFactoryImpl)this.roMessageFactory).setApplicationId(firstAppId.getVendorId(), firstAppId.getAuthAppId());
  283. this.sessionFactory = this.stack.getSessionFactory();
  284. this.ccaSessionFactory = new RoSessionFactory( this, sessionFactory,defaultDirectDebitingFailureHandling, defaultCreditControlFailureHandling, defaultValidityTime, defaultTxTimerValue);
  285. // Register CCA App Session Factories
  286. ((ISessionFactory) sessionFactory).registerAppFacory(ServerRoSession.class, this.ccaSessionFactory);
  287. ((ISessionFactory) sessionFactory).registerAppFacory(ClientRoSession.class, this.ccaSessionFactory);
  288. }
  289. catch (Exception e) {
  290. tracer.severe("Error Activating Diameter Ro RA Entity", e);
  291. }
  292. }
  293. public void raStopping() {
  294. if(tracer.isFineEnabled()) {
  295. tracer.fine("Diameter Ro RA :: raStopping.");
  296. }
  297. try {
  298. diameterMux.unregisterListener(this);
  299. }
  300. catch (Exception e) {
  301. tracer.severe("Failed to unregister Ro RA from Diameter Mux.", e);
  302. }
  303. //synchronized (this.activities) {
  304. // for (ActivityHandle activityHandle : activities.keySet()) {
  305. // try {
  306. // if(tracer.isInfoEnabled()) {
  307. // tracer.info("Ending activity [" + activityHandle + "]");
  308. // }
  309. //
  310. // activities.get(activityHandle).endActivity();
  311. // }
  312. // catch (Exception e) {
  313. // tracer.severe("Error Deactivating Activity", e);
  314. // }
  315. // }
  316. //}
  317. if(tracer.isInfoEnabled()) {
  318. tracer.info("Diameter Ro RA :: raStopping completed.");
  319. }
  320. }
  321. public void raInactive() {
  322. if(tracer.isFineEnabled()) {
  323. tracer.fine("Diameter Ro RA :: raInactive.");
  324. }
  325. //synchronized (this.activities) {
  326. // activities.clear();
  327. //}
  328. activities = null;
  329. if(tracer.isInfoEnabled()) {
  330. tracer.info("Diameter Ro RA :: raInactive completed.");
  331. }
  332. }
  333. public void raConfigure(ConfigProperties properties) {
  334. parseApplicationIds((String) properties.getProperty(AUTH_APPLICATION_IDS).getValue());
  335. }
  336. private void parseApplicationIds(String appIdsStr) {
  337. if(appIdsStr != null) {
  338. appIdsStr = appIdsStr.replaceAll(" ", "");
  339. String[] appIdsStrings = appIdsStr.split(",");
  340. authApplicationIds = new ArrayList<ApplicationId>(appIdsStrings.length);
  341. for(String appId : appIdsStrings) {
  342. String[] vendorAndAppId = appId.split(":");
  343. authApplicationIds.add(ApplicationId.createByAuthAppId(Long.valueOf(vendorAndAppId[0]), Long.valueOf(vendorAndAppId[1])));
  344. }
  345. }
  346. }
  347. public void raUnconfigure() {
  348. // Clean up!
  349. this.activities = null;
  350. this.raContext = null;
  351. this.eventLookup = null;
  352. this.raProvider = null;
  353. this.sleeEndpoint = null;
  354. this.stack = null;
  355. }
  356. // Configuration management methods ------------------------------------
  357. public void raVerifyConfiguration(ConfigProperties properties) throws InvalidConfigurationException {
  358. // TODO Auto-generated method stub
  359. }
  360. public void raConfigurationUpdate(ConfigProperties properties) {
  361. // this ra does not support config update while entity is active
  362. }
  363. // Interface access methods --------------------------------------------
  364. public Object getResourceAdaptorInterface(String className) {
  365. // this ra implements a single ra type
  366. return raProvider;
  367. }
  368. /*
  369. * (non-Javadoc)
  370. * @see javax.slee.resource.ResourceAdaptor#getMarshaler()
  371. */
  372. public Marshaler getMarshaler() {
  373. return marshaler;
  374. }
  375. // Event filtering methods ---------------------------------------------
  376. public void serviceActive(ReceivableService serviceInfo) {
  377. eventIDFilter.serviceActive(serviceInfo);
  378. }
  379. public void serviceStopping(ReceivableService serviceInfo) {
  380. eventIDFilter.serviceStopping(serviceInfo);
  381. }
  382. public void serviceInactive(ReceivableService serviceInfo) {
  383. eventIDFilter.serviceInactive(serviceInfo);
  384. }
  385. // Mandatory callback methods ------------------------------------------
  386. public void queryLiveness(ActivityHandle handle) {
  387. tracer.info("Diameter Ro RA :: queryLiveness :: handle[" + handle + "].");
  388. DiameterActivityImpl activity = (DiameterActivityImpl) activities.get((DiameterActivityHandle)handle);
  389. if (activity != null && !activity.isValid()) {
  390. try {
  391. sleeEndpoint.endActivity(handle);
  392. }
  393. catch (Exception e) {
  394. tracer.severe("Failure ending non-live activity.", e);
  395. }
  396. }
  397. }
  398. public Object getActivity(ActivityHandle handle) {
  399. if(tracer.isFineEnabled()) {
  400. tracer.fine("Diameter Ro RA :: getActivity :: handle[" + handle + "].");
  401. }
  402. return this.activities.get((DiameterActivityHandle)handle);
  403. }
  404. public ActivityHandle getActivityHandle(Object activity) {
  405. if(tracer.isFineEnabled()) {
  406. tracer.fine("Diameter Ro RA :: getActivityHandle :: activity[" + activity + "].");
  407. }
  408. if (!(activity instanceof DiameterActivity)) {
  409. return null;
  410. }
  411. DiameterActivityImpl inActivity = (DiameterActivityImpl) activity;
  412. //for (Map.Entry<ActivityHandle, DiameterActivity> activityInfo : this.activities.entrySet()) {
  413. // Object curActivity = activityInfo.getValue();
  414. //
  415. // if (curActivity.equals(inActivity)) {
  416. // return activityInfo.getKey();
  417. // }
  418. //}
  419. //
  420. //return null;
  421. return inActivity.getActivityHandle();
  422. }
  423. public void administrativeRemove(ActivityHandle handle) {
  424. // TODO what to do here?
  425. }
  426. // Optional callback methods -------------------------------------------
  427. public void eventProcessingFailed(ActivityHandle handle, FireableEventType eventType, Object event, Address address, ReceivableService service, int flags, FailureReason reason) {
  428. if(tracer.isFineEnabled()) {
  429. tracer.fine("Diameter Ro RA :: eventProcessingFailed :: handle[" + handle + "], eventType[" + eventType + "], event[" + event + "], address[" + address + "], flags[" + flags + "], reason[" + reason + "].");
  430. }
  431. if(!(handle instanceof DiameterActivityHandle)) {
  432. return;
  433. }
  434. processAfterEventDelivery(handle, eventType, event, address, service, flags);
  435. }
  436. public void eventProcessingSuccessful(ActivityHandle handle, FireableEventType eventType, Object event, Address address, ReceivableService service, int flags) {
  437. if(tracer.isFineEnabled()) {
  438. tracer.fine("Diameter Ro RA :: eventProcessingSuccessful :: handle[" + handle + "], eventType[" + eventType + "], event[" + event + "], address[" + address + "], flags[" + flags + "].");
  439. }
  440. if(!(handle instanceof DiameterActivityHandle)) {
  441. return;
  442. }
  443. processAfterEventDelivery(handle, eventType, event, address, service, flags);
  444. }
  445. public void eventUnreferenced(ActivityHandle handle, FireableEventType eventType, Object event, Address address, ReceivableService service, int flags) {
  446. if(tracer.isFineEnabled()) {
  447. tracer.fine("Diameter Ro RA :: eventUnreferenced :: handle[" + handle + "], eventType[" + eventType + "], event[" + event + "], address[" + address + "], service[" + service + "], flags[" + flags + "].");
  448. }
  449. if(!(handle instanceof DiameterActivityHandle)) {
  450. return;
  451. }
  452. processAfterEventDelivery(handle, eventType, event, address, service, flags);
  453. }
  454. private void processAfterEventDelivery(ActivityHandle handle, FireableEventType eventType, Object event, Address address, ReceivableService service, int flags) {
  455. DiameterActivityImpl activity = (DiameterActivityImpl) getActivity(handle);
  456. if (activity != null) {
  457. synchronized (activity) {
  458. if (activity.isTerminateAfterProcessing()) {
  459. activity.endActivity();
  460. }
  461. }
  462. }
  463. }
  464. public void activityEnded(ActivityHandle handle) {
  465. if(tracer.isInfoEnabled()) {
  466. tracer.info("Diameter Ro RA :: activityEnded :: handle[" + handle + "].");
  467. }
  468. if(this.activities != null) {
  469. synchronized (this.activities) {
  470. this.activities.remove((DiameterActivityHandle)handle);
  471. }
  472. }
  473. }
  474. public void activityUnreferenced(ActivityHandle handle) {
  475. if(tracer.isFineEnabled()) {
  476. tracer.fine("Diameter Ro RA :: activityUnreferenced :: handle[" + handle + "].");
  477. }
  478. //this.activityEnded(handle);
  479. if(handle instanceof DiameterActivityHandle) {
  480. this.endActivity((DiameterActivityHandle) handle);
  481. }
  482. }
  483. // Event and Activities management -------------------------------------
  484. public boolean fireEvent(Object event, ActivityHandle handle, FireableEventType eventID, Address address, boolean useFiltering, boolean transacted) {
  485. if (useFiltering && eventIDFilter.filterEvent(eventID)) {
  486. if (tracer.isFineEnabled()) {
  487. tracer.fine("Event " + eventID + " filtered");
  488. }
  489. }
  490. else if (eventID == null) {
  491. tracer.severe("Event ID for " + eventID + " is unknown, unable to fire.");
  492. }
  493. else {
  494. if (tracer.isFineEnabled()) {
  495. tracer.fine("Firing event " + event + " on handle " + handle);
  496. }
  497. try {
  498. Object o = getActivity(handle);
  499. if(o == null) {
  500. throw new IllegalStateException("No activity for handle: "+handle);
  501. }
  502. if(o instanceof RoServerSessionActivityImpl && event instanceof RoCreditControlRequest) {
  503. ((RoServerSessionActivityImpl)o).fetchCurrentState((RoCreditControlRequest)event);
  504. }
  505. this.raContext.getSleeEndpoint().fireEvent(handle, eventID, event, address, null, EVENT_FLAGS);
  506. return true;
  507. }
  508. catch (Exception e) {
  509. tracer.severe("Error firing event.", e);
  510. }
  511. }
  512. return false;
  513. }
  514. /*
  515. * (non-Javadoc)
  516. * @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#fireEvent(java.lang.String, org.jdiameter.api.Request, org.jdiameter.api.Answer)
  517. */
  518. public void fireEvent(String sessionId, Message message) {
  519. DiameterMessage event = (DiameterMessage) createEvent(message);
  520. FireableEventType eventId = eventIdCache.getEventId(eventLookup, message);
  521. this.fireEvent(event, getActivityHandle(sessionId), eventId, null, true, message.isRequest());
  522. }
  523. /**
  524. * {@inheritDoc}
  525. */
  526. @Override
  527. public void endActivity(DiameterActivityHandle arg0) {
  528. this.sleeEndpoint.endActivity(arg0);
  529. }
  530. /**
  531. * {@inheritDoc}
  532. */
  533. @Override
  534. public void startActivityRemoveTimer(DiameterActivityHandle handle) {
  535. this.activities.startActivityRemoveTimer(handle);
  536. }
  537. /**
  538. * {@inheritDoc}
  539. */
  540. @Override
  541. public void stopActivityRemoveTimer(DiameterActivityHandle handle) {
  542. this.activities.stopActivityRemoveTimer(handle);
  543. }
  544. /**
  545. * {@inheritDoc}
  546. */
  547. @Override
  548. public void update(DiameterActivityHandle arg0, DiameterActivity arg1) {
  549. this.activities.update(arg0, arg1);
  550. }
  551. /**
  552. * Create Event object from a JDiameter message (request or answer)
  553. *
  554. * @return a DiameterMessage object wrapping the request/answer
  555. * @throws OperationNotSupportedException
  556. */
  557. private DiameterMessage createEvent(Message message) {
  558. if (message == null) {
  559. throw new NullPointerException("Message argument cannot be null while creating event.");
  560. }
  561. int commandCode = message.getCommandCode();
  562. if (message.isError()) {
  563. return new ErrorAnswerImpl(message);
  564. }
  565. boolean isRequest = message.isRequest();
  566. switch (commandCode) {
  567. case RoCreditControlRequest.commandCode: // CCR/CCA
  568. return isRequest ? new RoCreditControlRequestImpl(message) : new RoCreditControlAnswerImpl(message);
  569. case AbortSessionAnswer.commandCode: // ASR/ASA
  570. return isRequest ? new AbortSessionRequestImpl(message) : new AbortSessionAnswerImpl(message);
  571. case SessionTerminationAnswer.commandCode: // STR/STA
  572. return isRequest ? new SessionTerminationRequestImpl(message) : new SessionTerminationAnswerImpl(message);
  573. case ReAuthAnswer.commandCode: // RAR/RAA
  574. return isRequest ? new ReAuthRequestImpl(message) : new ReAuthAnswerImpl(message);
  575. case AccountingAnswer.commandCode: // ACR/ACA
  576. return isRequest ? new AccountingRequestImpl(message) : new AccountingAnswerImpl(message);
  577. default:
  578. return new ExtensionDiameterMessageImpl(message);
  579. }
  580. }
  581. // Session Management --------------------------------------------------
  582. /**
  583. * Method for performing tasks when activity is created, such as informing SLEE about it and storing into internal map.
  584. *
  585. * @param ac the activity that has been created
  586. */
  587. private void addActivity(DiameterActivity ac, boolean suspended) {
  588. try {
  589. // Inform SLEE that Activity Started
  590. DiameterActivityImpl activity = (DiameterActivityImpl) ac;
  591. if (suspended) {
  592. sleeEndpoint.startActivitySuspended(activity.getActivityHandle(), activity, MARSHALABLE_ACTIVITY_FLAGS);
  593. }
  594. else {
  595. sleeEndpoint.startActivity(activity.getActivityHandle(), activity, MARSHALABLE_ACTIVITY_FLAGS);
  596. }
  597. // Set the listener
  598. activity.setSessionListener(this);
  599. // Put it into our activities map
  600. activities.put(activity.getActivityHandle(), activity);
  601. if(tracer.isInfoEnabled()) {
  602. tracer.info("Activity started [" + activity.getActivityHandle() + "]");
  603. }
  604. }
  605. catch (Exception e) {
  606. tracer.severe("Error creating activity", e);
  607. throw new RuntimeException("Error creating activity", e);
  608. }
  609. }
  610. // Private Methods -----------------------------------------------------
  611. /**
  612. * Initializes the RA Diameter Stack.
  613. *
  614. * @throws Exception
  615. */
  616. private synchronized void initStack() throws Exception {
  617. // Register in the Mux as an app listener.
  618. this.diameterMux.registerListener(this, (ApplicationId[]) authApplicationIds.toArray(new ApplicationId[authApplicationIds.size()]));
  619. // Get the stack (should not mess with)
  620. this.stack = this.diameterMux.getStack();
  621. if(tracer.isInfoEnabled()) {
  622. tracer.info("Diameter Ro RA :: Successfully initialized stack.");
  623. }
  624. }
  625. private void initActivitiesMgmt() {
  626. final DiameterRAInterface lst = this;
  627. if (this.ftRAContext.isLocal()) {
  628. // local mgmt;
  629. if(tracer.isInfoEnabled()) {
  630. tracer.info(raContext.getEntityName() + " -- running in LOCAL mode.");
  631. }
  632. this.activities = new LocalDiameterActivityManagement(this.raContext, activityRemoveDelay);
  633. }
  634. else {
  635. if(tracer.isInfoEnabled()) {
  636. tracer.info(raContext.getEntityName() + " -- running in CLUSTER mode.");
  637. }
  638. final org.mobicents.slee.resource.cluster.ReplicatedData<String, DiameterActivity> clusteredData = this.ftRAContext.getReplicateData(true);
  639. // get special one
  640. this.activities = new AbstractClusteredDiameterActivityManagement(this.ftRAContext, activityRemoveDelay,this.raContext.getTracer(""), stack, this.raContext.getSleeTransactionManager(), clusteredData) {
  641. @Override
  642. protected void performBeforeReturn(DiameterActivityImpl activity) {
  643. // do all the dirty work;
  644. try {
  645. Session session = null;
  646. if (activity.getClass().equals(DiameterActivityImpl.class)) {
  647. // check as first. since it requires session recreation.
  648. // JIC: is this required?
  649. session = this.diameterStack.getSessionFactory().getNewSession(activity.getSessionId());
  650. performBeforeReturnOnBase(activity, session);
  651. return;
  652. }
  653. else if (activity instanceof RoClientSessionActivity) {
  654. RoClientSessionActivityImpl acc = (RoClientSessionActivityImpl) activity;
  655. ClientRoSession appSession = this.diameterStack.getSession(activity.getSessionId(), ClientRoSession.class);
  656. session = appSession.getSessions().get(0);
  657. performBeforeReturnOnBase(activity, session);
  658. performBeforeReturnRo(acc, session);
  659. performBeforeReturnCC(acc);
  660. acc.setSession(appSession);
  661. }
  662. else if (activity instanceof RoServerSessionActivity) {
  663. RoServerSessionActivityImpl acc = (RoServerSessionActivityImpl) activity;
  664. ServerRoSession appSession = this.diameterStack.getSession(activity.getSessionId(), ServerRoSession.class);
  665. session = appSession.getSessions().get(0);
  666. performBeforeReturnOnBase(activity, session);
  667. performBeforeReturnRo(acc, session);
  668. performBeforeReturnCC(acc);
  669. acc.setSession(appSession);
  670. }
  671. else {
  672. throw new IllegalArgumentException("Unknown activity type: " + activity);
  673. }
  674. }
  675. catch (Exception e) {
  676. throw new DiameterException(e);
  677. }
  678. }
  679. // Two calls are required since Ro relies on CCA. CCA does not know anything about Ro so it needs its fields created.
  680. private void performBeforeReturnCC(RoServerSessionActivityImpl acc) {
  681. }
  682. private void performBeforeReturnCC(RoClientSessionActivityImpl acc) {
  683. }
  684. private void performBeforeReturnRo(RoServerSessionActivityImpl acc, Session session) {
  685. RoMessageFactoryImpl messageFactory = new RoMessageFactoryImpl(baseMessageFactory, session.getSessionId(), stack);
  686. // Set the first configured Application-Id as default for message factory
  687. ApplicationId firstAppId = authApplicationIds.get(0);
  688. messageFactory.setApplicationId(firstAppId.getVendorId(), firstAppId.getAuthAppId());
  689. acc.setRoMessageFactory(messageFactory);
  690. // acc.setRoAvpFactory(roAvpFactory);
  691. }
  692. private void performBeforeReturnRo(RoClientSessionActivityImpl acc, Session session) {
  693. RoMessageFactoryImpl messageFactory = new RoMessageFactoryImpl(baseMessageFactory, session.getSessionId(), stack);
  694. // Set the first configured Application-Id as default for message factory
  695. ApplicationId firstAppId = authApplicationIds.get(0);
  696. messageFactory.setApplicationId(firstAppId.getVendorId(), firstAppId.getAuthAppId());
  697. acc.setRoMessageFactory(messageFactory);
  698. // acc.setRoAvpFactory(roAvpFactory);
  699. }
  700. private void performBeforeReturnOnBase(DiameterActivityImpl ac, Session session) {
  701. DiameterMessageFactoryImpl msgFactory = new DiameterMessageFactoryImpl(session, stack, new DiameterIdentity[] {});
  702. ac.setAvpFactory(baseAvpFactory);
  703. ac.setMessageFactory(msgFactory);
  704. ac.setCurrentWorkingSession(session);
  705. ac.setSessionListener(lst);
  706. }
  707. // private void performBeforeReturnCC(DiameterActivityImpl ac)
  708. // {
  709. // CreditControlSessionImpl ccs = (CreditControlSessionImpl) ac;
  710. // ccs.setCCAAvpFactory(ccaAvpFactory);
  711. // ccs.setCCAMessageFactory(ccaMessageFactory);
  712. // }
  713. @Override
  714. public DiameterActivity get(DiameterActivityHandle handle) {
  715. return super.get(handle);
  716. }
  717. @Override
  718. public void put(DiameterActivityHandle handle, DiameterActivity activity) {
  719. super.put(handle, activity);
  720. }
  721. @Override
  722. public DiameterActivity remove(DiameterActivityHandle handle) {
  723. return super.remove(handle);
  724. }
  725. };
  726. }
  727. }
  728. /**
  729. * Create the Diameter Activity Handle for an given session id
  730. *
  731. * @param sessionId the session identifier to create the activity handle from
  732. * @return a DiameterActivityHandle for the provided sessionId
  733. */
  734. protected DiameterActivityHandle getActivityHandle(String sessionId) {
  735. return new DiameterActivityHandle(sessionId);
  736. }
  737. // NetworkReqListener Implementation -----------------------------------
  738. public Answer processRequest(Request request) {
  739. if(tracer.isInfoEnabled()) {
  740. tracer.info("Diameter Ro RA :: Got Request. Command-Code[" + request.getCommandCode() + "]");
  741. }
  742. // Here we receive initial request for which session does not exist!
  743. // Valid messages are:
  744. // * CCR - if we act as server, this is the message we receive
  745. // * NO other message should make it here, if it gets its an errro ?
  746. // FIXME: baranowb: check if ACR is vald here also
  747. if(request.getCommandCode() == RoCreditControlRequest.commandCode) {
  748. DiameterActivity activity;
  749. try {
  750. activity = raProvider.createActivity(request);
  751. if(activity == null) {
  752. tracer.severe("Diameter Ro RA :: Failed to create session, Command-Code: " + request.getCommandCode() + ", Session-Id: " + request.getSessionId());
  753. }
  754. else {
  755. // We can only have server session?, but for sake error catching
  756. if(activity instanceof RoServerSessionActivity) {
  757. RoServerSessionActivityImpl session = (RoServerSessionActivityImpl) activity;
  758. ((ServerRoSessionImpl)session.getSession()).processRequest(request);
  759. }
  760. }
  761. }
  762. catch (CreateActivityException e) {
  763. tracer.severe("Failure trying to create Ro Activity.", e);
  764. }
  765. // Returning null so we can answer later
  766. return null;
  767. }
  768. else {
  769. if(tracer.isInfoEnabled()) {
  770. tracer.info("Diameter Ro RA :: Received unexpected Request. Either its not CCR or session should exist to handle this, Command-Code: " + request.getCommandCode() + ", Session-Id: " + request.getSessionId());
  771. }
  772. }
  773. return null;
  774. }
  775. /*
  776. * (non-Javadoc)
  777. * @see org.jdiameter.api.EventListener#receivedSuccessMessage(org.jdiameter.api.Message, org.jdiameter.api.Message)
  778. */
  779. public void receivedSuccessMessage(Request request, Answer answer) {
  780. if(tracer.isFineEnabled()) {
  781. tracer.fine("Diameter Ro RA :: receivedSuccessMessage :: " + "Request[" + request + "], Answer[" + answer + "].");
  782. }
  783. tracer.warning("Resource Adaptor should not receive this (receivedSuccessMessage), a session should exist to handle it.");
  784. try {
  785. if(tracer.isInfoEnabled()) {
  786. tracer.info("Received Message Result-Code: " + answer.getResultCode().getUnsigned32());
  787. }
  788. }
  789. catch (AvpDataException ignore) {
  790. // ignore, this was just for informational purposes...
  791. }
  792. }
  793. /*
  794. * (non-Javadoc)
  795. * @see org.jdiameter.api.EventListener#timeoutExpired(org.jdiameter.api.Message)
  796. */
  797. public void timeoutExpired(Request request) {
  798. if(tracer.isInfoEnabled()) {
  799. tracer.info("Diameter Ro RA :: timeoutExpired :: " + "Request[" + request + "].");
  800. }
  801. tracer.warning("Resource Adaptor should not receive this (timeoutExpired), a session should exist to handle it.");
  802. try {
  803. // Message delivery timed out - we have to remove activity
  804. ((DiameterActivity) getActivity(getActivityHandle(request.getSessionId()))).endActivity();
  805. }
  806. catch (Exception e) {
  807. tracer.severe("Failure processing timeout message.", e);
  808. }
  809. }
  810. // Ro/CCA Session Creation Listener --------------------------------------
  811. public void sessionCreated(ClientRoSession ccClientSession) {
  812. // Make sure it's a new session and there's no activity created yet.
  813. if(this.getActivity(getActivityHandle(ccClientSession.getSessions().get(0).getSessionId())) != null) {
  814. tracer.warning("Activity found for created Credit-Control Client Session. Shouldn't exist. Aborting.");
  815. return;
  816. }
  817. // Create Client Activity
  818. RoClientSessionActivityImpl activity = new RoClientSessionActivityImpl(roMessageFactory, roAvpFactory, ccClientSession, null, null, stack);
  819. //FIXME: baranowb: add basic session mgmt for base? or do we rely on responses?
  820. //session.addStateChangeNotification(activity);
  821. activity.setSessionListener(this);
  822. addActivity(activity, false /*true*/);
  823. }
  824. public void sessionCreated(ServerRoSession ccServerSession)
  825. {
  826. // Make sure it's a new session and there's no activity created yet.
  827. if(this.getActivity(getActivityHandle(ccServerSession.getSessions().get(0).getSessionId())) != null) {
  828. tracer.warning("Activity found for created Credit-Control Server Session. Shouldn't exist. Aborting.");
  829. return;
  830. }
  831. // Create Server Activity
  832. RoServerSessionActivityImpl activity = new RoServerSessionActivityImpl(roMessageFactory, roAvpFactory, ccServerSession, null, null, stack);
  833. //FIXME: baranowb: add basic session mgmt for base? or do we rely on responses?
  834. //session.addStateChangeNotification(activity);
  835. activity.setSessionListener(this);
  836. addActivity(activity, false);
  837. }
  838. public boolean sessionExists(String sessionId) {
  839. return this.activities.containsKey(getActivityHandle(sessionId));
  840. }
  841. public void sessionDestroyed(String sessionId, Object appSession) {
  842. try {
  843. this.sleeEndpoint.endActivity(getActivityHandle(sessionId));
  844. }
  845. catch (Exception e) {
  846. tracer.severe("Failure Ending Activity with Session-Id[" + sessionId + "]", e);
  847. }
  848. }
  849. //
  850. // public void stateChanged(AppSession source, Enum oldState, Enum newState) {
  851. // DiameterActivityHandle dah = getActivityHandle(source.getSessionId());
  852. // Object activity = getActivity(dah);
  853. // if (activity != null) {
  854. // if (source instanceof ClientCCASession || source instanceof ServerCCASession) {
  855. // try{
  856. // CreditControlSessionImpl ccs = (CreditControlSessionImpl) activity;
  857. // ccs.stateChanged(source, oldState, newState);
  858. // }catch(Exception e)
  859. // {
  860. // tracer.warning("Failed to deliver state, for: " + dah + " on stateChanged( " + source + ", " + oldState + ", " + newState + " )", e);
  861. // }
  862. // }
  863. // } else {
  864. // tracer.warning("No activity for: " + dah + " on stateChanged( " + source + ", " + oldState + ", " + newState + " )");
  865. // }
  866. //
  867. // }
  868. // Provider Implementation ---------------------------------------------
  869. private class RoProviderImpl implements RoProvider {
  870. private DiameterRoResourceAdaptor ra;
  871. private Validator validator = new ValidatorImpl();
  872. public RoProviderImpl(DiameterRoResourceAdaptor ra) {
  873. this.ra = ra;
  874. }
  875. public RoClientSessionActivity createRoClientSessionActivity() throws CreateActivityException {
  876. try {
  877. ClientRoSession session = ((ISessionFactory) stack.getSessionFactory()).getNewAppSession(null, authApplicationIds.get(0), ClientRoSession.class, new Object[]{});
  878. sessionCreated(session);
  879. if (session == null) {
  880. tracer.severe("Failure creating Ro Client Session (null).");
  881. return null;
  882. }
  883. return (RoClientSessionActivity) getActivity(getActivityHandle(session.getSessions().get(0).getSessionId()));
  884. }
  885. catch (Exception e) {
  886. throw new CreateActivityException(e);
  887. }
  888. }
  889. public RoClientSessionActivity createRoClientSessionActivity(DiameterIdentity destinationHost, DiameterIdentity destinationRealm) throws CreateActivityException {
  890. RoClientSessionActivityImpl clientSession = (RoClientSessionActivityImpl) this.createRoClientSessionActivity();
  891. clientSession.setDestinationHost(destinationHost);
  892. clientSession.setDestinationRealm(destinationRealm);
  893. return clientSession;
  894. }
  895. public RoAvpFactory getRoAvpFactory() {
  896. return this.ra.roAvpFactory;
  897. }
  898. public RoMessageFactory getRoMessageFactory() {
  899. return this.ra.roMessageFactory;
  900. }
  901. public RoCreditControlAnswer sendRoCreditControlRequest(RoCreditControlRequest ccr) throws IOException {
  902. try {
  903. DiameterActivityImpl activity = (DiameterActivityImpl) getActivity(getActivityHandle(ccr.getSessionId()));
  904. if (activity == null) {
  905. activity = (DiameterActivityImpl) createActivity(((DiameterMessageImpl)ccr).getGenericData());
  906. }
  907. return (RoCreditControlAnswer) activity.sendSyncMessage(ccr);
  908. }
  909. catch (Exception e) {
  910. tracer.severe("Failure sending sync request.", e);
  911. }
  912. // FIXME Throw unknown message exception?
  913. return null;
  914. }
  915. private DiameterActivity createActivity(Message message) throws CreateActivityException {
  916. DiameterActivity activity = activities.get(getActivityHandle(message.getSessionId()));
  917. if (activity == null) {
  918. if (message.isRequest()) {
  919. return createRoServerSessionActivity((Request) message);
  920. }
  921. else {
  922. AvpSet avps = message.getAvps();
  923. Avp avp = null;
  924. DiameterIdentity destinationHost = null;
  925. DiameterIdentity destinationRealm = null;
  926. if ((avp = avps.getAvp(Avp.DESTINATION_HOST)) != null) {
  927. try {
  928. destinationHost = new DiameterIdentity(avp.getDiameterIdentity());
  929. }
  930. catch (AvpDataException e) {
  931. tracer.severe("Failed to extract Destination-Host from Message.", e);
  932. }
  933. }
  934. if ((avp = avps.getAvp(Avp.DESTINATION_REALM)) != null) {
  935. try {
  936. destinationRealm = new DiameterIdentity(avp.getDiameterIdentity());
  937. }
  938. catch (AvpDataException e) {
  939. tracer.severe("Failed to extract Destination-Realm from Message.", e);
  940. }
  941. }
  942. return (DiameterActivity) createRoClientSessionActivity(destinationHost, destinationRealm);
  943. }
  944. }
  945. return activity;
  946. }
  947. private DiameterActivity createRoServerSessionActivity(Request message) throws CreateActivityException {
  948. try {
  949. ServerRoSession session = ((ISessionFactory) stack.getSessionFactory()).getNewAppSession(message.getSessionId(), authApplicationIds.get(0), ServerRoSession.class, new Object[]{});
  950. sessionCreated(session);
  951. if (session == null) {
  952. tracer.severe("Failure creating Ro Server Session (null).");
  953. return null;
  954. }
  955. return (DiameterActivity) getActivity(getActivityHandle(session.getSessions().get(0).getSessionId()));
  956. }
  957. catch (Exception e) {
  958. throw new CreateActivityException(e);
  959. }
  960. }
  961. public DiameterIdentity[] getConnectedPeers() {
  962. return ra.getConnectedPeers();
  963. }
  964. public int getPeerCount() {
  965. return ra.getConnectedPeers().length;
  966. }
  967. /* (non-Javadoc)
  968. * @see net.java.slee.resource.diameter.ro.RoProvider#getValidator()
  969. */
  970. @Override
  971. public Validator getValidator() {
  972. return this.validator;
  973. }
  974. }
  975. public DiameterIdentity[] getConnectedPeers() {
  976. if (this.stack != null) {
  977. try {
  978. // Get the list of peers from the stack
  979. List<Peer> peers = stack.unwrap(PeerTable.class).getPeerTable();
  980. DiameterIdentity[] result = new DiameterIdentity[peers.size()];
  981. int i = 0;
  982. // Get each peer from the list and make a DiameterIdentity
  983. for (Peer peer : peers) {
  984. DiameterIdentity identity = new DiameterIdentity(peer.getUri().toString());
  985. result[i++] = identity;
  986. }
  987. return result;
  988. }
  989. catch (Exception e) {
  990. tracer.severe("Failure getting peer list.", e);
  991. }
  992. }
  993. return new DiameterIdentity[0];
  994. }
  995. }