/******************************************************************************* * Mission Control Technologies, Copyright (c) 2009-2012, United States Government * as represented by the Administrator of the National Aeronautics and Space * Administration. All rights reserved. * * The MCT platform is licensed under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * MCT includes source code licensed under additional open source licenses. See * the MCT Open Source Licenses file included with this distribution or the About * MCT Licenses dialog available at runtime from the MCT Help menu for additional * information. *******************************************************************************/ package gov.nasa.arc.mct.subscribe.manager; import gov.nasa.arc.mct.subscribe.manager.config.ConfigurationService; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.TreeSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class UnsubscriptionTimer extends Timer { private static final Logger LOGGER = LoggerFactory .getLogger(UnsubscriptionTimer.class); private TreeSet<UnsubscriptionContext> unsubscriptionList = new TreeSet<UnsubscriptionContext>( new Comparator<UnsubscriptionContext>() { public int compare(UnsubscriptionContext o1, UnsubscriptionContext o2) { if (o1.timeToUnsubscribeInMills < o2.timeToUnsubscribeInMills) { return -1; } if (o1.timeToUnsubscribeInMills == o2.timeToUnsubscribeInMills) { return o1.equals(o2) ? 0 : System.identityHashCode(o2) - System.identityHashCode(o1); } return 1; } }); private Map<String, UnsubscriptionContext> unsubcriptionListIndex = new HashMap<String, UnsubscriptionContext>(); private final int timerSleepTime; private final SubscriptionManagerService subscriptionManager; UnsubscriptionTimer(SubscriptionManagerService subscriptionManager) { super("Unsubscription Timer"); this.timerSleepTime = ConfigurationService.getInstance() .getTimerSleepTime(); this.subscriptionManager = subscriptionManager; } void addEligibleUnsubscriber(String feedID) { synchronized (subscriptionManager) { if (!unsubcriptionListIndex.containsKey(feedID)) { UnsubscriptionContext uc = new UnsubscriptionContext(feedID); unsubscriptionList.add(uc); unsubcriptionListIndex.put(feedID, uc); } } } boolean removeEligibleUnsubscriber(String feedID) { synchronized (subscriptionManager) { UnsubscriptionContext uc = unsubcriptionListIndex.remove(feedID); return uc != null && unsubscriptionList.remove(uc); } } public void schedule() { synchronized (subscriptionManager) { super.scheduleAtFixedRate(new TimerTask() { @Override public void run() { synchronized (subscriptionManager) { for (Iterator<UnsubscriptionContext> i = unsubscriptionList .iterator(); i.hasNext();) { UnsubscriptionContext uc = i.next(); if (!uc.isTimeToUnsubscribe()) { break; } String feedID = uc.feedID; LOGGER.debug( "removing...{} from unsubscription list.", uc); subscriptionManager.unsubscribeFromFeeds(feedID); i.remove(); unsubcriptionListIndex.remove(feedID); } } // call SubscriptionManager } }, timerSleepTime, timerSleepTime); } } private final static class UnsubscriptionContext { private final long timeToUnsubscribeInMills; private final String feedID; public UnsubscriptionContext(String feedID) { int unsubscriptionGracePeriod = ConfigurationService.getInstance() .getUnSubscriptionGracePeriod(); this.feedID = feedID; this.timeToUnsubscribeInMills = unsubscriptionGracePeriod + System.currentTimeMillis(); } public boolean isTimeToUnsubscribe() { return System.currentTimeMillis() > timeToUnsubscribeInMills; } @Override public boolean equals(Object obj) { return obj instanceof UnsubscriptionContext && feedID.equals(((UnsubscriptionContext) obj).feedID); } @Override public int hashCode() { return feedID.hashCode(); } @Override public String toString() { return feedID; } } }