Committed by
Gerrit Code Review
Event history service and CLI
- Tool created while debugging ONOS-3509 Usage Example: (See recent Mastership and Device events) onos> events -m -d Change-Id: I87aceaf8fe61732a61c2d1e39399d0f10a729b54
Showing
9 changed files
with
1071 additions
and
0 deletions
apps/events/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!-- | ||
| 3 | + ~ Copyright 2016 Open Networking Laboratory | ||
| 4 | + ~ | ||
| 5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | + ~ you may not use this file except in compliance with the License. | ||
| 7 | + ~ You may obtain a copy of the License at | ||
| 8 | + ~ | ||
| 9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | + ~ | ||
| 11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
| 12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | + ~ See the License for the specific language governing permissions and | ||
| 15 | + ~ limitations under the License. | ||
| 16 | + --> | ||
| 17 | +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 18 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 19 | + <modelVersion>4.0.0</modelVersion> | ||
| 20 | + <parent> | ||
| 21 | + <artifactId>onos-apps</artifactId> | ||
| 22 | + <groupId>org.onosproject</groupId> | ||
| 23 | + <version>1.5.0-SNAPSHOT</version> | ||
| 24 | + <relativePath>../pom.xml</relativePath> | ||
| 25 | + </parent> | ||
| 26 | + | ||
| 27 | + <groupId>org.onosproject</groupId> | ||
| 28 | + <artifactId>onos-events</artifactId> | ||
| 29 | + <packaging>bundle</packaging> | ||
| 30 | + | ||
| 31 | + <description>App to display ONOS event history</description> | ||
| 32 | + <url>http://onosproject.org</url> | ||
| 33 | + | ||
| 34 | + <properties> | ||
| 35 | + <onos.version>1.5.0-SNAPSHOT</onos.version> | ||
| 36 | + <onos.app.name>org.onosproject.events</onos.app.name> | ||
| 37 | + </properties> | ||
| 38 | + | ||
| 39 | + <dependencies> | ||
| 40 | + <dependency> | ||
| 41 | + <groupId>org.onosproject</groupId> | ||
| 42 | + <artifactId>onos-api</artifactId> | ||
| 43 | + </dependency> | ||
| 44 | + | ||
| 45 | + <dependency> | ||
| 46 | + <groupId>org.onosproject</groupId> | ||
| 47 | + <artifactId>onlab-osgi</artifactId> | ||
| 48 | + </dependency> | ||
| 49 | + | ||
| 50 | + <dependency> | ||
| 51 | + <groupId>junit</groupId> | ||
| 52 | + <artifactId>junit</artifactId> | ||
| 53 | + <scope>test</scope> | ||
| 54 | + </dependency> | ||
| 55 | + | ||
| 56 | + <dependency> | ||
| 57 | + <groupId>org.onosproject</groupId> | ||
| 58 | + <artifactId>onos-api</artifactId> | ||
| 59 | + <scope>test</scope> | ||
| 60 | + <classifier>tests</classifier> | ||
| 61 | + </dependency> | ||
| 62 | + | ||
| 63 | + <dependency> | ||
| 64 | + <groupId>org.apache.felix</groupId> | ||
| 65 | + <artifactId>org.apache.felix.scr.annotations</artifactId> | ||
| 66 | + <scope>provided</scope> | ||
| 67 | + </dependency> | ||
| 68 | + | ||
| 69 | + <dependency> | ||
| 70 | + <groupId>org.onosproject</groupId> | ||
| 71 | + <artifactId>onos-cli</artifactId> | ||
| 72 | + <version>${project.version}</version> | ||
| 73 | + </dependency> | ||
| 74 | + | ||
| 75 | + <dependency> | ||
| 76 | + <groupId>org.osgi</groupId> | ||
| 77 | + <artifactId>org.osgi.core</artifactId> | ||
| 78 | + <scope>provided</scope> | ||
| 79 | + </dependency> | ||
| 80 | + | ||
| 81 | + <dependency> | ||
| 82 | + <groupId>org.apache.karaf.shell</groupId> | ||
| 83 | + <artifactId>org.apache.karaf.shell.console</artifactId> | ||
| 84 | + <scope>provided</scope> | ||
| 85 | + </dependency> | ||
| 86 | + <dependency> | ||
| 87 | + <groupId>org.onosproject</groupId> | ||
| 88 | + <artifactId>onlab-junit</artifactId> | ||
| 89 | + <scope>test</scope> | ||
| 90 | + </dependency> | ||
| 91 | + <dependency> | ||
| 92 | + <groupId>org.onosproject</groupId> | ||
| 93 | + <artifactId>onlab-misc</artifactId> | ||
| 94 | + </dependency> | ||
| 95 | + </dependencies> | ||
| 96 | + | ||
| 97 | + <build> | ||
| 98 | + <plugins> | ||
| 99 | + <plugin> | ||
| 100 | + <groupId>org.apache.felix</groupId> | ||
| 101 | + <artifactId>maven-bundle-plugin</artifactId> | ||
| 102 | + <extensions>true</extensions> | ||
| 103 | + </plugin> | ||
| 104 | + <plugin> | ||
| 105 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 106 | + <artifactId>maven-compiler-plugin</artifactId> | ||
| 107 | + </plugin> | ||
| 108 | + <plugin> | ||
| 109 | + <groupId>org.apache.felix</groupId> | ||
| 110 | + <artifactId>maven-scr-plugin</artifactId> | ||
| 111 | + <executions> | ||
| 112 | + <execution> | ||
| 113 | + <id>generate-scr-srcdescriptor</id> | ||
| 114 | + <goals> | ||
| 115 | + <goal>scr</goal> | ||
| 116 | + </goals> | ||
| 117 | + </execution> | ||
| 118 | + </executions> | ||
| 119 | + <configuration> | ||
| 120 | + <supportedProjectTypes> | ||
| 121 | + <supportedProjectType>bundle</supportedProjectType> | ||
| 122 | + <supportedProjectType>war</supportedProjectType> | ||
| 123 | + </supportedProjectTypes> | ||
| 124 | + </configuration> | ||
| 125 | + </plugin> | ||
| 126 | + <plugin> | ||
| 127 | + <groupId>org.onosproject</groupId> | ||
| 128 | + <artifactId>onos-maven-plugin</artifactId> | ||
| 129 | + <executions> | ||
| 130 | + <execution> | ||
| 131 | + <id>cfg</id> | ||
| 132 | + <phase>generate-resources</phase> | ||
| 133 | + <goals> | ||
| 134 | + <goal>cfg</goal> | ||
| 135 | + </goals> | ||
| 136 | + </execution> | ||
| 137 | + <execution> | ||
| 138 | + <id>swagger</id> | ||
| 139 | + <phase>generate-sources</phase> | ||
| 140 | + <goals> | ||
| 141 | + <goal>swagger</goal> | ||
| 142 | + </goals> | ||
| 143 | + </execution> | ||
| 144 | + <execution> | ||
| 145 | + <id>app</id> | ||
| 146 | + <phase>package</phase> | ||
| 147 | + <goals> | ||
| 148 | + <goal>app</goal> | ||
| 149 | + </goals> | ||
| 150 | + </execution> | ||
| 151 | + </executions> | ||
| 152 | + </plugin> | ||
| 153 | + </plugins> | ||
| 154 | + </build> | ||
| 155 | + | ||
| 156 | +</project> |
| 1 | +/* | ||
| 2 | + * Copyright 2016 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 | + */ | ||
| 16 | +package org.onosproject.events; | ||
| 17 | + | ||
| 18 | +import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ||
| 19 | +import static org.onlab.util.Tools.groupedThreads; | ||
| 20 | +import static org.onlab.util.Tools.minPriority; | ||
| 21 | + | ||
| 22 | +import java.util.Deque; | ||
| 23 | +import java.util.concurrent.ConcurrentLinkedDeque; | ||
| 24 | +import java.util.concurrent.ScheduledExecutorService; | ||
| 25 | +import java.util.concurrent.TimeUnit; | ||
| 26 | + | ||
| 27 | +import org.apache.felix.scr.annotations.Activate; | ||
| 28 | +import org.apache.felix.scr.annotations.Component; | ||
| 29 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 30 | +import org.apache.felix.scr.annotations.Property; | ||
| 31 | +import org.apache.felix.scr.annotations.Reference; | ||
| 32 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 33 | +import org.apache.felix.scr.annotations.Service; | ||
| 34 | +import org.onlab.util.UnmodifiableDeque; | ||
| 35 | +import org.onosproject.cluster.ClusterEvent; | ||
| 36 | +import org.onosproject.cluster.ClusterEventListener; | ||
| 37 | +import org.onosproject.cluster.ClusterService; | ||
| 38 | +import org.onosproject.core.ApplicationId; | ||
| 39 | +import org.onosproject.core.CoreService; | ||
| 40 | +import org.onosproject.event.Event; | ||
| 41 | +import org.onosproject.event.ListenerTracker; | ||
| 42 | +import org.onosproject.mastership.MastershipEvent; | ||
| 43 | +import org.onosproject.mastership.MastershipListener; | ||
| 44 | +import org.onosproject.mastership.MastershipService; | ||
| 45 | +import org.onosproject.net.device.DeviceEvent; | ||
| 46 | +import org.onosproject.net.device.DeviceListener; | ||
| 47 | +import org.onosproject.net.device.DeviceService; | ||
| 48 | +import org.onosproject.net.host.HostEvent; | ||
| 49 | +import org.onosproject.net.host.HostListener; | ||
| 50 | +import org.onosproject.net.host.HostService; | ||
| 51 | +import org.onosproject.net.link.LinkEvent; | ||
| 52 | +import org.onosproject.net.link.LinkListener; | ||
| 53 | +import org.onosproject.net.link.LinkService; | ||
| 54 | +import org.onosproject.net.topology.TopologyEvent; | ||
| 55 | +import org.onosproject.net.topology.TopologyListener; | ||
| 56 | +import org.onosproject.net.topology.TopologyService; | ||
| 57 | +import org.slf4j.Logger; | ||
| 58 | +import org.slf4j.LoggerFactory; | ||
| 59 | + | ||
| 60 | +/** | ||
| 61 | + * Application to store history of instance local ONOS Events. | ||
| 62 | + */ | ||
| 63 | +@Component(immediate = true) | ||
| 64 | +@Service | ||
| 65 | +public class EventHistoryManager | ||
| 66 | + implements EventHistoryService { | ||
| 67 | + | ||
| 68 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
| 69 | + | ||
| 70 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 71 | + protected CoreService coreService; | ||
| 72 | + | ||
| 73 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 74 | + protected MastershipService mastershipService; | ||
| 75 | + | ||
| 76 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 77 | + protected DeviceService deviceService; | ||
| 78 | + | ||
| 79 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 80 | + protected LinkService linkService; | ||
| 81 | + | ||
| 82 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 83 | + protected TopologyService topologyService; | ||
| 84 | + | ||
| 85 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 86 | + protected HostService hostService; | ||
| 87 | + | ||
| 88 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 89 | + protected ClusterService clusterService; | ||
| 90 | + | ||
| 91 | + @Property(name = "excludeStatsEvent", boolValue = true, | ||
| 92 | + label = "Exclude stats related events") | ||
| 93 | + private boolean excludeStatsEvent = true; | ||
| 94 | + | ||
| 95 | + @Property(name = "sizeLimit", intValue = 10_000, | ||
| 96 | + label = "Number of event history to store") | ||
| 97 | + private int sizeLimit = 10_000; | ||
| 98 | + | ||
| 99 | + private ApplicationId appId; | ||
| 100 | + | ||
| 101 | + private ListenerTracker listeners; | ||
| 102 | + | ||
| 103 | + // Using Deque so that it'll be possible to iterate from both ends | ||
| 104 | + // (Tail-end is the most recent event) | ||
| 105 | + private final Deque<Event<?, ?>> history = new ConcurrentLinkedDeque<>(); | ||
| 106 | + | ||
| 107 | + private ScheduledExecutorService pruner; | ||
| 108 | + | ||
| 109 | + // pruneEventHistoryTask() execution interval in seconds | ||
| 110 | + private long pruneInterval = 5; | ||
| 111 | + | ||
| 112 | + | ||
| 113 | + @Activate | ||
| 114 | + protected void activate() { | ||
| 115 | + appId = coreService.registerApplication("org.onosproject.events"); | ||
| 116 | + log.debug("Registered as {}", appId); | ||
| 117 | + | ||
| 118 | + pruner = newSingleThreadScheduledExecutor(minPriority(groupedThreads("onos/events", "history-pruner"))); | ||
| 119 | + | ||
| 120 | + pruner.scheduleWithFixedDelay(this::pruneEventHistoryTask, | ||
| 121 | + pruneInterval , pruneInterval, TimeUnit.SECONDS); | ||
| 122 | + | ||
| 123 | + listeners = new ListenerTracker(); | ||
| 124 | + listeners.addListener(mastershipService, new InternalMastershipListener()) | ||
| 125 | + .addListener(deviceService, new InternalDeviceListener()) | ||
| 126 | + .addListener(linkService, new InternalLinkListener()) | ||
| 127 | + .addListener(topologyService, new InternalTopologyListener()) | ||
| 128 | + .addListener(hostService, new InternalHostListener()) | ||
| 129 | + .addListener(clusterService, new InternalClusterListener()); | ||
| 130 | + | ||
| 131 | + log.info("Started"); | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + @Deactivate | ||
| 135 | + protected void deactivate() { | ||
| 136 | + listeners.removeListeners(); | ||
| 137 | + | ||
| 138 | + pruner.shutdownNow(); | ||
| 139 | + history.clear(); | ||
| 140 | + | ||
| 141 | + log.info("Stopped"); | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + @Override | ||
| 145 | + public Deque<Event<?, ?>> history() { | ||
| 146 | + return UnmodifiableDeque.unmodifiableDeque(history); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + @Override | ||
| 150 | + public void clear() { | ||
| 151 | + history.clear(); | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + // This method assumes only 1 call is in flight at the same time. | ||
| 155 | + private void pruneEventHistoryTask() { | ||
| 156 | + int size = history.size(); | ||
| 157 | + int overflows = size - sizeLimit; | ||
| 158 | + if (overflows > 0) { | ||
| 159 | + for (int i = 0; i < overflows; ++i) { | ||
| 160 | + history.poll(); | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + private void addEvent(Event<?, ?> event) { | ||
| 166 | + history.offer(event); | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + class InternalMastershipListener | ||
| 170 | + implements MastershipListener { | ||
| 171 | + | ||
| 172 | + @Override | ||
| 173 | + public void event(MastershipEvent event) { | ||
| 174 | + addEvent(event); | ||
| 175 | + } | ||
| 176 | + } | ||
| 177 | + | ||
| 178 | + class InternalDeviceListener | ||
| 179 | + implements DeviceListener { | ||
| 180 | + | ||
| 181 | + @Override | ||
| 182 | + public boolean isRelevant(DeviceEvent event) { | ||
| 183 | + if (excludeStatsEvent) { | ||
| 184 | + return event.type() != DeviceEvent.Type.PORT_STATS_UPDATED; | ||
| 185 | + } else { | ||
| 186 | + return true; | ||
| 187 | + } | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + @Override | ||
| 191 | + public void event(DeviceEvent event) { | ||
| 192 | + addEvent(event); | ||
| 193 | + } | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + class InternalLinkListener | ||
| 197 | + implements LinkListener { | ||
| 198 | + | ||
| 199 | + @Override | ||
| 200 | + public void event(LinkEvent event) { | ||
| 201 | + addEvent(event); | ||
| 202 | + } | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + class InternalTopologyListener | ||
| 206 | + implements TopologyListener { | ||
| 207 | + | ||
| 208 | + @Override | ||
| 209 | + public void event(TopologyEvent event) { | ||
| 210 | + addEvent(event); | ||
| 211 | + } | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + class InternalHostListener | ||
| 215 | + implements HostListener { | ||
| 216 | + | ||
| 217 | + @Override | ||
| 218 | + public void event(HostEvent event) { | ||
| 219 | + addEvent(event); | ||
| 220 | + } | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + class InternalClusterListener | ||
| 224 | + implements ClusterEventListener { | ||
| 225 | + | ||
| 226 | + @Override | ||
| 227 | + public void event(ClusterEvent event) { | ||
| 228 | + addEvent(event); | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | + | ||
| 232 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2016 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 | + */ | ||
| 16 | +package org.onosproject.events; | ||
| 17 | + | ||
| 18 | +import java.util.Deque; | ||
| 19 | + | ||
| 20 | +import org.onosproject.event.Event; | ||
| 21 | + | ||
| 22 | +import com.google.common.annotations.Beta; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * Provides history of instance local ONOS Events. | ||
| 26 | + */ | ||
| 27 | +@Beta | ||
| 28 | +public interface EventHistoryService { | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * Returns unmodifiable view of ONOS events history. | ||
| 32 | + * | ||
| 33 | + * @return ONOS events (First element is the oldest event stored) | ||
| 34 | + */ | ||
| 35 | + Deque<Event<?, ?>> history(); | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Clears all stored history. | ||
| 39 | + */ | ||
| 40 | + void clear(); | ||
| 41 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2016 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 | + */ | ||
| 16 | +package org.onosproject.events; | ||
| 17 | + | ||
| 18 | +import static java.util.stream.Collectors.toList; | ||
| 19 | + | ||
| 20 | +import java.io.PrintWriter; | ||
| 21 | +import java.io.StringWriter; | ||
| 22 | +import java.util.List; | ||
| 23 | +import java.util.function.Predicate; | ||
| 24 | +import java.util.stream.Collector; | ||
| 25 | +import java.util.stream.Stream; | ||
| 26 | + | ||
| 27 | +import org.apache.karaf.shell.commands.Command; | ||
| 28 | +import org.apache.karaf.shell.commands.Option; | ||
| 29 | +import org.joda.time.LocalDateTime; | ||
| 30 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 31 | +import org.onosproject.cluster.ClusterEvent; | ||
| 32 | +import org.onosproject.event.Event; | ||
| 33 | +import org.onosproject.mastership.MastershipEvent; | ||
| 34 | +import org.onosproject.net.Link; | ||
| 35 | +import org.onosproject.net.device.DeviceEvent; | ||
| 36 | +import org.onosproject.net.host.HostEvent; | ||
| 37 | +import org.onosproject.net.link.LinkEvent; | ||
| 38 | +import org.onosproject.net.topology.Topology; | ||
| 39 | +import org.onosproject.net.topology.TopologyEvent; | ||
| 40 | + | ||
| 41 | +import com.fasterxml.jackson.core.JsonProcessingException; | ||
| 42 | +import com.fasterxml.jackson.databind.JsonNode; | ||
| 43 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
| 44 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 45 | +import com.google.common.base.MoreObjects; | ||
| 46 | +import com.google.common.collect.ImmutableList; | ||
| 47 | + | ||
| 48 | +/** | ||
| 49 | + * Command to print history of instance local ONOS Events. | ||
| 50 | + */ | ||
| 51 | +@Command(scope = "onos", name = "events", | ||
| 52 | + description = "Command to print history of instance local ONOS Events") | ||
| 53 | +public class EventsCommand | ||
| 54 | + extends AbstractShellCommand { | ||
| 55 | + | ||
| 56 | + @Option(name = "--all", aliases = "-a", | ||
| 57 | + description = "Include all Events (default behavior)", | ||
| 58 | + required = false) | ||
| 59 | + private boolean all = false; | ||
| 60 | + | ||
| 61 | + @Option(name = "--mastership", aliases = "-m", | ||
| 62 | + description = "Include MastershipEvent", | ||
| 63 | + required = false) | ||
| 64 | + private boolean mastership = false; | ||
| 65 | + | ||
| 66 | + @Option(name = "--device", aliases = "-d", | ||
| 67 | + description = "Include DeviceEvent", | ||
| 68 | + required = false) | ||
| 69 | + private boolean device = false; | ||
| 70 | + | ||
| 71 | + @Option(name = "--link", aliases = "-l", | ||
| 72 | + description = "Include LinkEvent", | ||
| 73 | + required = false) | ||
| 74 | + private boolean link = false; | ||
| 75 | + | ||
| 76 | + @Option(name = "--topology", aliases = "-t", | ||
| 77 | + description = "Include TopologyEvent", | ||
| 78 | + required = false) | ||
| 79 | + private boolean topology = false; | ||
| 80 | + | ||
| 81 | + @Option(name = "--host", aliases = "-t", | ||
| 82 | + description = "Include HostEvent", | ||
| 83 | + required = false) | ||
| 84 | + private boolean host = false; | ||
| 85 | + | ||
| 86 | + @Option(name = "--cluster", aliases = "-c", | ||
| 87 | + description = "Include ClusterEvent", | ||
| 88 | + required = false) | ||
| 89 | + private boolean cluster = false; | ||
| 90 | + | ||
| 91 | + @Option(name = "--max-events", aliases = "-n", | ||
| 92 | + description = "Maximum number of events to print", | ||
| 93 | + required = false, | ||
| 94 | + valueToShowInHelp = "-1 [no limit]") | ||
| 95 | + private long maxSize = -1; | ||
| 96 | + | ||
| 97 | + @Override | ||
| 98 | + protected void execute() { | ||
| 99 | + EventHistoryService eventHistoryService = get(EventHistoryService.class); | ||
| 100 | + | ||
| 101 | + Stream<Event<?, ?>> events = eventHistoryService.history().stream(); | ||
| 102 | + | ||
| 103 | + boolean dumpAll = all || !(mastership || device || link || topology || host); | ||
| 104 | + | ||
| 105 | + if (!dumpAll) { | ||
| 106 | + Predicate<Event<?, ?>> filter = (defaultIs) -> false; | ||
| 107 | + | ||
| 108 | + if (mastership) { | ||
| 109 | + filter = filter.or(evt -> evt instanceof MastershipEvent); | ||
| 110 | + } | ||
| 111 | + if (device) { | ||
| 112 | + filter = filter.or(evt -> evt instanceof DeviceEvent); | ||
| 113 | + } | ||
| 114 | + if (link) { | ||
| 115 | + filter = filter.or(evt -> evt instanceof LinkEvent); | ||
| 116 | + } | ||
| 117 | + if (topology) { | ||
| 118 | + filter = filter.or(evt -> evt instanceof TopologyEvent); | ||
| 119 | + } | ||
| 120 | + if (host) { | ||
| 121 | + filter = filter.or(evt -> evt instanceof HostEvent); | ||
| 122 | + } | ||
| 123 | + if (cluster) { | ||
| 124 | + filter = filter.or(evt -> evt instanceof ClusterEvent); | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + events = events.filter(filter); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + if (maxSize > 0) { | ||
| 131 | + events = events.limit(maxSize); | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + if (outputJson()) { | ||
| 135 | + ArrayNode jsonEvents = events.map(this::json).collect(toArrayNode()); | ||
| 136 | + printJson(jsonEvents); | ||
| 137 | + } else { | ||
| 138 | + events.forEach(this::printEvent); | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + private Collector<JsonNode, ArrayNode, ArrayNode> toArrayNode() { | ||
| 144 | + return Collector.of(() -> mapper().createArrayNode(), | ||
| 145 | + ArrayNode::add, | ||
| 146 | + ArrayNode::addAll); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + private ObjectNode json(Event<?, ?> event) { | ||
| 150 | + ObjectNode result = mapper().createObjectNode(); | ||
| 151 | + | ||
| 152 | + result.put("time", event.time()) | ||
| 153 | + .put("type", event.type().toString()) | ||
| 154 | + .put("event", event.toString()); | ||
| 155 | + | ||
| 156 | + return result; | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + /** | ||
| 160 | + * Print JsonNode using default pretty printer. | ||
| 161 | + * | ||
| 162 | + * @param json JSON node to print | ||
| 163 | + */ | ||
| 164 | + private void printJson(JsonNode json) { | ||
| 165 | + try { | ||
| 166 | + print("%s", mapper().writerWithDefaultPrettyPrinter().writeValueAsString(json)); | ||
| 167 | + } catch (JsonProcessingException e) { | ||
| 168 | + StringWriter sw = new StringWriter(); | ||
| 169 | + e.printStackTrace(new PrintWriter(sw)); | ||
| 170 | + print("[ERROR] %s\n%s", e.getMessage(), sw.toString()); | ||
| 171 | + } | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + private void printEvent(Event<?, ?> event) { | ||
| 175 | + if (event instanceof DeviceEvent) { | ||
| 176 | + DeviceEvent deviceEvent = (DeviceEvent) event; | ||
| 177 | + if (event.type().toString().startsWith("PORT")) { | ||
| 178 | + // Port event | ||
| 179 | + print("%s %s\t%s/%s [%s]", | ||
| 180 | + new LocalDateTime(event.time()), | ||
| 181 | + event.type(), | ||
| 182 | + deviceEvent.subject().id(), deviceEvent.port().number(), | ||
| 183 | + deviceEvent.port() | ||
| 184 | + ); | ||
| 185 | + } else { | ||
| 186 | + // Device event | ||
| 187 | + print("%s %s\t%s [%s]", | ||
| 188 | + new LocalDateTime(event.time()), | ||
| 189 | + event.type(), | ||
| 190 | + deviceEvent.subject().id(), | ||
| 191 | + deviceEvent.subject() | ||
| 192 | + ); | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + } else if (event instanceof MastershipEvent) { | ||
| 196 | + print("%s %s\t%s [%s]", | ||
| 197 | + new LocalDateTime(event.time()), | ||
| 198 | + event.type(), | ||
| 199 | + event.subject(), | ||
| 200 | + ((MastershipEvent) event).roleInfo()); | ||
| 201 | + | ||
| 202 | + } else if (event instanceof LinkEvent) { | ||
| 203 | + LinkEvent linkEvent = (LinkEvent) event; | ||
| 204 | + Link link = linkEvent.subject(); | ||
| 205 | + print("%s %s\t%s/%s-%s/%s [%s]", | ||
| 206 | + new LocalDateTime(event.time()), | ||
| 207 | + event.type(), | ||
| 208 | + link.src().deviceId(), link.src().port(), link.dst().deviceId(), link.dst().port(), | ||
| 209 | + link); | ||
| 210 | + | ||
| 211 | + } else if (event instanceof HostEvent) { | ||
| 212 | + HostEvent hostEvent = (HostEvent) event; | ||
| 213 | + print("%s %s\t%s [%s->%s]", | ||
| 214 | + new LocalDateTime(event.time()), | ||
| 215 | + event.type(), | ||
| 216 | + hostEvent.subject().id(), | ||
| 217 | + hostEvent.prevSubject(), hostEvent.subject()); | ||
| 218 | + | ||
| 219 | + } else if (event instanceof TopologyEvent) { | ||
| 220 | + TopologyEvent topoEvent = (TopologyEvent) event; | ||
| 221 | + List<Event> reasons = MoreObjects.firstNonNull(topoEvent.reasons(), ImmutableList.of()); | ||
| 222 | + Topology topo = topoEvent.subject(); | ||
| 223 | + String summary = String.format("(d=%d,l=%d,c=%d)", | ||
| 224 | + topo.deviceCount(), | ||
| 225 | + topo.linkCount(), | ||
| 226 | + topo.clusterCount()); | ||
| 227 | + print("%s %s%s [%s]", | ||
| 228 | + new LocalDateTime(event.time()), | ||
| 229 | + event.type(), | ||
| 230 | + summary, | ||
| 231 | + reasons.stream().map(e -> e.type()).collect(toList())); | ||
| 232 | + | ||
| 233 | + } else if (event instanceof ClusterEvent) { | ||
| 234 | + print("%s %s\t%s [%s]", | ||
| 235 | + new LocalDateTime(event.time()), | ||
| 236 | + event.type(), | ||
| 237 | + ((ClusterEvent) event).subject().id(), | ||
| 238 | + event.subject()); | ||
| 239 | + | ||
| 240 | + } else { | ||
| 241 | + // Unknown Event? | ||
| 242 | + print("%s %s\t%s [%s]", | ||
| 243 | + new LocalDateTime(event.time()), | ||
| 244 | + event.type(), | ||
| 245 | + event.subject(), | ||
| 246 | + event); | ||
| 247 | + } | ||
| 248 | + } | ||
| 249 | + | ||
| 250 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2016 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 | + */ | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * Application to store history of instance local ONOS Events. | ||
| 19 | + */ | ||
| 20 | +package org.onosproject.events; |
| 1 | +<!-- | ||
| 2 | + ~ Copyright 2016 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 | + --> | ||
| 16 | +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> | ||
| 17 | + | ||
| 18 | + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | ||
| 19 | + <command> | ||
| 20 | + <action class="org.onosproject.events.EventsCommand"/> | ||
| 21 | + </command> | ||
| 22 | + </command-bundle> | ||
| 23 | + | ||
| 24 | +</blueprint> |
| ... | @@ -63,6 +63,7 @@ | ... | @@ -63,6 +63,7 @@ |
| 63 | <module>pathpainter</module> | 63 | <module>pathpainter</module> |
| 64 | <module>drivermatrix</module> | 64 | <module>drivermatrix</module> |
| 65 | <module>cpman</module> | 65 | <module>cpman</module> |
| 66 | + <module>events</module> | ||
| 66 | </modules> | 67 | </modules> |
| 67 | 68 | ||
| 68 | <properties> | 69 | <properties> |
| ... | @@ -107,3 +108,4 @@ | ... | @@ -107,3 +108,4 @@ |
| 107 | </build> | 108 | </build> |
| 108 | 109 | ||
| 109 | </project> | 110 | </project> |
| 111 | + | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2016 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 | + */ | ||
| 16 | +package org.onosproject.event; | ||
| 17 | + | ||
| 18 | +import java.util.ArrayList; | ||
| 19 | +import java.util.List; | ||
| 20 | + | ||
| 21 | +import javax.annotation.concurrent.NotThreadSafe; | ||
| 22 | + | ||
| 23 | +import org.apache.commons.lang3.tuple.Pair; | ||
| 24 | + | ||
| 25 | +import com.google.common.annotations.Beta; | ||
| 26 | +import com.google.common.collect.Lists; | ||
| 27 | + | ||
| 28 | +/** | ||
| 29 | + * Utility to keeps track of registered Listeners. | ||
| 30 | + * <p> | ||
| 31 | + * Usage Example: | ||
| 32 | + * <pre> | ||
| 33 | + * <code> | ||
| 34 | + private ListenerTracker listeners; | ||
| 35 | + | ||
| 36 | + {@code @Activate} | ||
| 37 | + protected void activate() { | ||
| 38 | + listeners = new ListenerTracker(); | ||
| 39 | + listeners.addListener(mastershipService, new InternalMastershipListener()) | ||
| 40 | + .addListener(deviceService, new InternalDeviceListener()) | ||
| 41 | + .addListener(linkService, new InternalLinkListener()) | ||
| 42 | + .addListener(topologyService, new InternalTopologyListener()) | ||
| 43 | + .addListener(hostService, new InternalHostListener()); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + {@code @Deactivate} | ||
| 47 | + protected void deactivate() { | ||
| 48 | + listeners.removeListeners(); | ||
| 49 | + } | ||
| 50 | + * </code> | ||
| 51 | + * </pre> | ||
| 52 | + */ | ||
| 53 | +@Beta | ||
| 54 | +@NotThreadSafe | ||
| 55 | +public class ListenerTracker { | ||
| 56 | + | ||
| 57 | + @SuppressWarnings("rawtypes") | ||
| 58 | + private List<Pair<ListenerService, EventListener>> listeners = new ArrayList<>(); | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * Adds {@link EventListener} to specified {@link ListenerService}. | ||
| 62 | + * | ||
| 63 | + * @param service {@link ListenerService} | ||
| 64 | + * @param listener {@link EventListener} | ||
| 65 | + * @return self | ||
| 66 | + */ | ||
| 67 | + public <E extends Event<?, ?>, L extends EventListener<E>> | ||
| 68 | + ListenerTracker addListener(ListenerService<E, L> service, L listener) { | ||
| 69 | + service.addListener(listener); | ||
| 70 | + listeners.add(Pair.of(service, listener)); | ||
| 71 | + return this; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + /** | ||
| 75 | + * Removes all listeners in reverse order they have been registered. | ||
| 76 | + */ | ||
| 77 | + public void removeListeners() { | ||
| 78 | + Lists.reverse(listeners) | ||
| 79 | + .forEach(r -> r.getLeft().removeListener(r.getRight())); | ||
| 80 | + listeners.clear(); | ||
| 81 | + } | ||
| 82 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2016 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 | + */ | ||
| 16 | +package org.onlab.util; | ||
| 17 | + | ||
| 18 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 19 | + | ||
| 20 | +import java.util.Collection; | ||
| 21 | +import java.util.Deque; | ||
| 22 | +import java.util.Iterator; | ||
| 23 | +import java.util.Spliterator; | ||
| 24 | +import java.util.function.Consumer; | ||
| 25 | +import java.util.function.Predicate; | ||
| 26 | +import java.util.stream.Stream; | ||
| 27 | +import com.google.common.collect.Iterators; | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * Unmodifiable view of the specified Deque. | ||
| 31 | + */ | ||
| 32 | +public class UnmodifiableDeque<E> implements Deque<E> { | ||
| 33 | + | ||
| 34 | + private final Deque<E> deque; | ||
| 35 | + | ||
| 36 | + UnmodifiableDeque(Deque<E> deque) { | ||
| 37 | + this.deque = checkNotNull(deque); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * Returns an unmodifiable view of the specified Deque. | ||
| 42 | + * | ||
| 43 | + * @param deque underlying {@link Deque} to use. | ||
| 44 | + * @return unmodifiable view of {@code deque} | ||
| 45 | + */ | ||
| 46 | + public static <T> Deque<T> unmodifiableDeque(Deque<T> deque) { | ||
| 47 | + return new UnmodifiableDeque<T>(deque); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + @Override | ||
| 51 | + public void forEach(Consumer<? super E> action) { | ||
| 52 | + deque.forEach(action); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + public void addFirst(E e) { | ||
| 57 | + throw new UnsupportedOperationException(); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public boolean isEmpty() { | ||
| 62 | + return deque.isEmpty(); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @Override | ||
| 66 | + public void addLast(E e) { | ||
| 67 | + throw new UnsupportedOperationException(); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + @Override | ||
| 71 | + public Object[] toArray() { | ||
| 72 | + return deque.toArray(); | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + @Override | ||
| 76 | + public boolean offerFirst(E e) { | ||
| 77 | + throw new UnsupportedOperationException(); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + @Override | ||
| 81 | + public <T> T[] toArray(T[] a) { | ||
| 82 | + return deque.toArray(a); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + @Override | ||
| 86 | + public boolean offerLast(E e) { | ||
| 87 | + throw new UnsupportedOperationException(); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + @Override | ||
| 91 | + public E removeFirst() { | ||
| 92 | + throw new UnsupportedOperationException(); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + @Override | ||
| 96 | + public E removeLast() { | ||
| 97 | + throw new UnsupportedOperationException(); | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + @Override | ||
| 101 | + public E pollFirst() { | ||
| 102 | + throw new UnsupportedOperationException(); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + @Override | ||
| 106 | + public E pollLast() { | ||
| 107 | + throw new UnsupportedOperationException(); | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + @Override | ||
| 111 | + public E getFirst() { | ||
| 112 | + return deque.getFirst(); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + @Override | ||
| 116 | + public E getLast() { | ||
| 117 | + return deque.getLast(); | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + @Override | ||
| 121 | + public E peekFirst() { | ||
| 122 | + return deque.peekFirst(); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + @Override | ||
| 126 | + public E peekLast() { | ||
| 127 | + return deque.peekLast(); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + @Override | ||
| 131 | + public boolean removeFirstOccurrence(Object o) { | ||
| 132 | + throw new UnsupportedOperationException(); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + @Override | ||
| 136 | + public boolean removeLastOccurrence(Object o) { | ||
| 137 | + throw new UnsupportedOperationException(); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + @Override | ||
| 141 | + public boolean containsAll(Collection<?> c) { | ||
| 142 | + return deque.containsAll(c); | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + @Override | ||
| 146 | + public boolean add(E e) { | ||
| 147 | + throw new UnsupportedOperationException(); | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + @Override | ||
| 151 | + public boolean addAll(Collection<? extends E> c) { | ||
| 152 | + throw new UnsupportedOperationException(); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + @Override | ||
| 156 | + public boolean offer(E e) { | ||
| 157 | + throw new UnsupportedOperationException(); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + @Override | ||
| 161 | + public boolean removeAll(Collection<?> c) { | ||
| 162 | + throw new UnsupportedOperationException(); | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + @Override | ||
| 166 | + public E remove() { | ||
| 167 | + throw new UnsupportedOperationException(); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + @Override | ||
| 171 | + public E poll() { | ||
| 172 | + throw new UnsupportedOperationException(); | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + @Override | ||
| 176 | + public E element() { | ||
| 177 | + return deque.element(); | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + @Override | ||
| 181 | + public boolean removeIf(Predicate<? super E> filter) { | ||
| 182 | + throw new UnsupportedOperationException(); | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + @Override | ||
| 186 | + public E peek() { | ||
| 187 | + return deque.peek(); | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + @Override | ||
| 191 | + public void push(E e) { | ||
| 192 | + throw new UnsupportedOperationException(); | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + @Override | ||
| 196 | + public boolean retainAll(Collection<?> c) { | ||
| 197 | + throw new UnsupportedOperationException(); | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + @Override | ||
| 201 | + public E pop() { | ||
| 202 | + throw new UnsupportedOperationException(); | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + @Override | ||
| 206 | + public boolean remove(Object o) { | ||
| 207 | + throw new UnsupportedOperationException(); | ||
| 208 | + } | ||
| 209 | + | ||
| 210 | + @Override | ||
| 211 | + public void clear() { | ||
| 212 | + throw new UnsupportedOperationException(); | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | + @Override | ||
| 216 | + public boolean equals(Object o) { | ||
| 217 | + return deque.equals(o); | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + @Override | ||
| 221 | + public boolean contains(Object o) { | ||
| 222 | + return deque.contains(o); | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + @Override | ||
| 226 | + public int size() { | ||
| 227 | + return deque.size(); | ||
| 228 | + } | ||
| 229 | + | ||
| 230 | + @Override | ||
| 231 | + public Iterator<E> iterator() { | ||
| 232 | + return Iterators.unmodifiableIterator(deque.iterator()); | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + @Override | ||
| 236 | + public Iterator<E> descendingIterator() { | ||
| 237 | + return Iterators.unmodifiableIterator(deque.descendingIterator()); | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + @Override | ||
| 241 | + public int hashCode() { | ||
| 242 | + return deque.hashCode(); | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + @Override | ||
| 246 | + public Spliterator<E> spliterator() { | ||
| 247 | + return deque.spliterator(); | ||
| 248 | + } | ||
| 249 | + | ||
| 250 | + @Override | ||
| 251 | + public Stream<E> stream() { | ||
| 252 | + return deque.stream(); | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + @Override | ||
| 256 | + public Stream<E> parallelStream() { | ||
| 257 | + return deque.parallelStream(); | ||
| 258 | + } | ||
| 259 | + | ||
| 260 | + @Override | ||
| 261 | + public String toString() { | ||
| 262 | + return deque.toString(); | ||
| 263 | + } | ||
| 264 | +} |
-
Please register or login to post a comment