blob: b5ee31687a46d8ee70dda4906d96e56335968dbe [file] [log] [blame]
HIGUCHI Yuta9092db82016-01-03 18:45:01 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
HIGUCHI Yuta9092db82016-01-03 18:45:01 -08003 *
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 */
16package org.onosproject.events;
17
18import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
19import static org.onlab.util.Tools.groupedThreads;
20import static org.onlab.util.Tools.minPriority;
21
22import java.util.Deque;
23import java.util.concurrent.ConcurrentLinkedDeque;
24import java.util.concurrent.ScheduledExecutorService;
25import java.util.concurrent.TimeUnit;
26
27import org.apache.felix.scr.annotations.Activate;
28import org.apache.felix.scr.annotations.Component;
29import org.apache.felix.scr.annotations.Deactivate;
30import org.apache.felix.scr.annotations.Property;
31import org.apache.felix.scr.annotations.Reference;
32import org.apache.felix.scr.annotations.ReferenceCardinality;
33import org.apache.felix.scr.annotations.Service;
34import org.onlab.util.UnmodifiableDeque;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080035import org.onosproject.cluster.ClusterService;
36import org.onosproject.core.ApplicationId;
37import org.onosproject.core.CoreService;
38import org.onosproject.event.Event;
39import org.onosproject.event.ListenerTracker;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080040import org.onosproject.mastership.MastershipService;
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -080041import org.onosproject.net.config.NetworkConfigService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080042import org.onosproject.net.device.DeviceEvent;
43import org.onosproject.net.device.DeviceListener;
44import org.onosproject.net.device.DeviceService;
Yuta HIGUCHI4e3af862016-07-21 16:03:34 -070045import org.onosproject.net.edge.EdgePortService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080046import org.onosproject.net.host.HostService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080047import org.onosproject.net.link.LinkService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080048import org.onosproject.net.topology.TopologyService;
49import org.slf4j.Logger;
50import org.slf4j.LoggerFactory;
51
52/**
53 * Application to store history of instance local ONOS Events.
54 */
55@Component(immediate = true)
56@Service
57public class EventHistoryManager
58 implements EventHistoryService {
59
60 private final Logger log = LoggerFactory.getLogger(getClass());
61
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected CoreService coreService;
64
65 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 protected MastershipService mastershipService;
67
68 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 protected DeviceService deviceService;
70
71 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 protected LinkService linkService;
73
74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 protected TopologyService topologyService;
76
77 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78 protected HostService hostService;
79
80 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
81 protected ClusterService clusterService;
82
Yuta HIGUCHI4e3af862016-07-21 16:03:34 -070083 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84 protected EdgePortService edgeService;
85
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -080086 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 protected NetworkConfigService netcfgService;
88
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080089 @Property(name = "excludeStatsEvent", boolValue = true,
90 label = "Exclude stats related events")
91 private boolean excludeStatsEvent = true;
92
93 @Property(name = "sizeLimit", intValue = 10_000,
94 label = "Number of event history to store")
95 private int sizeLimit = 10_000;
96
97 private ApplicationId appId;
98
99 private ListenerTracker listeners;
100
101 // Using Deque so that it'll be possible to iterate from both ends
102 // (Tail-end is the most recent event)
103 private final Deque<Event<?, ?>> history = new ConcurrentLinkedDeque<>();
104
105 private ScheduledExecutorService pruner;
106
107 // pruneEventHistoryTask() execution interval in seconds
108 private long pruneInterval = 5;
109
110
111 @Activate
112 protected void activate() {
113 appId = coreService.registerApplication("org.onosproject.events");
114 log.debug("Registered as {}", appId);
115
HIGUCHI Yuta060da9a2016-03-11 19:16:35 -0800116 pruner = newSingleThreadScheduledExecutor(
117 minPriority(groupedThreads("onos/events", "history-pruner", log)));
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800118
119 pruner.scheduleWithFixedDelay(this::pruneEventHistoryTask,
Jian Li68c4fc42016-01-11 16:07:03 -0800120 pruneInterval, pruneInterval, TimeUnit.SECONDS);
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800121
122 listeners = new ListenerTracker();
Yuta HIGUCHId90dbc92016-08-04 18:35:21 -0700123 listeners.addListener(mastershipService, this::addEvent)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800124 .addListener(deviceService, new InternalDeviceListener())
Yuta HIGUCHId90dbc92016-08-04 18:35:21 -0700125 .addListener(linkService, this::addEvent)
126 .addListener(topologyService, this::addEvent)
127 .addListener(hostService, this::addEvent)
128 .addListener(clusterService, this::addEvent)
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -0800129 .addListener(edgeService, this::addEvent)
130 .addListener(netcfgService, this::addEvent);
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800131
132 log.info("Started");
133 }
134
135 @Deactivate
136 protected void deactivate() {
137 listeners.removeListeners();
138
139 pruner.shutdownNow();
140 history.clear();
141
142 log.info("Stopped");
143 }
144
145 @Override
146 public Deque<Event<?, ?>> history() {
147 return UnmodifiableDeque.unmodifiableDeque(history);
148 }
149
150 @Override
151 public void clear() {
152 history.clear();
153 }
154
155 // This method assumes only 1 call is in flight at the same time.
156 private void pruneEventHistoryTask() {
157 int size = history.size();
158 int overflows = size - sizeLimit;
159 if (overflows > 0) {
160 for (int i = 0; i < overflows; ++i) {
161 history.poll();
162 }
163 }
164 }
165
166 private void addEvent(Event<?, ?> event) {
167 history.offer(event);
168 }
169
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800170 class InternalDeviceListener
171 implements DeviceListener {
172
173 @Override
174 public boolean isRelevant(DeviceEvent event) {
175 if (excludeStatsEvent) {
176 return event.type() != DeviceEvent.Type.PORT_STATS_UPDATED;
177 } else {
178 return true;
179 }
180 }
181
182 @Override
183 public void event(DeviceEvent event) {
184 addEvent(event);
185 }
186 }
187
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800188}