package org.mobicents.slee.services.sip.location; import java.util.Map; import java.util.Set; import javax.naming.Context; import javax.naming.InitialContext; import javax.slee.ActivityContextInterface; import javax.slee.CreateException; import javax.slee.RolledBackContext; import javax.slee.Sbb; import javax.slee.SbbContext; import javax.slee.facilities.ActivityContextNamingFacility; import javax.slee.facilities.TimerEvent; import javax.slee.facilities.TimerFacility; import javax.slee.facilities.TimerID; import javax.slee.facilities.TimerOptions; import javax.slee.facilities.TimerPreserveMissed; import javax.slee.nullactivity.NullActivity; import javax.slee.nullactivity.NullActivityContextInterfaceFactory; import javax.slee.nullactivity.NullActivityFactory; import org.apache.log4j.Logger; public abstract class LocationSbb implements Sbb, LocationService { private static final Logger logger = Logger.getLogger(LocationSbb.class); private static LocationService locationService = null; private static final TimerOptions defaultTimerOptions = createDefaultTimerOptions(); private static TimerOptions createDefaultTimerOptions() { TimerOptions timerOptions = new TimerOptions(); timerOptions.setPreserveMissed(TimerPreserveMissed.ALL); return timerOptions; } private Context myEnv; private SbbContext sbbContext; private TimerFacility timerFacility; private NullActivityFactory nullActivityFactory; private NullActivityContextInterfaceFactory nullACIFactory; private ActivityContextNamingFacility activityContextNamingFacility; public void sbbActivate() {} public void sbbCreate() throws CreateException {} public void sbbExceptionThrown(Exception arg0, Object arg1, ActivityContextInterface arg2) {} public void sbbLoad() {} public void sbbPassivate() {} public void sbbPostCreate() throws CreateException {} public void sbbRemove() {} public void sbbRolledBack(RolledBackContext arg0) {} public void sbbStore() {} /* * (non-Javadoc) * @see javax.slee.Sbb#setSbbContext(javax.slee.SbbContext) */ public void setSbbContext(SbbContext sbbContext) { this.sbbContext = sbbContext; try { myEnv = (Context) new InitialContext().lookup("java:comp/env"); timerFacility = (TimerFacility) myEnv .lookup("slee/facilities/timer"); nullACIFactory = (NullActivityContextInterfaceFactory) myEnv .lookup("slee/nullactivity/activitycontextinterfacefactory"); nullActivityFactory = (NullActivityFactory) myEnv .lookup("slee/nullactivity/factory"); activityContextNamingFacility = (ActivityContextNamingFacility) myEnv .lookup("slee/facilities/activitycontextnaming"); if (locationService == null) { locationService = LocationServiceFactory.getLocationService((String) myEnv.lookup("LOCATION_SERVICE_CLASS_NAME")); } } catch (Exception ne) { logger.error("Could not set SBB context: ", ne); } } /* * (non-Javadoc) * @see javax.slee.Sbb#unsetSbbContext() */ public void unsetSbbContext() { this.sbbContext = null; } /** * * @param aci * @return */ public abstract RegistrationBindingActivityContextInterface asSbbActivityContextInterface( ActivityContextInterface aci); /* * */ private String getACIName(String contactAddress,String sipAddress) { return "LocationSbb:aci:ca="+contactAddress+",sa="+sipAddress; } // **** SBB LOCAL METHODS /* * (non-Javadoc) * @see org.mobicents.slee.services.sip.location.LocationService#addBinding(java.lang.String, java.lang.String, java.lang.String, long, long, float, java.lang.String, long) */ public RegistrationBinding addBinding(String sipAddress, String contactAddress, String comment, long expires, long registrationDate, float qValue, String callId, long cSeq) throws LocationServiceException { // add binding RegistrationBinding registrationBinding = locationService.addBinding(sipAddress, contactAddress, comment, expires, registrationDate, qValue, callId, cSeq); if (logger.isDebugEnabled()) { logger.debug("addBinding: "+registrationBinding); } // create null aci NullActivity nullActivity = nullActivityFactory.createNullActivity(); ActivityContextInterface aci = null; try { aci = nullACIFactory.getActivityContextInterface(nullActivity); // set name activityContextNamingFacility.bind(aci, getACIName(contactAddress, sipAddress)); } catch (Exception e) { throw new LocationServiceException(e.getLocalizedMessage()); } // atach to this activity aci.attach(sbbContext.getSbbLocalObject()); // set timer TimerID timerID = timerFacility.setTimer(aci, null,registrationDate + ((expires+1)*1000), defaultTimerOptions); // save data in aci RegistrationBindingActivityContextInterface rgAci = asSbbActivityContextInterface(aci); rgAci.setTimerID(timerID); rgAci.setContactAddress(contactAddress); rgAci.setSipAddress(sipAddress); if(logger.isInfoEnabled()) { logger.info("added binding: sipAddress="+sipAddress+",contactAddress="+contactAddress); } return registrationBinding; } /* * (non-Javadoc) * @see org.mobicents.slee.services.sip.location.LocationService#getRegisteredUsers() */ public Set<String> getRegisteredUsers() throws LocationServiceException { if (logger.isDebugEnabled()) { logger.debug("getRegisteredUsers"); } return locationService.getRegisteredUsers(); } /* * (non-Javadoc) * @see org.mobicents.slee.services.sip.location.LocationService#getBindings(java.lang.String) */ public Map<String, RegistrationBinding> getBindings(String sipAddress) throws LocationServiceException { if (logger.isDebugEnabled()) { logger.debug("getBindings: sipAddress="+sipAddress); } return locationService.getBindings(sipAddress); } /* * (non-Javadoc) * @see org.mobicents.slee.services.sip.location.LocationService#updateBinding(org.mobicents.slee.services.sip.location.RegistrationBinding) */ public void updateBinding(RegistrationBinding registrationBinding) throws LocationServiceException { if (logger.isDebugEnabled()) { logger.debug("updateBinding: registrationBinding="+registrationBinding); } // get named aci ActivityContextInterface aci = activityContextNamingFacility.lookup(getACIName(registrationBinding.getContactAddress(), registrationBinding.getSipAddress())); // get the timer id from the aci and reset the timer RegistrationBindingActivityContextInterface rgAci = asSbbActivityContextInterface(aci); timerFacility.cancelTimer(rgAci.getTimerID()); rgAci.setTimerID(timerFacility.setTimer(aci, null, registrationBinding.getRegistrationDate() + ((registrationBinding.getExpires()+1) * 1000), defaultTimerOptions)); // update in location service locationService.updateBinding(registrationBinding); if(logger.isInfoEnabled()) { logger.info("binding updated: sipAddress="+registrationBinding.getSipAddress()+",contactAddress="+registrationBinding.getContactAddress()); } } /* * (non-Javadoc) * @see org.mobicents.slee.services.sip.location.LocationService#removeBinding(java.lang.String, java.lang.String) */ public void removeBinding(String sipAddress, String contactAddress) throws LocationServiceException { if (logger.isDebugEnabled()) { logger.debug("removeBinding: sipAddress="+sipAddress+",contactAddress="+contactAddress); } try { // lookup null aci from aci naming facility, get timerid and cancel // timer (when present). ActivityContextInterface aci = activityContextNamingFacility .lookup(getACIName(contactAddress, sipAddress)); if (aci != null) { timerFacility.cancelTimer(asSbbActivityContextInterface(aci) .getTimerID()); activityContextNamingFacility.unbind(getACIName(contactAddress, sipAddress)); // end null activity, detach is no good because this is a different // sbb entity then the one that create the binding ((NullActivity)aci.getActivity()).endActivity(); } } catch (Exception e) { throw new LocationServiceException(e.getLocalizedMessage()); } // remove from location service locationService.removeBinding(sipAddress, contactAddress); if(logger.isInfoEnabled()) { logger.info("removed binding: sipAddress="+sipAddress+",contactAddress="+contactAddress); } } /* (non-Javadoc) * @see org.mobicents.slee.services.sip.location.jmx.LocationServiceManagementMBean#getContacts(java.lang.String) */ public Set<String> getContacts(String sipAddress) throws LocationServiceException { return locationService.getContacts(sipAddress); } /* (non-Javadoc) * @see org.mobicents.slee.services.sip.location.jmx.LocationServiceManagementMBean#getExpirationTime(java.lang.String, java.lang.String) */ public long getExpirationTime(String sipAddress, String contactAddress) throws LocationServiceException { return locationService.getExpirationTime(sipAddress, contactAddress); } /* (non-Javadoc) * @see org.mobicents.slee.services.sip.location.jmx.LocationServiceManagementMBean#getRegisteredUserCount() */ public int getRegisteredUserCount() throws LocationServiceException { return locationService.getRegisteredUserCount(); } /** * a registration expires * @param timer * @param aci */ public void onTimerEvent(TimerEvent timer, ActivityContextInterface aci) { if (logger.isDebugEnabled()) { logger.debug("onTimerEvent()"); } aci.detach(sbbContext.getSbbLocalObject()); // cast to rg aci RegistrationBindingActivityContextInterface rgAci = asSbbActivityContextInterface(aci); // get data from aci String contactAddress = rgAci.getContactAddress(); String sipAddress = rgAci.getSipAddress(); // unbind from aci so it ends try { activityContextNamingFacility.unbind(getACIName(contactAddress, sipAddress)); } catch (Exception e) { logger.error(e); } // remove rg from location service try { locationService.removeBinding(sipAddress, contactAddress); } catch (Exception e) { logger.error(e); } if(logger.isInfoEnabled()) { logger.info("binding expired: sipAddress="+sipAddress+",contactAddress="+contactAddress); } } // PROCESSING SERVICE (DE)ACTIVATION public void init() { try { locationService.init(); } catch (Exception e) { logger.error(e); } } public void shutdown() { try { // lets close the jpa location service locationService.shutdown(); } catch (Exception e) { logger.error(e); } } }