/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ package org.apache.brooklyn.core.mgmt.internal; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.mgmt.SubscriptionHandle; import org.apache.brooklyn.api.sensor.Sensor; import org.apache.brooklyn.api.sensor.SensorEvent; import com.google.common.base.Objects; @SuppressWarnings("rawtypes") public class QueueingSubscriptionManager extends AbstractSubscriptionManager { static class QueuedSubscription<T> { Map<String, Object> flags; Subscription<T> s; } public AbstractSubscriptionManager delegate = null; public boolean useDelegateForSubscribing = false; public boolean useDelegateForPublishing = false; List<QueuedSubscription> queuedSubscriptions = new ArrayList<QueuedSubscription>(); List<SensorEvent> queuedSensorEvents = new ArrayList<SensorEvent>(); @Override protected synchronized <T> SubscriptionHandle subscribe(Map<String, Object> flags, Subscription<T> s) { if (useDelegateForSubscribing) return delegate.subscribe(flags, s); QueuedSubscription<T> qs = new QueuedSubscription<T>(); qs.flags = flags; s.subscriber = getSubscriber(flags, s); qs.s = s; queuedSubscriptions.add(qs); return s; } @Override public synchronized <T> void publish(SensorEvent<T> event) { if (useDelegateForPublishing) { delegate.publish(event); return; } queuedSensorEvents.add(event); } public void setDelegate(AbstractSubscriptionManager delegate) { this.delegate = delegate; } @SuppressWarnings("unchecked") public synchronized void startDelegatingForSubscribing() { assert delegate!=null; for (QueuedSubscription s: queuedSubscriptions) { delegate.subscribe(s.flags, s.s); } queuedSubscriptions.clear(); useDelegateForSubscribing = true; } @SuppressWarnings("unchecked") public synchronized void startDelegatingForPublishing() { assert delegate!=null; for (SensorEvent evt: queuedSensorEvents) { delegate.publish(evt); } queuedSensorEvents.clear(); useDelegateForPublishing = true; } public synchronized void stopDelegatingForSubscribing() { useDelegateForSubscribing = false; } public synchronized void stopDelegatingForPublishing() { useDelegateForPublishing = false; } @Override public synchronized boolean unsubscribe(SubscriptionHandle subscriptionId) { if (useDelegateForSubscribing) return delegate.unsubscribe(subscriptionId); Iterator<QueuedSubscription> qi = queuedSubscriptions.iterator(); while (qi.hasNext()) { QueuedSubscription q = qi.next(); if (Objects.equal(subscriptionId, q.s)) { qi.remove(); return true; } } return false; } @SuppressWarnings("unchecked") @Override public synchronized Set<SubscriptionHandle> getSubscriptionsForSubscriber(Object subscriber) { if (useDelegateForSubscribing) return delegate.getSubscriptionsForSubscriber(subscriber); Set<SubscriptionHandle> result = new LinkedHashSet<SubscriptionHandle>(); for (QueuedSubscription q: queuedSubscriptions) { if (Objects.equal(subscriber, getSubscriber(q.flags, q.s))) result.add(q.s); } return result; } @Override public synchronized Set<SubscriptionHandle> getSubscriptionsForEntitySensor(Entity source, Sensor<?> sensor) { if (useDelegateForSubscribing) return delegate.getSubscriptionsForEntitySensor(source, sensor); Set<SubscriptionHandle> result = new LinkedHashSet<SubscriptionHandle>(); for (QueuedSubscription q: queuedSubscriptions) { if ((q.s.sensor==null || Objects.equal(q.s.sensor, sensor)) && (q.s.producer==null || Objects.equal(q.s.producer, sensor))) result.add(q.s); } return result; } }