blob: 7df0b3cb1cbf3500e1d84b15194f297ec00b8e6a [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
tom94bb4a42014-08-27 22:12:02 -070016package org.onlab.onos.event.impl;
17
tom5f38b3a2014-08-27 23:50:54 -070018import org.apache.felix.scr.annotations.Activate;
tom94bb4a42014-08-27 22:12:02 -070019import org.apache.felix.scr.annotations.Component;
tom5f38b3a2014-08-27 23:50:54 -070020import org.apache.felix.scr.annotations.Deactivate;
tom94bb4a42014-08-27 22:12:02 -070021import org.apache.felix.scr.annotations.Service;
tom5f38b3a2014-08-27 23:50:54 -070022import org.onlab.onos.event.AbstractEvent;
tom96dfcab2014-08-28 09:26:03 -070023import org.onlab.onos.event.DefaultEventSinkRegistry;
tom94bb4a42014-08-27 22:12:02 -070024import org.onlab.onos.event.Event;
tom96dfcab2014-08-28 09:26:03 -070025import org.onlab.onos.event.EventDeliveryService;
tom94bb4a42014-08-27 22:12:02 -070026import org.onlab.onos.event.EventSink;
tom5f38b3a2014-08-27 23:50:54 -070027import org.slf4j.Logger;
tom94bb4a42014-08-27 22:12:02 -070028
tom5f38b3a2014-08-27 23:50:54 -070029import java.util.concurrent.BlockingQueue;
tom94bb4a42014-08-27 22:12:02 -070030import java.util.concurrent.ExecutorService;
tom5f38b3a2014-08-27 23:50:54 -070031import java.util.concurrent.LinkedBlockingQueue;
32
33import static java.util.concurrent.Executors.newSingleThreadExecutor;
34import static org.onlab.util.Tools.namedThreads;
35import static org.slf4j.LoggerFactory.getLogger;
tom94bb4a42014-08-27 22:12:02 -070036
37/**
38 * Simple implementation of an event dispatching service.
39 */
40@Component(immediate = true)
41@Service
tom202175a2014-09-19 19:00:11 -070042public class CoreEventDispatcher extends DefaultEventSinkRegistry
tom96dfcab2014-08-28 09:26:03 -070043 implements EventDeliveryService {
tom94bb4a42014-08-27 22:12:02 -070044
tom5f38b3a2014-08-27 23:50:54 -070045 private final Logger log = getLogger(getClass());
46
47 private final ExecutorService executor =
48 newSingleThreadExecutor(namedThreads("event-dispatch-%d"));
49
50 @SuppressWarnings("unchecked")
51 private static final Event KILL_PILL = new AbstractEvent(null, 0) {
52 };
53
54 private final BlockingQueue<Event> events = new LinkedBlockingQueue<>();
55
56 private volatile boolean stopped = false;
tom94bb4a42014-08-27 22:12:02 -070057
58 @Override
59 public void post(Event event) {
tom5f38b3a2014-08-27 23:50:54 -070060 events.add(event);
tom94bb4a42014-08-27 22:12:02 -070061 }
62
tom5f38b3a2014-08-27 23:50:54 -070063 @Activate
64 public void activate() {
65 stopped = false;
66 executor.execute(new DispatchLoop());
67 log.info("Started");
tom94bb4a42014-08-27 22:12:02 -070068 }
69
tom5f38b3a2014-08-27 23:50:54 -070070 @Deactivate
71 public void deactivate() {
72 stopped = true;
73 post(KILL_PILL);
74 log.info("Stopped");
tom94bb4a42014-08-27 22:12:02 -070075 }
76
tom5f38b3a2014-08-27 23:50:54 -070077 // Auxiliary event dispatching loop that feeds off the events queue.
78 private class DispatchLoop implements Runnable {
79 @Override
80 @SuppressWarnings("unchecked")
81 public void run() {
82 log.info("Dispatch loop initiated");
83 while (!stopped) {
84 try {
85 // Fetch the next event and if it is the kill-pill, bail
86 Event event = events.take();
87 if (event == KILL_PILL) {
88 break;
89 }
90
91 // Locate the sink for the event class and use it to
92 // process the event
93 EventSink sink = getSink(event.getClass());
94 if (sink != null) {
95 sink.process(event);
96 } else {
97 log.warn("No sink registered for event class {}",
98 event.getClass());
99 }
tom19bf4212014-08-29 13:08:29 -0700100 } catch (Exception e) {
tom5f38b3a2014-08-27 23:50:54 -0700101 log.warn("Error encountered while dispatching event:", e);
102 }
103 }
104 log.info("Dispatch loop terminated");
105 }
tom94bb4a42014-08-27 22:12:02 -0700106 }
107
tom94bb4a42014-08-27 22:12:02 -0700108}