package org.mobicents.slee.sipevent.server.subscription.pojo; import java.io.Serializable; import java.util.List; import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.EntityManager; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Transient; import javax.slee.facilities.TimerID; /** * Subscription: A subscription is a set of application state associated * with a dialog. This application state includes a pointer to the * associated dialog, the event package name, and possibly an * identification token. Event packages will define additional * subscription state information. By definition, subscriptions * exist in both a subscriber and a notifier. * * This class is JPA pojo for a subscription. * * @author eduardomartins * */ @Entity @Table(name = "MOBICENTS_SIPEVENT_SUBSCRIPTIONS") @NamedQueries({ @NamedQuery(name=Subscription.JPA_NAMED_QUERY_SELECT_SUBSCRIPTION_FROM_TIMERID,query="SELECT s FROM Subscription s WHERE s.timerID = :timerID"), @NamedQuery(name=Subscription.JPA_NAMED_QUERY_SELECT_SUBSCRIPTIONS_FROM_NOTIFIER_AND_EVENTPACKAGE,query="SELECT s FROM Subscription s WHERE s.notifier = :notifier AND s.key.eventPackage = :eventPackage and s.notifierParams = null"), @NamedQuery(name=Subscription.JPA_NAMED_QUERY_SELECT_SUBSCRIPTIONS_FROM_NOTIFIER,query="SELECT s FROM Subscription s WHERE s.notifier = :notifier and s.notifierParams = null"), @NamedQuery(name=Subscription.JPA_NAMED_QUERY_SELECT_SUBSCRIPTIONS_FROM_NOTIFIER_WITH_PARAMS,query="SELECT s FROM Subscription s WHERE s.notifier = :notifier and s.notifierParams = :notifierParams"), @NamedQuery(name=Subscription.JPA_NAMED_QUERY_SELECT_DIALOG_SUBSCRIPTIONS,query="SELECT s FROM Subscription s WHERE s.key.callId = :callId AND s.key.remoteTag = :remoteTag") }) public class Subscription implements Serializable { /** * */ private static final long serialVersionUID = 8020033417766370446L; private static final String JPA_NAMED_QUERY_PREFIX = "MSPS_NQUERY_"; public static final String JPA_NAMED_QUERY_SELECT_SUBSCRIPTION_FROM_TIMERID = JPA_NAMED_QUERY_PREFIX + "selectSubscriptionFromTimerID"; public static final String JPA_NAMED_QUERY_SELECT_SUBSCRIPTIONS_FROM_NOTIFIER_AND_EVENTPACKAGE = JPA_NAMED_QUERY_PREFIX + "selectSubscriptionsFromNotifierAndEventPackage"; public static final String JPA_NAMED_QUERY_SELECT_SUBSCRIPTIONS_FROM_NOTIFIER = JPA_NAMED_QUERY_PREFIX + "selectSubscriptionsFromNotifier"; public static final String JPA_NAMED_QUERY_SELECT_SUBSCRIPTIONS_FROM_NOTIFIER_WITH_PARAMS = JPA_NAMED_QUERY_PREFIX + "selectSubscriptionsFromNotifierWithParams"; public static final String JPA_NAMED_QUERY_SELECT_DIALOG_SUBSCRIPTIONS = JPA_NAMED_QUERY_PREFIX + "selectDialogSubscriptions"; /** * the subscription key */ @EmbeddedId protected SubscriptionKey key; /** * the subscriber */ @Column(name = "SUBSCRIBER",nullable=false) private String subscriber; /** * the notifier */ @Column(name = "NOTIFER",nullable=false) private String notifier; /** * the notifier uri params */ @Column(name = "NOTIFER_PARAMS",nullable=true) private String notifierParams; /** * the current status of the subscription */ public enum Status { active, pending, waiting, terminated; } @Column(name = "STATUS", nullable = false) private Status status; /** * the date when this subscription was created */ @Column(name = "CREATION_DATE", nullable = false) private long creationDate; // subscription's date of creation /** * the last time this subscription was refreshed */ @Column(name = "LAST_REFRESH_DATE", nullable = false) private long lastRefreshDate; // last time this subscription was refreshed /** * seconds to expire the subscription, after creation/last refresh */ @Column(name = "EXPIRES", nullable = false) private int expires; // seconds to expire /** * display name of the subscriber */ @Column(name = "SUBSCRIBER_DISPLAY_NAME", nullable = true) private String subscriberDisplayName; // the display name of the subscriber in a sip header /** * last event that occurred in the subscription */ public enum Event { noresource, rejected, deactivated, probation, timeout, approved, giveup, subscribe } @Column(name = "LAST_EVENT", nullable = true) private Event lastEvent; /** * the id of the SLEE timer associated with this subscription */ @Column(name = "TIMER_ID", nullable = true) private TimerID timerID; /** * the version of the last content, this only applies to WInfo or RLS subscriptions */ @Column(name = "VERSION", nullable = false) private int version; /** * if true the subscription if for a resource list */ @Column(name = "RESOURCE_LIST", nullable = false) private Boolean resourceList; /** * the entity manager used to load and persist this subscription */ @Transient private EntityManager entityManager; /** * notifier uri with params */ @Transient private String notifierWithParams; /** * */ public Subscription() { } /** * * @param key * @param subscriber * @param notifier * @param status * @param subscriberDisplayName * @param expires * @param resourceList */ public Subscription(SubscriptionKey key, String subscriber, String notifier, Status status, String subscriberDisplayName, int expires, boolean resourceList) { this.key = key; this.subscriber = subscriber; int index = notifier.indexOf(';'); this.notifierWithParams = notifier; if (index > 0) { this.notifier = notifier.substring(0,index); this.notifierParams = notifier.substring(index); } else { this.notifier = notifier; this.notifierParams = null; } this.status = status; if (status.equals(Status.active)){ this.lastEvent = Event.approved; } else if (status.equals(Status.pending)) { this.lastEvent = Event.subscribe; } this.creationDate = System.currentTimeMillis(); this.lastRefreshDate = creationDate; this.expires = expires; this.subscriberDisplayName = subscriberDisplayName; this.version = 0; this.resourceList = Boolean.valueOf(resourceList); } public int getRemainingExpires() { long remainingExpires = expires - (System.currentTimeMillis()-lastRefreshDate) / 1000; if (remainingExpires < 0) { return 0; } else { return (int) remainingExpires; } } public int getSubscriptionDuration() { return (int) ((System.currentTimeMillis() - creationDate) / 1000); } public void refresh(int expires) { lastRefreshDate = System.currentTimeMillis(); this.expires = expires; } public boolean changeStatus(Event event) { // implements subscription state machine Status oldStatus = status; if (status == Status.active) { if (event == Event.noresource || event == Event.rejected || event == Event.deactivated || event == Event.probation || event == Event.timeout) { status = Status.terminated; } } else if (status == Status.pending) { if (event == Event.approved) { status = Status.active; } else if (event == Event.timeout) { status = Status.waiting; } else if (event == Event.noresource || event == Event.rejected || event == Event.deactivated || event == Event.probation || event == Event.giveup) { status = Status.terminated; } } else if (status == Status.waiting) { if (event == Event.noresource || event == Event.rejected || event == Event.giveup || event == Event.approved) { status = Status.terminated; } } if (status != oldStatus) { lastEvent = event; return true; } else { return false; } } @Override public int hashCode() { return key.hashCode(); } @Override public boolean equals(Object obj) { if (obj != null && obj.getClass() == this.getClass()) { return ((Subscription)obj).key.equals(this.key); } else { return false; } } // -- GETTERS AND SETTERS public SubscriptionKey getKey() { return key; } public void setKey(SubscriptionKey key) { this.key = key; } public String getSubscriber() { return subscriber; } public void setSubscriber(String subscriber) { this.subscriber = subscriber; } public String getNotifier() { return notifier; } public void setNotifier(String notifier) { this.notifier = notifier; } public String getNotifierParams() { return notifierParams; } public void setNotifierParams(String notifierParams) { this.notifierParams = notifierParams; } public String getNotifierWithParams() { if (notifierWithParams == null) { if (notifierParams == null) { notifierWithParams = notifier; } else { notifierWithParams = notifier + notifierParams; } } return notifierWithParams; } public Status getStatus() { return status; } public void setStatus(Status status) { this.status = status; } public long getCreationDate() { return creationDate; } public void setCreationDate(long creationDate) { this.creationDate = creationDate; } public long getLastRefreshDate() { return lastRefreshDate; } public void setLastRefreshDate(long lastRefreshDate) { this.lastRefreshDate = lastRefreshDate; } public int getExpires() { return expires; } public void setExpires(int expires) { this.expires = expires; } public String getSubscriberDisplayName() { return subscriberDisplayName; } public void setSubscriberDisplayName(String subscriberDisplayName) { this.subscriberDisplayName = subscriberDisplayName; } public Event getLastEvent() { return lastEvent; } public void setLastEvent(Event lastEvent) { this.lastEvent = lastEvent; } public TimerID getTimerID() { return timerID; } public void setTimerID(TimerID timerID) { this.timerID = timerID; } public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } public void incrementVersion() { this.version++; } public Boolean getResourceList() { return resourceList; } public void setResourceList(Boolean resourceList) { this.resourceList = resourceList; } @Override public String toString() { return "subscription: subscriber="+subscriber+",notifier="+notifier+",resourceList="+resourceList+",eventPackage="+key.getEventPackage()+",eventId="+key.getRealEventId()+",status="+status; } /* * loads subscription pojo from persistence */ public static Subscription getSubscription(EntityManager entityManager, String callId, String remoteTag, String eventPackage, String eventId) { return (Subscription) entityManager.find(Subscription.class, new SubscriptionKey(callId, remoteTag, eventPackage, eventId)); } /** * retrieves subscriptions associated with the specified dialog * @param entityManager * @param dialog * @return */ public static List<?> getDialogSubscriptions(EntityManager entityManager, String callId, String remoteTag) { return entityManager.createNamedQuery(JPA_NAMED_QUERY_SELECT_DIALOG_SUBSCRIPTIONS) .setParameter("callId",callId) .setParameter("remoteTag",remoteTag) .getResultList(); } public EntityManager getEntityManager() { return entityManager; } public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } }