package org.mobicents.slee.sipevent.examples; import java.io.IOException; import java.io.StringWriter; import javax.naming.Context; import javax.naming.InitialContext; import javax.slee.ActivityContextInterface; import javax.slee.ChildRelation; import javax.slee.RolledBackContext; import javax.slee.SbbContext; import javax.slee.facilities.TimerEvent; import javax.slee.facilities.TimerFacility; 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 javax.xml.bind.JAXBContext; import org.apache.log4j.Logger; import org.mobicents.slee.sipevent.server.subscription.pojo.Subscription; import org.mobicents.slee.sipevent.server.subscription.pojo.Subscription.Event; import org.mobicents.slee.sipevent.server.subscription.pojo.Subscription.Status; import org.mobicents.slee.sippresence.client.PresenceClientControlParentSbbLocalObject; import org.mobicents.slee.sippresence.client.PresenceClientControlSbbLocalObject; import org.mobicents.slee.xdm.server.XDMClientControlParentSbbLocalObject; import org.mobicents.slee.xdm.server.XDMClientControlSbbLocalObject; import org.openxdm.xcap.client.appusage.resourcelists.jaxb.EntryType; import org.openxdm.xcap.client.appusage.resourcelists.jaxb.ListType; import org.openxdm.xcap.client.appusage.resourcelists.jaxb.EntryType.DisplayName; import org.openxdm.xcap.client.appusage.rlsservices.jaxb.ObjectFactory; import org.openxdm.xcap.client.appusage.rlsservices.jaxb.PackagesType; import org.openxdm.xcap.client.appusage.rlsservices.jaxb.RlsServices; import org.openxdm.xcap.client.appusage.rlsservices.jaxb.ServiceType; import org.openxdm.xcap.common.key.UserDocumentUriKey; import org.openxdm.xcap.common.key.XcapUriKey; import org.openxdm.xcap.server.slee.appusage.rlsservices.RLSServicesAppUsage; /** * * @author Eduardo Martins * */ public abstract class RLSExampleSubscriberSbb implements javax.slee.Sbb, RLSExampleSubscriberSbbLocalObject { String presenceDomain = System.getProperty("bind.address","127.0.0.1"); String subscriber = "sip:carol@"+presenceDomain; String notifier = "sip:mybuddies@"+presenceDomain;; String eventPackage = "presence"; String contentType = "application"; String contentSubType = "pidf+xml"; int expires = 300; // --- PRESENCE CLIENT CHILD SBB public abstract ChildRelation getPresenceClientControlSbbChildRelation(); public abstract PresenceClientControlSbbLocalObject getPresenceClientControlSbbCMP(); public abstract void setPresenceClientControlSbbCMP( PresenceClientControlSbbLocalObject value); private PresenceClientControlSbbLocalObject getPresenceClientControlSbb() { PresenceClientControlSbbLocalObject childSbb = getPresenceClientControlSbbCMP(); if (childSbb == null) { try { childSbb = (PresenceClientControlSbbLocalObject) getPresenceClientControlSbbChildRelation() .create(); } catch (Exception e) { log4j.error("Failed to create child sbb", e); return null; } setPresenceClientControlSbbCMP(childSbb); childSbb .setParentSbb((PresenceClientControlParentSbbLocalObject) this.sbbContext .getSbbLocalObject()); } return childSbb; } // --- XDM CLIENT CHILD SBB public abstract ChildRelation getXDMClientControlChildRelation(); public abstract XDMClientControlSbbLocalObject getXDMClientControlChildSbbCMP(); public abstract void setXDMClientControlChildSbbCMP( XDMClientControlSbbLocalObject value); public XDMClientControlSbbLocalObject getXDMClientControlSbb() { XDMClientControlSbbLocalObject childSbb = getXDMClientControlChildSbbCMP(); if (childSbb == null) { try { childSbb = (XDMClientControlSbbLocalObject) getXDMClientControlChildRelation() .create(); } catch (Exception e) { log4j.error("Failed to create child sbb", e); return null; } setXDMClientControlChildSbbCMP(childSbb); childSbb .setParentSbb((XDMClientControlParentSbbLocalObject) this.sbbContext .getSbbLocalObject()); } return childSbb; } // --- CMPs public abstract void setParentSbbCMP(RLSExampleSubscriberParentSbbLocalObject value); public abstract RLSExampleSubscriberParentSbbLocalObject getParentSbbCMP(); // --- SBB LOCAL OBJECT public void setParentSbb(RLSExampleSubscriberParentSbbLocalObject parentSbb) { setParentSbbCMP(parentSbb); } private EntryType createEntryType(String uri) { EntryType entryType = new EntryType(); entryType.setUri(uri); DisplayName displayName = new EntryType.DisplayName(); displayName.setValue(uri); entryType.setDisplayName(displayName); return entryType; } private String getRlsServices(String[] entryURIs) { StringWriter stringWriter = new StringWriter(); try { JAXBContext context = JAXBContext.newInstance("org.openxdm.xcap.client.appusage.rlsservices.jaxb"); ListType listType = new ListType(); for (String entryURI : entryURIs) { listType.getListOrExternalOrEntry().add(createEntryType(entryURI)); } ServiceType serviceType = new ServiceType(); serviceType.setList(listType); PackagesType packagesType = new PackagesType(); packagesType.getPackageAndAny().add(new ObjectFactory().createPackagesTypePackage(eventPackage)); serviceType.setPackages(packagesType); serviceType.setUri(notifier); RlsServices rlsServices = new RlsServices(); rlsServices.getService().add(serviceType); context.createMarshaller().marshal(rlsServices, stringWriter); return stringWriter.toString(); } catch (Exception e) { log4j.error("failed to read rls-services.xml",e); } finally { try { stringWriter.close(); } catch (IOException e) { log4j.error(e.getMessage(),e); } } return null; } public void start(String[] entryURIs) { try { XDMClientControlSbbLocalObject xdm = getXDMClientControlSbb(); // insert the document xdm.put(new UserDocumentUriKey(RLSServicesAppUsage.ID,subscriber,"index"), RLSServicesAppUsage.MIMETYPE, getRlsServices(entryURIs).getBytes("UTF-8"),null); } catch (Exception e) { log4j.error(e.getMessage(), e); getParentSbbCMP().subscriberNotStarted(); } } private String getSubscriptionId() { return "rls-example~"+subscriber+"~"+notifier+"~"+eventPackage; } public void putResponse(XcapUriKey key, int responseCode, String responseContent, String tag) { log4j.info("Response to the insertion of the rls services document: status="+responseCode+",content="+responseContent); if (responseCode != 200 && responseCode != 201) { getParentSbbCMP().subscriberNotStarted(); } else { // now subscribe the presence of it getPresenceClientControlSbb().newSubscription(subscriber, "...", notifier, eventPackage, getSubscriptionId(), expires); } } public void newSubscriptionOk(String subscriber, String notifier, String eventPackage, String subscriptionId, int expires, int responseCode) { log4j.info("subscribe ok: responseCode=" + responseCode + ",expires=" + expires); try { // let's set a periodic timer in a null activity to refresh the // publication TimerOptions timerOptions = new TimerOptions(); timerOptions.setPersistent(true); timerOptions.setPreserveMissed(TimerPreserveMissed.ALL); NullActivity nullActivity = nullActivityFactory.createNullActivity(); ActivityContextInterface aci = nullACIFactory.getActivityContextInterface(nullActivity); aci.attach(this.sbbContext.getSbbLocalObject()); timerFacility.setTimer(aci, null, System.currentTimeMillis() + (expires-1) * 1000, (expires-1) * 1000, 0, timerOptions); getParentSbbCMP().subscriberStarted(); } catch (Exception e) { log4j.error(e.getMessage(),e); } } private void deleteRlsServices() { try { getXDMClientControlSbb().delete(new UserDocumentUriKey(RLSServicesAppUsage.ID,subscriber,"index"),null); } catch (Exception e) { log4j.error(e.getMessage(), e); } } public void newSubscriptionError(String subscriber, String notifier, String eventPackage, String subscriptionId, int error) { log4j.info("error on subscribe: error=" + error); deleteRlsServices(); } public void notifyEvent(String subscriber, String notifier, String eventPackage, String subscriptionId, Event terminationReason, Status status, String content, String contentType, String contentSubtype) { String notification = "\nNOTIFY EVENT:" + "\n+-- Subscriber: " + subscriber + "\n+-- Notifier: " + notifier + "\n+-- EventPackage: " + eventPackage + "\n+-- SubscriptionId: " + subscriptionId + "\n+-- Subscription status: " + status + "\n+-- Subscription terminationReason: " + terminationReason + "\n+-- Content Type: " + contentType + '/' + contentSubtype + "\n+-- Content:\n\n" + content; log4j.info(notification); if (status.equals(Subscription.Status.terminated) && terminationReason != null && terminationReason.equals(Subscription.Event.deactivated)) { log4j.info("The subscription was deactivated, re-subscribing"); // re-subscribe getPresenceClientControlSbb().newSubscription(subscriber, "...", notifier, eventPackage, getSubscriptionId(), expires); } } public void onTimerEvent(TimerEvent event, ActivityContextInterface aci) { // refresh subscription getPresenceClientControlSbb().refreshSubscription(subscriber, notifier, eventPackage, getSubscriptionId(), expires); } public void refreshSubscriptionOk(String subscriber, String notifier, String eventPackage, String subscriptionId, int expires) { log4j.info("resubscribe Ok : expires=" + expires); } public void refreshSubscriptionError(String subscriber, String notifier, String eventPackage, String subscriptionId, int error) { log4j.info("error on resubscribe: error=" + error); deleteRlsServices(); } public void stop() { getPresenceClientControlSbb().removeSubscription(subscriber, notifier, eventPackage, getSubscriptionId()); deleteRlsServices(); } public void removeSubscriptionError(String subscriber, String notifier, String eventPackage, String subscriptionId, int error) { log4j.info("error on unsubscribe: error=" + error); } public void removeSubscriptionOk(String subscriber, String notifier, String eventPackage, String subscriptionId) { log4j.info("unsubscribe Ok"); } public void deleteResponse(XcapUriKey key, int responseCode, String responseContent, String tag) { getParentSbbCMP().subscriberStopped(); } // --- SBB OBJECT private SbbContext sbbContext = null; // This SBB's context private TimerFacility timerFacility = null; private NullActivityContextInterfaceFactory nullACIFactory; private NullActivityFactory nullActivityFactory; /** * Called when an sbb object is instantied and enters the pooled state. */ public void setSbbContext(SbbContext sbbContext) { this.sbbContext = sbbContext; try { Context context = (Context) new InitialContext() .lookup("java:comp/env"); timerFacility = (TimerFacility) context .lookup("slee/facilities/timer"); nullACIFactory = (NullActivityContextInterfaceFactory) context .lookup("slee/nullactivity/activitycontextinterfacefactory"); nullActivityFactory = (NullActivityFactory) context .lookup("slee/nullactivity/factory"); } catch (Exception e) { log4j.error("Unable to retrieve factories, facilities & providers", e); } } public void unsetSbbContext() { log4j.info("unsetSbbContext()"); this.sbbContext = null; } public void sbbCreate() throws javax.slee.CreateException { } public void sbbPostCreate() throws javax.slee.CreateException { } public void sbbActivate() { } public void sbbPassivate() { } public void sbbRemove() { } public void sbbLoad() { } public void sbbStore() { } public void sbbExceptionThrown(Exception exception, Object event, ActivityContextInterface activity) { } public void sbbRolledBack(RolledBackContext sbbRolledBack) { } private static Logger log4j = Logger .getLogger(RLSExampleSubscriberSbb.class); }