tom

Adding event sink & dispatcher abstractions.

Increased strength of the provider & service types.
1 +package org.onlab.onos.event;
2 +
3 +import com.google.common.collect.ImmutableSet;
4 +
5 +import java.util.Map;
6 +import java.util.Set;
7 +import java.util.concurrent.ConcurrentHashMap;
8 +
9 +import static com.google.common.base.Preconditions.checkArgument;
10 +import static com.google.common.base.Preconditions.checkNotNull;
11 +
12 +/**
13 + * Base implementation of event sink broker.
14 + */
15 +public class AbstractEventSinkBroker implements EventSinkBroker {
16 +
17 + private final Map<Class<? extends Event>, EventSink<? extends Event>> sinks =
18 + new ConcurrentHashMap<>();
19 +
20 + @Override
21 + public <E extends Event> void addSink(Class<E> eventClass, EventSink<E> sink) {
22 + checkNotNull(eventClass, "Event class cannot be null");
23 + checkNotNull(sink, "Event sink cannot be null");
24 + checkArgument(!sinks.containsKey(eventClass),
25 + "Event sink already registered for %s", eventClass.getName());
26 + sinks.put(eventClass, sink);
27 + }
28 +
29 + @Override
30 + public <E extends Event> void removeSink(Class<E> eventClass) {
31 + checkNotNull(eventClass, "Event class cannot be null");
32 + checkArgument(sinks.remove(eventClass) != null,
33 + "Event sink not registered for %s", eventClass.getName());
34 + }
35 +
36 + @Override
37 + @SuppressWarnings("unchecked")
38 + public <E extends Event> EventSink<E> getSink(Class<E> eventClass) {
39 + return (EventSink<E>) sinks.get(eventClass);
40 + }
41 +
42 + @Override
43 + public Set<Class<? extends Event>> getSinks() {
44 + return ImmutableSet.copyOf(sinks.keySet());
45 + }
46 +}
1 +package org.onlab.onos.event;
2 +
3 +import org.slf4j.Logger;
4 +import org.slf4j.LoggerFactory;
5 +
6 +import java.util.Set;
7 +import java.util.concurrent.CopyOnWriteArraySet;
8 +
9 +import static com.google.common.base.Preconditions.checkArgument;
10 +import static com.google.common.base.Preconditions.checkNotNull;
11 +
12 +/**
13 + * Base implementation of a manager capable of tracking listeners and
14 + * dispatching events to them.
15 + */
16 +public class AbstractListenerManager<E extends Event, L extends EventListener<E>>
17 + implements EventSink<E> {
18 +
19 + protected Logger log = LoggerFactory.getLogger(AbstractListenerManager.class);
20 +
21 + private final Set<L> listeners = new CopyOnWriteArraySet<>();
22 +
23 + /**
24 + * Adds the specified listener.
25 + *
26 + * @param listener listener to be added
27 + */
28 + public void addListener(L listener) {
29 + checkNotNull(listener, "Listener cannot be null");
30 + listeners.add(listener);
31 + }
32 +
33 + /**
34 + * Removes the specified listener.
35 + *
36 + * @param listener listener to be removed
37 + */
38 + public void removeListener(L listener) {
39 + checkNotNull(listener, "Listener cannot be null");
40 + checkArgument(listeners.remove(listener), "Listener not registered");
41 + }
42 +
43 + @Override
44 + public void process(E event) {
45 + for (L listener : listeners) {
46 + try {
47 + listener.event(event);
48 + } catch (Throwable error) {
49 + reportProblem(event, error);
50 + }
51 + }
52 + }
53 +
54 + @Override
55 + public void reportProblem(E event, Throwable error) {
56 + log.warn("Exception encountered while processing event " + event, error);
57 + }
58 +
59 +}
1 +package org.onlab.onos.event;
2 +
3 +/**
4 + * Abstraction of a mechanism capable of accepting and dispatching events.
5 + * Whether the events are accepted and the dispatched synchronously or
6 + * asynchronously is unspecified.
7 + */
8 +public interface EventDispatcher<E extends Event> {
9 +
10 + /**
11 + * Posts the specified event for dispatching.
12 + *
13 + * @param event event to be posted
14 + */
15 + void post(E event);
16 +
17 +}
1 +package org.onlab.onos.event;
2 +
3 +/**
4 + * Abstraction of an event sink capable of processing the specified event types.
5 + */
6 +public interface EventSink<E extends Event> {
7 +
8 + /**
9 + * Processes the specified event.
10 + *
11 + * @param event event to be processed
12 + */
13 + void process(E event);
14 +
15 + /**
16 + * Reports a problem encountered while processing an event.
17 + *
18 + * @param event event being processed
19 + * @param error error encountered while processing
20 + */
21 + void reportProblem(E event, Throwable error);
22 +
23 +}
1 +package org.onlab.onos.event;
2 +
3 +import java.util.Set;
4 +
5 +/**
6 + * Abstraction of an event sink broker capable of tracking sinks based on
7 + * their event class.
8 + */
9 +public interface EventSinkBroker {
10 +
11 + /**
12 + * Adds the specified sink for the given event class.
13 + *
14 + * @param eventClass event class
15 + * @param sink event sink
16 + * @param <E> type of event
17 + */
18 + <E extends Event> void addSink(Class<E> eventClass, EventSink<E> sink);
19 +
20 + /**
21 + * Removes the sink associated with the given event class.
22 + *
23 + * @param eventClass event class
24 + * @param <E> type of event
25 + */
26 + <E extends Event> void removeSink(Class<E> eventClass);
27 +
28 + /**
29 + * Returns the event sink associated with the specified event class.
30 + *
31 + * @param eventClass event class
32 + * @param <E> type of event
33 + * @return event sink or null if none found
34 + */
35 + <E extends Event> EventSink<E> getSink(Class<E> eventClass);
36 +
37 + /**
38 + * Returns the set of all event classes for which sinks are presently
39 + * registered.
40 + *
41 + * @return set of event classes
42 + */
43 + Set<Class<? extends Event>> getSinks();
44 +
45 +}
...@@ -9,7 +9,7 @@ import java.util.List; ...@@ -9,7 +9,7 @@ import java.util.List;
9 * Service through which device providers can inject device information into 9 * Service through which device providers can inject device information into
10 * the core. 10 * the core.
11 */ 11 */
12 -public interface DeviceProviderService extends ProviderService { 12 +public interface DeviceProviderService extends ProviderService<DeviceProvider> {
13 13
14 // TODO: define suspend and remove actions on the mezzanine administrative API 14 // TODO: define suspend and remove actions on the mezzanine administrative API
15 15
......
...@@ -6,7 +6,7 @@ import org.onlab.onos.net.provider.ProviderService; ...@@ -6,7 +6,7 @@ import org.onlab.onos.net.provider.ProviderService;
6 * Service through which flowrule providers can inject flowrule information into 6 * Service through which flowrule providers can inject flowrule information into
7 * the core. 7 * the core.
8 */ 8 */
9 -public interface FlowRuleProviderService extends ProviderService { 9 +public interface FlowRuleProviderService extends ProviderService<FlowRuleProvider> {
10 10
11 /** 11 /**
12 * Signals that a flow that was previously installed has been removed. 12 * Signals that a flow that was previously installed has been removed.
......
...@@ -5,7 +5,7 @@ import org.onlab.onos.net.provider.ProviderService; ...@@ -5,7 +5,7 @@ import org.onlab.onos.net.provider.ProviderService;
5 /** 5 /**
6 * Means of conveying host information to the core. 6 * Means of conveying host information to the core.
7 */ 7 */
8 -public interface HostProviderService extends ProviderService { 8 +public interface HostProviderService extends ProviderService<HostProvider> {
9 9
10 /** 10 /**
11 * Notifies the core when a host has been detected on a network along with 11 * Notifies the core when a host has been detected on a network along with
......
...@@ -5,7 +5,7 @@ import org.onlab.onos.net.provider.ProviderService; ...@@ -5,7 +5,7 @@ import org.onlab.onos.net.provider.ProviderService;
5 /** 5 /**
6 * Means for injecting link information into the core. 6 * Means for injecting link information into the core.
7 */ 7 */
8 -public interface LinkProviderService extends ProviderService { 8 +public interface LinkProviderService extends ProviderService<LinkProvider> {
9 9
10 /** 10 /**
11 * Signals that an infrastructure link has been connected. 11 * Signals that an infrastructure link has been connected.
......
...@@ -12,7 +12,7 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -12,7 +12,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
12 * @param <P> type of the information provider 12 * @param <P> type of the information provider
13 * @param <S> type of the provider service 13 * @param <S> type of the provider service
14 */ 14 */
15 -public abstract class AbstractProviderBroker<P extends Provider, S extends ProviderService> 15 +public abstract class AbstractProviderBroker<P extends Provider, S extends ProviderService<P>>
16 implements ProviderBroker<P, S> { 16 implements ProviderBroker<P, S> {
17 17
18 private final Map<ProviderId, S> services = new HashMap<>(); 18 private final Map<ProviderId, S> services = new HashMap<>();
......
...@@ -5,7 +5,7 @@ import org.onlab.onos.net.provider.ProviderService; ...@@ -5,7 +5,7 @@ import org.onlab.onos.net.provider.ProviderService;
5 /** 5 /**
6 * Means for injecting topology information into the core. 6 * Means for injecting topology information into the core.
7 */ 7 */
8 -public interface TopologyProviderService extends ProviderService { 8 +public interface TopologyProviderService extends ProviderService<TopologyProvider> {
9 9
10 // What can be conveyed in a topology that isn't by individual 10 // What can be conveyed in a topology that isn't by individual
11 // providers? 11 // providers?
......