package org.mobicents.slee.resource.xcapclient; import java.io.Serializable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.slee.Address; import javax.slee.InvalidStateException; import javax.slee.resource.ActivityHandle; import javax.slee.resource.BootstrapContext; import javax.slee.resource.FailureReason; import javax.slee.resource.Marshaler; import javax.slee.resource.ResourceAdaptor; import javax.slee.resource.ResourceAdaptorTypeID; import javax.slee.resource.ResourceException; import javax.slee.resource.SleeEndpoint; import org.apache.log4j.Logger; import org.mobicents.slee.container.SleeContainer; import org.mobicents.slee.resource.ResourceAdaptorActivityContextInterfaceFactory; import org.mobicents.slee.resource.ResourceAdaptorEntity; import org.mobicents.slee.resource.ResourceAdaptorState; import org.mobicents.slee.resource.xcapclient.ResponseEvent; import org.mobicents.slee.resource.xcapclient.XCAPClientActivityContextInterfaceFactory; import org.mobicents.slee.resource.xcapclient.XCAPClientResourceAdaptorSbbInterface; import org.mobicents.slee.resource.xcapclient.XCAPResourceAdaptorActivityHandle; import org.openxdm.xcap.client.XCAPClient; import org.openxdm.xcap.client.XCAPClientImpl; /** * @author Eduardo Martins * @version 2.0 * */ public class XCAPClientResourceAdaptor implements ResourceAdaptor, Serializable { private static final long serialVersionUID = 1L; private static transient Logger logger = Logger.getLogger(XCAPClientResourceAdaptor.class); private String XCAP_SERVER_HOST; private int XCAP_SERVER_PORT; private String XCAP_SERVER_ROOT; private ResourceAdaptorState state; private transient ConcurrentHashMap<XCAPResourceAdaptorActivityHandle, AsyncActivityImpl> activities = new ConcurrentHashMap<XCAPResourceAdaptorActivityHandle, AsyncActivityImpl>(); private transient SleeEndpoint sleeEndpoint; private transient BootstrapContext bootstrapContext; private transient XCAPClientResourceAdaptorSbbInterface sbbInterface; private transient XCAPClientActivityContextInterfaceFactory acif; private transient XCAPClient client; private transient int responseEventID; private transient ExecutorService executorService = Executors.newCachedThreadPool(); public XCAPClientResourceAdaptor() { } public String getServerHost() { return XCAP_SERVER_HOST; } public void setServerHost(String serverHost) { this.XCAP_SERVER_HOST = serverHost; } public Integer getServerPort() { return Integer.valueOf(XCAP_SERVER_PORT); } public void setServerPort(Integer port) { this.XCAP_SERVER_PORT = port.intValue(); } public String getXcapRoot() { return XCAP_SERVER_ROOT; } public void setXcapRoot(String xcapRoot) { this.XCAP_SERVER_ROOT = xcapRoot; } public void entityCreated(BootstrapContext ctx) throws javax.slee.resource.ResourceException { //TODO if (logger.isDebugEnabled()) { logger.debug("entityCreated"); } this.init(ctx); } public void entityRemoved() { //TODO if (logger.isDebugEnabled()) { logger.debug("entityRemoved"); } } public void entityActivated() throws ResourceException { if (logger.isDebugEnabled()) { logger.debug("entityActivated"); } try { this.configure(); } catch (InvalidStateException e1) { logger.warn(e1); } this.start(); } public void entityDeactivating() { //TODO if (logger.isDebugEnabled()) { logger.debug("entityDeactivating"); } this.stopping(); } public void entityDeactivated() { if (logger.isDebugEnabled()) { logger.debug("entityDeactivated"); } this.stop(); } public void eventProcessingFailed(ActivityHandle arg0, Object arg1, int arg2, Address arg3, int arg4, FailureReason arg5) { // TODO Auto-generated method stub } public void eventProcessingSuccessful(ActivityHandle arg0, Object arg1, int arg2, Address arg3, int arg4) { // TODO Auto-generated method stub } public void endActivity(ActivityHandle ah) { if (logger.isDebugEnabled()) { logger.debug("endActivity"); } if (activities.containsKey(ah)) { // tell slee to end the activity try { this.sleeEndpoint.activityEnding(ah); } catch (Exception e) { logger.error("unable to end activity: ",e); } } } public void activityEnded(ActivityHandle ah) { if (logger.isDebugEnabled()) { logger.debug("activityEnded(ActivityHandle="+ah+")"); } // just remove the handle activities.remove(ah); } public void activityUnreferenced(ActivityHandle ah) { // ignore } public void queryLiveness(ActivityHandle ah) { // ignore } public Object getActivity(ActivityHandle ah) { if (logger.isDebugEnabled()) { logger.debug("get Activity with ActivityHandle "+ah.toString()); } // if handle exists then recreate activity return activities.get(ah); } public ActivityHandle getActivityHandle(Object arg0) { if (logger.isDebugEnabled()) { logger.debug("getActivityHandle"); } XCAPResourceAdaptorActivityHandle activityHandle = ((AsyncActivityImpl)arg0).getHandle(); if (activities.containsKey(activityHandle)) { return activityHandle; } else { return null; } } public Object getSBBResourceAdaptorInterface(String arg0) { if (logger.isDebugEnabled()) { logger.debug("getSBBResourceAdaptorInterface"); } return this.sbbInterface; } public Marshaler getMarshaler() { //TODO if (logger.isDebugEnabled()) { logger.debug("getMarshaler"); } return null; } public void serviceInstalled(String arg0, int[] arg1, String[] arg2) { // EVENT FILTERING IS NO GOOD FOR THIS RA } public void serviceActivated(String arg0) { // EVENT FILTERING IS NO GOOD FOR THIS RA } public void serviceDeactivated(String arg0) { // EVENT FILTERING IS NO GOOD FOR THIS RA } public void serviceUninstalled(String arg0) { // EVENT FILTERING IS NO GOOD FOR THIS RA } public void init(BootstrapContext bootstrapContext) throws javax.slee.resource.ResourceException { if (logger.isDebugEnabled()) { logger.debug("init"); } this.bootstrapContext = bootstrapContext; this.sleeEndpoint = bootstrapContext.getSleeEndpoint(); try { this.responseEventID = bootstrapContext.getEventLookupFacility().getEventID("ResponseEvent", "org.mobicents", "1.0"); } catch (Exception e) { throw new ResourceException(e.getMessage()); } // TODO use JSLEE 1.1 facilities state = ResourceAdaptorState.UNCONFIGURED; } public void configure() throws InvalidStateException { if (logger.isDebugEnabled()) { logger.debug("configure"); } if (this.state != ResourceAdaptorState.UNCONFIGURED) { throw new InvalidStateException("Cannot configure RA wrong state: " + this.state); } state = ResourceAdaptorState.CONFIGURED; } public void start() throws ResourceException { if (logger.isDebugEnabled()) { logger.debug("start"); } try { SleeContainer container = SleeContainer.lookupFromJndi(); ResourceAdaptorEntity resourceAdaptorEntity = ((ResourceAdaptorEntity) container .getResourceAdaptorEnitity(this.bootstrapContext.getEntityName())); ResourceAdaptorTypeID raTypeId = resourceAdaptorEntity .getInstalledResourceAdaptor().getRaType().getResourceAdaptorTypeID(); this.acif = new XCAPClientActivityContextInterfaceFactoryImpl( resourceAdaptorEntity.getServiceContainer(), this.bootstrapContext.getEntityName()); resourceAdaptorEntity.getServiceContainer().getActivityContextInterfaceFactories().put(raTypeId, this.acif); if (this.acif != null) { String jndiName = ((ResourceAdaptorActivityContextInterfaceFactory) this.acif) .getJndiName(); int begind = jndiName.indexOf(':'); int toind = jndiName.lastIndexOf('/'); String prefix = jndiName.substring(begind + 1, toind); String name = jndiName.substring(toind + 1); if (logger.isDebugEnabled()) { logger.debug("jndiName prefix =" + prefix + "; jndiName = " + name); } SleeContainer.registerWithJndi(prefix, name, this.acif); } // init client client = new XCAPClientImpl(XCAP_SERVER_HOST,XCAP_SERVER_PORT,XCAP_SERVER_ROOT); // create sbb interface sbbInterface = new XCAPClientResourceAdaptorSbbInterfaceImpl(this); } catch (Exception ex) { ex.printStackTrace(); throw new ResourceException(ex.getMessage()); } state = ResourceAdaptorState.ACTIVE; } /** * Stops this resource adaptor. * */ public void stop() { if (logger.isDebugEnabled()) { logger.debug("stop"); } // end all activities synchronized(activities) { for(XCAPResourceAdaptorActivityHandle handle : activities.keySet()) { endActivity(handle); } } if (logger.isDebugEnabled()) { logger.debug("All activities ended."); } try { if (this.acif != null) { String jndiName = ((ResourceAdaptorActivityContextInterfaceFactory) this.acif).getJndiName(); //remove "java:" prefix int begind = jndiName.indexOf(':'); String javaJNDIName = jndiName.substring(begind + 1); SleeContainer.unregisterWithJndi(javaJNDIName); } } catch (Exception e) { logger.error("Can't unbind naming context",e); } this.sbbInterface = null; this.client.shutdown(); this.client = null; this.executorService.shutdown(); this.executorService = null; if (logger.isDebugEnabled()) { logger.debug("XCAP Client RA Resource Adaptor stopped."); } } public void stopping() { if (logger.isDebugEnabled()) { logger.debug("stopping"); } state = ResourceAdaptorState.STOPPING; } public Object getActivityContextInterfaceFactory() { if (logger.isDebugEnabled()) { logger.debug("getActivityContextInterfaceFactory"); } return acif; } public void setResourceAdaptorEntity( ResourceAdaptorEntity resourceAdaptorEntity) { //TODO if (logger.isDebugEnabled()) { logger.debug("setResourceAdaptorEntity"); } } /* Receives an Event and sends it to the SLEE */ public void processResponseEvent(ResponseEvent event, XCAPResourceAdaptorActivityHandle handle){ if (logger.isDebugEnabled()) { logger.debug("NEW RESPONSE EVENT"); } try { sleeEndpoint.fireEvent(handle, event, responseEventID, null); } catch (Exception e) { logger.warn("unable to fire event",e); } } protected ConcurrentHashMap<XCAPResourceAdaptorActivityHandle, AsyncActivityImpl> getActivities() { return activities; } /** * @return Returns the sleeEndpoint. */ public SleeEndpoint getSleeEndpoint() { if (logger.isDebugEnabled()) { logger.debug("getSleeEndpoint"); } return sleeEndpoint; } /** * @param sleeEndpoint The sleeEndpoint to set. */ public void setSleeEndpoint(SleeEndpoint sleeEndpoint) { if (logger.isDebugEnabled()) { logger.debug("setSleeEndpoint"); } this.sleeEndpoint = sleeEndpoint; } public XCAPClient getClient() { return client; } public ExecutorService getExecutorService() { return executorService; } }