package org.mobicents.slee.sipevent.server.internal; import javax.persistence.EntityManager; import javax.sip.message.Response; import javax.slee.ActivityContextInterface; import javax.slee.nullactivity.NullActivity; import org.apache.log4j.Logger; import org.mobicents.slee.sipevent.server.subscription.ImplementedSubscriptionControlSbbLocalObject; import org.mobicents.slee.sipevent.server.subscription.SubscriptionControlSbb; import org.mobicents.slee.sipevent.server.subscription.pojo.Subscription; import org.mobicents.slee.sipevent.server.subscription.pojo.SubscriptionKey; /** * Handles the creation of a new SIP subscription * * @author martins * */ public class NewInternalSubscriptionHandler { private static Logger logger = Logger .getLogger(SubscriptionControlSbb.class); private InternalSubscriptionHandler internalSubscriptionHandler; public NewInternalSubscriptionHandler( InternalSubscriptionHandler internalSubscriptionHandler) { this.internalSubscriptionHandler = internalSubscriptionHandler; } public void newInternalSubscription(String subscriber, String subscriberDisplayName, String notifier, String eventPackage, String subscriptionId, int expires, String content, String contentType, String contentSubtype, boolean eventList, EntityManager entityManager, ImplementedSubscriptionControlSbbLocalObject childSbb) { if (logger.isDebugEnabled()) { logger.debug("newInternalSubscription()"); } SubscriptionControlSbb sbb = internalSubscriptionHandler.sbb; // check if expires is not less than the allowed min expires if (expires >= sbb.getConfiguration().getMinExpires()) { // ensure expires is not bigger than max expires if (expires > sbb.getConfiguration().getMaxExpires()) { expires = sbb.getConfiguration().getMaxExpires(); } } else { // expires is > 0 but < min expires, respond (Interval // Too Brief) with Min-Expires = MINEXPIRES sbb.getParentSbbCMP().subscribeError(subscriber, notifier, eventPackage, subscriptionId, Response.INTERVAL_TOO_BRIEF); return; } // create subscription key SubscriptionKey key = new SubscriptionKey( SubscriptionKey.NO_CALL_ID, SubscriptionKey.NO_REMOTE_TAG, eventPackage, subscriptionId); // find subscription Subscription subscription = entityManager.find(Subscription.class, key); if (subscription != null) { // subscription exists sbb.getParentSbbCMP().subscribeError(subscriber, notifier, eventPackage, subscriptionId, Response.CONDITIONAL_REQUEST_FAILED); } else { authorizeNewInternalSubscription(subscriber, subscriberDisplayName, notifier, key, expires, content, contentType, contentSubtype, eventList, entityManager, childSbb); } } private void authorizeNewInternalSubscription(String subscriber, String subscriberDisplayName, String notifier, SubscriptionKey key, int expires, String content, String contentType, String contentSubtype, boolean eventList, EntityManager entityManager, ImplementedSubscriptionControlSbbLocalObject childSbb) { // ask authorization if (key.getEventPackage().endsWith(".winfo")) { // winfo package, only accept subscriptions when subscriber and // notifier are the same newInternalSubscriptionAuthorization(subscriber, subscriberDisplayName, notifier, key, expires, (subscriber.equals(notifier) ? Response.OK : Response.FORBIDDEN), eventList, entityManager, childSbb); } else { childSbb.isSubscriberAuthorized(subscriber, subscriberDisplayName, notifier, key, expires, content, contentType, contentSubtype,eventList,null); } } /** * Used by {@link ImplementedSubscriptionControlSbbLocalObject} to provide * the authorization to a new internal subscription request. * * @param event * @param subscriber * @param notifier * @param subscriptionKey * @param expires * @param responseCode * @param eventList * @param entityManager * @param childSbb */ public void newInternalSubscriptionAuthorization(String subscriber, String subscriberDisplayName, String notifier, SubscriptionKey subscriptionKey, int expires, int responseCode, boolean eventList, EntityManager entityManager, ImplementedSubscriptionControlSbbLocalObject childSbb) { if (logger.isDebugEnabled()) { logger.debug("newInternalSubscriptionAuthorization()"); } SubscriptionControlSbb sbb = internalSubscriptionHandler.sbb; ActivityContextInterface aci = null; // send response if (responseCode == Response.ACCEPTED || responseCode == Response.OK) { // create null activity, bind a name and attach the sbb NullActivity nullActivity = sbb.getNullActivityFactory() .createNullActivity(); try { aci = sbb.getNullACIFactory().getActivityContextInterface( nullActivity); sbb.getActivityContextNamingfacility().bind(aci, subscriptionKey.toString()); } catch (Exception e) { logger.error("Failed to create internal subscription aci", e); sbb.getParentSbbCMP().subscribeError(subscriber, notifier, subscriptionKey.getEventPackage(), subscriptionKey.getEventId(), Response.SERVER_INTERNAL_ERROR); return; } aci.attach(sbb.getSbbContext().getSbbLocalObject()); // inform parent sbb.getParentSbbCMP().subscribeOk(subscriber, notifier, subscriptionKey.getEventPackage(), subscriptionKey.getEventId(), expires, responseCode); } else { sbb.getParentSbbCMP().subscribeError(subscriber, notifier, subscriptionKey.getEventPackage(), subscriptionKey.getEventId(), responseCode); if (logger.isInfoEnabled()) { logger.info("Subscription: subscriber=" + subscriber + ",notifier=" + notifier + ",eventPackage=" + subscriptionKey.getEventPackage() + " not authorized (" + responseCode + ")"); } return; } // create subscription, initial status depends on authorization Subscription.Status initialStatus = responseCode == Response.ACCEPTED ? Subscription.Status.pending : Subscription.Status.active; Subscription subscription = new Subscription(subscriptionKey, subscriber, notifier, initialStatus, subscriberDisplayName, expires, eventList); if (!eventList || (responseCode == Response.ACCEPTED)) { // notify subscriber internalSubscriptionHandler.getInternalSubscriberNotificationHandler() .notifyInternalSubscriber(entityManager, subscription, aci, childSbb); } // notify winfo subscribers sbb.getWInfoSubscriptionHandler().notifyWinfoSubscriptions( entityManager, subscription, childSbb); // set new timer sbb.setSubscriptionTimerAndPersistSubscription(entityManager, subscription, expires + 1, aci); if (eventList && (responseCode == Response.OK)) { // resource list and active subscription, ask the event list control child to create the subscription if (!internalSubscriptionHandler.sbb.getEventListControlChildSbb().createSubscription(subscription)) { internalSubscriptionHandler.getRemoveInternalSubscriptionHandler().removeInternalSubscription(aci, subscription, entityManager, childSbb); } } if (logger.isInfoEnabled()) { logger.info("Created " + subscription); } } }