blob: f99dd153a61c1877f408adcd4e3194b2ee401a12 [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
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080018import org.onlab.util.UnmodifiableDeque;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080019import org.onosproject.cluster.ClusterService;
20import org.onosproject.core.ApplicationId;
21import org.onosproject.core.CoreService;
22import org.onosproject.event.Event;
23import org.onosproject.event.ListenerTracker;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080024import org.onosproject.mastership.MastershipService;
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -080025import org.onosproject.net.config.NetworkConfigService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080026import org.onosproject.net.device.DeviceEvent;
27import org.onosproject.net.device.DeviceListener;
28import org.onosproject.net.device.DeviceService;
Yuta HIGUCHI4e3af862016-07-21 16:03:34 -070029import org.onosproject.net.edge.EdgePortService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080030import org.onosproject.net.host.HostService;
Jon Halld66228c2017-08-09 11:24:24 -070031import org.onosproject.net.intent.IntentService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080032import org.onosproject.net.link.LinkService;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080033import org.onosproject.net.topology.TopologyService;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070034import org.osgi.service.component.annotations.Activate;
35import org.osgi.service.component.annotations.Component;
36import org.osgi.service.component.annotations.Deactivate;
37import org.osgi.service.component.annotations.Reference;
38import org.osgi.service.component.annotations.ReferenceCardinality;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080039import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
41
Ray Milkeyd84f89b2018-08-17 14:54:17 -070042import java.util.Deque;
43import java.util.concurrent.ConcurrentLinkedDeque;
44import java.util.concurrent.ScheduledExecutorService;
45import java.util.concurrent.TimeUnit;
46
47import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
48import static org.onlab.util.Tools.groupedThreads;
49import static org.onlab.util.Tools.minPriority;
Ray Milkey4694e062018-10-31 13:17:18 -070050import static org.onosproject.events.OsgiPropertyConstants.EXCLUDE_STATS_EVENT;
51import static org.onosproject.events.OsgiPropertyConstants.EXCLUDE_STATS_EVENT_DEFAULT;
52import static org.onosproject.events.OsgiPropertyConstants.SIZE_LIMIT;
53import static org.onosproject.events.OsgiPropertyConstants.SIZE_LIMIT_DEFAULT;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070054
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080055/**
56 * Application to store history of instance local ONOS Events.
57 */
Ray Milkey4694e062018-10-31 13:17:18 -070058@Component(
59 immediate = true,
60 service = EventHistoryService.class,
61 property = {
62 EXCLUDE_STATS_EVENT + "=" + EXCLUDE_STATS_EVENT_DEFAULT,
63 SIZE_LIMIT + "=" + SIZE_LIMIT_DEFAULT
64 }
65)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080066public class EventHistoryManager
67 implements EventHistoryService {
68
69 private final Logger log = LoggerFactory.getLogger(getClass());
70
Ray Milkeyd84f89b2018-08-17 14:54:17 -070071 @Reference(cardinality = ReferenceCardinality.MANDATORY)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080072 protected CoreService coreService;
73
Ray Milkeyd84f89b2018-08-17 14:54:17 -070074 @Reference(cardinality = ReferenceCardinality.MANDATORY)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080075 protected MastershipService mastershipService;
76
Ray Milkeyd84f89b2018-08-17 14:54:17 -070077 @Reference(cardinality = ReferenceCardinality.MANDATORY)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080078 protected DeviceService deviceService;
79
Ray Milkeyd84f89b2018-08-17 14:54:17 -070080 @Reference(cardinality = ReferenceCardinality.MANDATORY)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080081 protected LinkService linkService;
82
Ray Milkeyd84f89b2018-08-17 14:54:17 -070083 @Reference(cardinality = ReferenceCardinality.MANDATORY)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080084 protected TopologyService topologyService;
85
Ray Milkeyd84f89b2018-08-17 14:54:17 -070086 @Reference(cardinality = ReferenceCardinality.MANDATORY)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080087 protected HostService hostService;
88
Ray Milkeyd84f89b2018-08-17 14:54:17 -070089 @Reference(cardinality = ReferenceCardinality.MANDATORY)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -080090 protected ClusterService clusterService;
91
Ray Milkeyd84f89b2018-08-17 14:54:17 -070092 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yuta HIGUCHI4e3af862016-07-21 16:03:34 -070093 protected EdgePortService edgeService;
94
Ray Milkeyd84f89b2018-08-17 14:54:17 -070095 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jon Halld66228c2017-08-09 11:24:24 -070096 protected IntentService intentService;
97
Ray Milkeyd84f89b2018-08-17 14:54:17 -070098 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -080099 protected NetworkConfigService netcfgService;
100
Ray Milkey4694e062018-10-31 13:17:18 -0700101 /** Exclude stats related events. */
102 private boolean excludeStatsEvent = EXCLUDE_STATS_EVENT_DEFAULT;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800103
Ray Milkey4694e062018-10-31 13:17:18 -0700104 /** Number of event history to store. */
105 private int sizeLimit = SIZE_LIMIT_DEFAULT;
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800106
107 private ApplicationId appId;
108
109 private ListenerTracker listeners;
110
111 // Using Deque so that it'll be possible to iterate from both ends
112 // (Tail-end is the most recent event)
113 private final Deque<Event<?, ?>> history = new ConcurrentLinkedDeque<>();
114
115 private ScheduledExecutorService pruner;
116
117 // pruneEventHistoryTask() execution interval in seconds
118 private long pruneInterval = 5;
119
120
121 @Activate
122 protected void activate() {
123 appId = coreService.registerApplication("org.onosproject.events");
124 log.debug("Registered as {}", appId);
125
HIGUCHI Yuta060da9a2016-03-11 19:16:35 -0800126 pruner = newSingleThreadScheduledExecutor(
127 minPriority(groupedThreads("onos/events", "history-pruner", log)));
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800128
129 pruner.scheduleWithFixedDelay(this::pruneEventHistoryTask,
Jian Li68c4fc42016-01-11 16:07:03 -0800130 pruneInterval, pruneInterval, TimeUnit.SECONDS);
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800131
132 listeners = new ListenerTracker();
Yuta HIGUCHId90dbc92016-08-04 18:35:21 -0700133 listeners.addListener(mastershipService, this::addEvent)
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800134 .addListener(deviceService, new InternalDeviceListener())
Yuta HIGUCHId90dbc92016-08-04 18:35:21 -0700135 .addListener(linkService, this::addEvent)
136 .addListener(topologyService, this::addEvent)
137 .addListener(hostService, this::addEvent)
138 .addListener(clusterService, this::addEvent)
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -0800139 .addListener(edgeService, this::addEvent)
Jon Halld66228c2017-08-09 11:24:24 -0700140 .addListener(intentService, this::addEvent)
Yuta HIGUCHI858ad8c2016-12-08 10:59:33 -0800141 .addListener(netcfgService, this::addEvent);
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800142
143 log.info("Started");
144 }
145
146 @Deactivate
147 protected void deactivate() {
148 listeners.removeListeners();
149
150 pruner.shutdownNow();
151 history.clear();
152
153 log.info("Stopped");
154 }
155
156 @Override
157 public Deque<Event<?, ?>> history() {
158 return UnmodifiableDeque.unmodifiableDeque(history);
159 }
160
161 @Override
162 public void clear() {
163 history.clear();
164 }
165
166 // This method assumes only 1 call is in flight at the same time.
167 private void pruneEventHistoryTask() {
168 int size = history.size();
169 int overflows = size - sizeLimit;
170 if (overflows > 0) {
171 for (int i = 0; i < overflows; ++i) {
172 history.poll();
173 }
174 }
175 }
176
177 private void addEvent(Event<?, ?> event) {
Jon Halld66228c2017-08-09 11:24:24 -0700178 if (log.isTraceEnabled()) {
179 log.trace(event.toString());
180 }
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800181 history.offer(event);
182 }
183
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800184 class InternalDeviceListener
185 implements DeviceListener {
186
187 @Override
188 public boolean isRelevant(DeviceEvent event) {
189 if (excludeStatsEvent) {
190 return event.type() != DeviceEvent.Type.PORT_STATS_UPDATED;
191 } else {
192 return true;
193 }
194 }
195
196 @Override
197 public void event(DeviceEvent event) {
198 addEvent(event);
199 }
200 }
201
HIGUCHI Yuta9092db82016-01-03 18:45:01 -0800202}