Yuta HIGUCHI
Committed by Yuta Higuchi

Configuration to suppress LLDP discovery

Change-Id: I3b14df6682839f14694b69330a0943facd4f3a6f
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
34 34
35 <dependencies> 35 <dependencies>
36 <dependency> 36 <dependency>
37 + <groupId>org.osgi</groupId>
38 + <artifactId>org.osgi.compendium</artifactId>
39 + </dependency>
40 +
41 + <dependency>
37 <groupId>org.onosproject</groupId> 42 <groupId>org.onosproject</groupId>
38 <artifactId>onos-api</artifactId> 43 <artifactId>onos-api</artifactId>
39 <classifier>tests</classifier> 44 <classifier>tests</classifier>
......
...@@ -18,6 +18,8 @@ package org.onosproject.provider.lldp.impl; ...@@ -18,6 +18,8 @@ package org.onosproject.provider.lldp.impl;
18 import org.apache.felix.scr.annotations.Activate; 18 import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 19 import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 20 import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Modified;
22 +import org.apache.felix.scr.annotations.Property;
21 import org.apache.felix.scr.annotations.Reference; 23 import org.apache.felix.scr.annotations.Reference;
22 import org.apache.felix.scr.annotations.ReferenceCardinality; 24 import org.apache.felix.scr.annotations.ReferenceCardinality;
23 import org.onosproject.mastership.MastershipEvent; 25 import org.onosproject.mastership.MastershipEvent;
...@@ -38,8 +40,16 @@ import org.onosproject.net.packet.PacketProcessor; ...@@ -38,8 +40,16 @@ import org.onosproject.net.packet.PacketProcessor;
38 import org.onosproject.net.packet.PacketService; 40 import org.onosproject.net.packet.PacketService;
39 import org.onosproject.net.provider.AbstractProvider; 41 import org.onosproject.net.provider.AbstractProvider;
40 import org.onosproject.net.provider.ProviderId; 42 import org.onosproject.net.provider.ProviderId;
43 +import org.osgi.service.component.ComponentContext;
41 import org.slf4j.Logger; 44 import org.slf4j.Logger;
42 45
46 +import com.google.common.base.Strings;
47 +import com.google.common.collect.ImmutableMap;
48 +import com.google.common.collect.ImmutableSet;
49 +
50 +import java.io.IOException;
51 +import java.util.Dictionary;
52 +import java.util.EnumSet;
43 import java.util.Map; 53 import java.util.Map;
44 import java.util.concurrent.ConcurrentHashMap; 54 import java.util.concurrent.ConcurrentHashMap;
45 import java.util.concurrent.ScheduledExecutorService; 55 import java.util.concurrent.ScheduledExecutorService;
...@@ -57,6 +67,13 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -57,6 +67,13 @@ import static org.slf4j.LoggerFactory.getLogger;
57 @Component(immediate = true) 67 @Component(immediate = true)
58 public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { 68 public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
59 69
70 +
71 + private static final String PROP_USE_BDDP = "useBDDP";
72 +
73 + private static final String PROP_LLDP_SUPPRESSION = "lldpSuppression";
74 +
75 + private static final String DEFAULT_LLDP_SUPPRESSION_CONFIG = "../config/lldp_suppression.json";
76 +
60 private final Logger log = getLogger(getClass()); 77 private final Logger log = getLogger(getClass());
61 78
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 79 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
...@@ -75,17 +92,26 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -75,17 +92,26 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
75 92
76 private ScheduledExecutorService executor; 93 private ScheduledExecutorService executor;
77 94
78 - private final boolean useBDDP = true; 95 + @Property(name = PROP_USE_BDDP, boolValue = true,
96 + label = "use BDDP for link discovery")
97 + private boolean useBDDP = true;
79 98
80 private static final long INIT_DELAY = 5; 99 private static final long INIT_DELAY = 5;
81 private static final long DELAY = 5; 100 private static final long DELAY = 5;
82 101
102 + @Property(name = PROP_LLDP_SUPPRESSION, value = DEFAULT_LLDP_SUPPRESSION_CONFIG,
103 + label = "Path to LLDP suppression configuration file")
104 + private String filePath = DEFAULT_LLDP_SUPPRESSION_CONFIG;
105 +
106 +
83 private final InternalLinkProvider listener = new InternalLinkProvider(); 107 private final InternalLinkProvider listener = new InternalLinkProvider();
84 108
85 private final InternalRoleListener roleListener = new InternalRoleListener(); 109 private final InternalRoleListener roleListener = new InternalRoleListener();
86 110
87 protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>(); 111 protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
88 112
113 + private SuppressionRules rules;
114 +
89 /** 115 /**
90 * Creates an OpenFlow link provider. 116 * Creates an OpenFlow link provider.
91 */ 117 */
...@@ -95,6 +121,8 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -95,6 +121,8 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
95 121
96 @Activate 122 @Activate
97 public void activate() { 123 public void activate() {
124 + loadSuppressionRules();
125 +
98 providerService = providerRegistry.register(this); 126 providerService = providerRegistry.register(this);
99 deviceService.addListener(listener); 127 deviceService.addListener(listener);
100 packetSevice.addProcessor(listener, 0); 128 packetSevice.addProcessor(listener, 0);
...@@ -102,10 +130,19 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -102,10 +130,19 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
102 130
103 LinkDiscovery ld; 131 LinkDiscovery ld;
104 for (Device device : deviceService.getAvailableDevices()) { 132 for (Device device : deviceService.getAvailableDevices()) {
133 + if (rules.isSuppressed(device)) {
134 + log.debug("LinkDiscovery from {} disabled by configuration", device.id());
135 + continue;
136 + }
105 ld = new LinkDiscovery(device, packetSevice, masterService, 137 ld = new LinkDiscovery(device, packetSevice, masterService,
106 providerService, useBDDP); 138 providerService, useBDDP);
107 discoverers.put(device.id(), ld); 139 discoverers.put(device.id(), ld);
108 for (Port p : deviceService.getPorts(device.id())) { 140 for (Port p : deviceService.getPorts(device.id())) {
141 + if (rules.isSuppressed(p)) {
142 + log.debug("LinkDiscovery from {}@{} disabled by configuration",
143 + p.number(), device.id());
144 + continue;
145 + }
109 if (!p.number().isLogical()) { 146 if (!p.number().isLogical()) {
110 ld.addPort(p); 147 ld.addPort(p);
111 } 148 }
...@@ -134,6 +171,45 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -134,6 +171,45 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
134 log.info("Stopped"); 171 log.info("Stopped");
135 } 172 }
136 173
174 + @Modified
175 + public void modified(ComponentContext context) {
176 + if (context == null) {
177 + return;
178 + }
179 + @SuppressWarnings("rawtypes")
180 + Dictionary properties = context.getProperties();
181 +
182 + String s = (String) properties.get(PROP_USE_BDDP);
183 + if (Strings.isNullOrEmpty(s)) {
184 + useBDDP = true;
185 + } else {
186 + useBDDP = Boolean.valueOf(s);
187 + }
188 + s = (String) properties.get(PROP_LLDP_SUPPRESSION);
189 + if (Strings.isNullOrEmpty(s)) {
190 + filePath = DEFAULT_LLDP_SUPPRESSION_CONFIG;
191 + } else {
192 + filePath = s;
193 + }
194 +
195 + loadSuppressionRules();
196 + }
197 +
198 + private void loadSuppressionRules() {
199 + SuppressionRulesStore store = new SuppressionRulesStore(filePath);
200 + try {
201 + rules = store.read();
202 + } catch (IOException e) {
203 + log.info("Failed to load {}, using built-in rules", filePath);
204 + // default rule to suppress ROADM to maintain compatibility
205 + rules = new SuppressionRules(ImmutableSet.of(),
206 + EnumSet.of(Device.Type.ROADM),
207 + ImmutableMap.of());
208 + }
209 +
210 + // should refresh discoverers when we need dynamic reconfiguration
211 + }
212 +
137 private class InternalRoleListener implements MastershipListener { 213 private class InternalRoleListener implements MastershipListener {
138 214
139 @Override 215 @Override
...@@ -150,6 +226,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -150,6 +226,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
150 log.warn("Device {} doesn't exist, or isn't there yet", deviceId); 226 log.warn("Device {} doesn't exist, or isn't there yet", deviceId);
151 return; 227 return;
152 } 228 }
229 + if (rules.isSuppressed(device)) {
230 + return;
231 + }
153 synchronized (discoverers) { 232 synchronized (discoverers) {
154 if (!discoverers.containsKey(deviceId)) { 233 if (!discoverers.containsKey(deviceId)) {
155 // ideally, should never reach here 234 // ideally, should never reach here
...@@ -180,20 +259,24 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -180,20 +259,24 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
180 switch (event.type()) { 259 switch (event.type()) {
181 case DEVICE_ADDED: 260 case DEVICE_ADDED:
182 case DEVICE_UPDATED: 261 case DEVICE_UPDATED:
183 - synchronized (discoverers) { 262 + synchronized (discoverers) {
184 - ld = discoverers.get(deviceId); 263 + ld = discoverers.get(deviceId);
185 - if (ld == null) { 264 + if (ld == null) {
186 - log.debug("Device added ({}) {}", event.type(), 265 + if (rules.isSuppressed(device)) {
187 - deviceId); 266 + log.debug("LinkDiscovery from {} disabled by configuration", device.id());
188 - discoverers.put(deviceId, new LinkDiscovery(device, 267 + return;
189 - packetSevice, masterService, providerService, 268 + }
190 - useBDDP)); 269 + log.debug("Device added ({}) {}", event.type(),
191 - } else { 270 + deviceId);
192 - if (ld.isStopped()) { 271 + discoverers.put(deviceId, new LinkDiscovery(device,
193 - log.debug("Device restarted ({}) {}", event.type(), 272 + packetSevice, masterService, providerService,
194 - deviceId); 273 + useBDDP));
195 - ld.start(); 274 + } else {
196 - } 275 + if (ld.isStopped()) {
276 + log.debug("Device restarted ({}) {}", event.type(),
277 + deviceId);
278 + ld.start();
279 + }
197 } 280 }
198 } 281 }
199 break; 282 break;
...@@ -204,6 +287,11 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -204,6 +287,11 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
204 if (ld == null) { 287 if (ld == null) {
205 return; 288 return;
206 } 289 }
290 + if (rules.isSuppressed(port)) {
291 + log.debug("LinkDiscovery from {}@{} disabled by configuration",
292 + port.number(), device.id());
293 + return;
294 + }
207 if (!port.number().isLogical()) { 295 if (!port.number().isLogical()) {
208 log.debug("Port added {}", port); 296 log.debug("Port added {}", port);
209 ld.addPort(port); 297 ld.addPort(port);
...@@ -280,6 +368,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -280,6 +368,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
280 try { 368 try {
281 LinkDiscovery ld = null; 369 LinkDiscovery ld = null;
282 for (Device dev : deviceService.getDevices()) { 370 for (Device dev : deviceService.getDevices()) {
371 + if (rules.isSuppressed(dev)) {
372 + continue;
373 + }
283 DeviceId did = dev.id(); 374 DeviceId did = dev.id();
284 synchronized (discoverers) { 375 synchronized (discoverers) {
285 if (!discoverers.containsKey(did)) { 376 if (!discoverers.containsKey(did)) {
...@@ -287,6 +378,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -287,6 +378,9 @@ public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
287 masterService, providerService, useBDDP); 378 masterService, providerService, useBDDP);
288 discoverers.put(did, ld); 379 discoverers.put(did, ld);
289 for (Port p : deviceService.getPorts(did)) { 380 for (Port p : deviceService.getPorts(did)) {
381 + if (rules.isSuppressed(p)) {
382 + continue;
383 + }
290 if (!p.number().isLogical()) { 384 if (!p.number().isLogical()) {
291 ld.addPort(p); 385 ld.addPort(p);
292 } 386 }
......
...@@ -344,14 +344,12 @@ public class LinkDiscovery implements TimerTask { ...@@ -344,14 +344,12 @@ public class LinkDiscovery implements TimerTask {
344 } 344 }
345 345
346 private void sendProbes(Long portNumber) { 346 private void sendProbes(Long portNumber) {
347 - if (device.type() != Device.Type.ROADM) { 347 + log.trace("Sending probes out to {}@{}", portNumber, device.id());
348 - log.trace("Sending probes out to {}@{}", portNumber, device.id()); 348 + OutboundPacket pkt = this.createOutBoundLLDP(portNumber);
349 - OutboundPacket pkt = this.createOutBoundLLDP(portNumber); 349 + pktService.emit(pkt);
350 - pktService.emit(pkt); 350 + if (useBDDP) {
351 - if (useBDDP) { 351 + OutboundPacket bpkt = this.createOutBoundBDDP(portNumber);
352 - OutboundPacket bpkt = this.createOutBoundBDDP(portNumber); 352 + pktService.emit(bpkt);
353 - pktService.emit(bpkt);
354 - }
355 } 353 }
356 } 354 }
357 355
......
1 +/*
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 + */
16 +
17 +package org.onosproject.provider.lldp.impl;
18 +
19 +import java.util.Map;
20 +import java.util.Map.Entry;
21 +import java.util.Set;
22 +
23 +import org.onosproject.net.Annotations;
24 +import org.onosproject.net.Device;
25 +import org.onosproject.net.DeviceId;
26 +import org.onosproject.net.Element;
27 +import org.onosproject.net.Port;
28 +
29 +import com.google.common.collect.ImmutableMap;
30 +import com.google.common.collect.ImmutableSet;
31 +
32 +public class SuppressionRules {
33 +
34 + public static final String ANY_VALUE = "(any)";
35 +
36 + private final Set<DeviceId> suppressedDevice;
37 + private final Set<Device.Type> suppressedDeviceType;
38 + private final Map<String, String> suppressedAnnotation;
39 +
40 + public SuppressionRules(Set<DeviceId> suppressedDevice,
41 + Set<Device.Type> suppressedType,
42 + Map<String, String> suppressedAnnotation) {
43 +
44 + this.suppressedDevice = ImmutableSet.copyOf(suppressedDevice);
45 + this.suppressedDeviceType = ImmutableSet.copyOf(suppressedType);
46 + this.suppressedAnnotation = ImmutableMap.copyOf(suppressedAnnotation);
47 + }
48 +
49 + public boolean isSuppressed(Device device) {
50 + if (suppressedDevice.contains(device.id())) {
51 + return true;
52 + }
53 + if (suppressedDeviceType.contains(device.type())) {
54 + return true;
55 + }
56 + final Annotations annotations = device.annotations();
57 + if (containsSuppressionAnnotation(annotations)) {
58 + return true;
59 + }
60 + return false;
61 + }
62 +
63 + public boolean isSuppressed(Port port) {
64 + Element parent = port.element();
65 + if (parent instanceof Device) {
66 + if (isSuppressed((Device) parent)) {
67 + return true;
68 + }
69 + }
70 +
71 + final Annotations annotations = port.annotations();
72 + if (containsSuppressionAnnotation(annotations)) {
73 + return true;
74 + }
75 + return false;
76 + }
77 +
78 + private boolean containsSuppressionAnnotation(final Annotations annotations) {
79 + for (Entry<String, String> entry : suppressedAnnotation.entrySet()) {
80 + final String suppValue = entry.getValue();
81 + final String suppKey = entry.getKey();
82 + if (suppValue == ANY_VALUE) {
83 + if (annotations.keys().contains(suppKey)) {
84 + return true;
85 + }
86 + } else {
87 + if (suppValue.equals(annotations.value(suppKey))) {
88 + return true;
89 + }
90 + }
91 + }
92 + return false;
93 + }
94 +
95 + Set<DeviceId> getSuppressedDevice() {
96 + return suppressedDevice;
97 + }
98 +
99 + Set<Device.Type> getSuppressedDeviceType() {
100 + return suppressedDeviceType;
101 + }
102 +
103 + Map<String, String> getSuppressedAnnotation() {
104 + return suppressedAnnotation;
105 + }
106 +}
1 +/*
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 + */
16 +package org.onosproject.provider.lldp.impl;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +import static org.slf4j.LoggerFactory.getLogger;
20 +
21 +import com.fasterxml.jackson.core.JsonEncoding;
22 +import com.fasterxml.jackson.core.JsonFactory;
23 +import com.fasterxml.jackson.databind.JsonNode;
24 +import com.fasterxml.jackson.databind.ObjectMapper;
25 +import com.fasterxml.jackson.databind.node.ArrayNode;
26 +import com.fasterxml.jackson.databind.node.ObjectNode;
27 +
28 +import org.onosproject.net.Device;
29 +import org.onosproject.net.DeviceId;
30 +import org.slf4j.Logger;
31 +
32 +import java.io.File;
33 +import java.io.IOException;
34 +import java.util.EnumSet;
35 +import java.util.HashMap;
36 +import java.util.HashSet;
37 +import java.util.Iterator;
38 +import java.util.Map;
39 +import java.util.Map.Entry;
40 +import java.util.Set;
41 +
42 +/*
43 + * JSON file example
44 + *
45 +
46 +{
47 + "deviceId" : [ "of:2222000000000000" ],
48 + "deviceType" : [ "ROADM" ],
49 + "annotation" : { "no-lldp" : null, "sendLLDP" : "false" }
50 +}
51 + */
52 +
53 +/**
54 + * Allows for reading and writing LLDP suppression definition as a JSON file.
55 + */
56 +public class SuppressionRulesStore {
57 +
58 + private static final String DEVICE_ID = "deviceId";
59 + private static final String DEVICE_TYPE = "deviceType";
60 + private static final String ANNOTATION = "annotation";
61 +
62 + private final Logger log = getLogger(getClass());
63 +
64 + private final File file;
65 +
66 + /**
67 + * Creates a reader/writer of the LLDP suppression definition file.
68 + *
69 + * @param filePath location of the definition file
70 + */
71 + public SuppressionRulesStore(String filePath) {
72 + file = new File(filePath);
73 + }
74 +
75 + /**
76 + * Creates a reader/writer of the LLDP suppression definition file.
77 + *
78 + * @param file definition file
79 + */
80 + public SuppressionRulesStore(File file) {
81 + this.file = checkNotNull(file);
82 + }
83 +
84 + /**
85 + * Returns SuppressionRules.
86 + *
87 + * @return SuppressionRules
88 + * @throws IOException
89 + */
90 + public SuppressionRules read() throws IOException {
91 + final Set<DeviceId> suppressedDevice = new HashSet<>();
92 + final EnumSet<Device.Type> suppressedDeviceType = EnumSet.noneOf(Device.Type.class);
93 + final Map<String, String> suppressedAnnotation = new HashMap<>();
94 +
95 + ObjectMapper mapper = new ObjectMapper();
96 + ObjectNode root = (ObjectNode) mapper.readTree(file);
97 +
98 + for (JsonNode deviceId : root.get(DEVICE_ID)) {
99 + if (deviceId.isTextual()) {
100 + suppressedDevice.add(DeviceId.deviceId(deviceId.asText()));
101 + } else {
102 + log.warn("Encountered unexpected JSONNode {} for deviceId", deviceId);
103 + }
104 + }
105 +
106 + for (JsonNode deviceType : root.get(DEVICE_TYPE)) {
107 + if (deviceType.isTextual()) {
108 + suppressedDeviceType.add(Device.Type.valueOf(deviceType.asText()));
109 + } else {
110 + log.warn("Encountered unexpected JSONNode {} for deviceType", deviceType);
111 + }
112 + }
113 +
114 + JsonNode annotation = root.get(ANNOTATION);
115 + if (annotation.isObject()) {
116 + ObjectNode obj = (ObjectNode) annotation;
117 + Iterator<Entry<String, JsonNode>> it = obj.fields();
118 + while (it.hasNext()) {
119 + Entry<String, JsonNode> entry = it.next();
120 + final String key = entry.getKey();
121 + final JsonNode value = entry.getValue();
122 +
123 + if (value.isValueNode()) {
124 + if (value.isNull()) {
125 + suppressedAnnotation.put(key, SuppressionRules.ANY_VALUE);
126 + } else {
127 + suppressedAnnotation.put(key, value.asText());
128 + }
129 + } else {
130 + log.warn("Encountered unexpected JSON field {} for annotation", entry);
131 + }
132 + }
133 + } else {
134 + log.warn("Encountered unexpected JSONNode {} for annotation", annotation);
135 + }
136 +
137 + return new SuppressionRules(suppressedDevice,
138 + suppressedDeviceType,
139 + suppressedAnnotation);
140 + }
141 +
142 + /**
143 + * Writes the given SuppressionRules.
144 + *
145 + * @param rules SuppressionRules
146 + * @throws IOException
147 + */
148 + public void write(SuppressionRules rules) throws IOException {
149 + ObjectMapper mapper = new ObjectMapper();
150 + ObjectNode root = mapper.createObjectNode();
151 + ArrayNode deviceIds = mapper.createArrayNode();
152 + ArrayNode deviceTypes = mapper.createArrayNode();
153 + ObjectNode annotations = mapper.createObjectNode();
154 + root.set(DEVICE_ID, deviceIds);
155 + root.set(DEVICE_TYPE, deviceTypes);
156 + root.set(ANNOTATION, annotations);
157 +
158 + rules.getSuppressedDevice()
159 + .forEach(deviceId -> deviceIds.add(deviceId.toString()));
160 +
161 + rules.getSuppressedDeviceType()
162 + .forEach(type -> deviceTypes.add(type.toString()));
163 +
164 + rules.getSuppressedAnnotation().forEach((key, value) -> {
165 + if (value == SuppressionRules.ANY_VALUE) {
166 + annotations.putNull(key);
167 + } else {
168 + annotations.put(key, value);
169 + }
170 + });
171 + mapper.writeTree(new JsonFactory().createGenerator(file, JsonEncoding.UTF8),
172 + root);
173 + }
174 +}
1 +/*
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 + */
16 +
17 +package org.onosproject.provider.lldp.impl;
18 +
19 +import static org.junit.Assert.*;
20 +import static org.onosproject.net.DeviceId.deviceId;
21 +
22 +import java.io.File;
23 +import java.io.IOException;
24 +import java.net.URISyntaxException;
25 +import java.nio.file.Path;
26 +import java.nio.file.Paths;
27 +
28 +import org.junit.Rule;
29 +import org.junit.Test;
30 +import org.junit.rules.TemporaryFolder;
31 +import org.onosproject.net.Device;
32 +
33 +import com.google.common.collect.ImmutableMap;
34 +import com.google.common.collect.ImmutableSet;
35 +import com.google.common.io.Resources;
36 +
37 +public class SuppressionRulesStoreTest {
38 +
39 + @Rule
40 + public TemporaryFolder tempFolder = new TemporaryFolder();
41 +
42 + // "lldp_suppression.json"
43 + SuppressionRules testData
44 + = new SuppressionRules(ImmutableSet.of(deviceId("of:2222000000000000")),
45 + ImmutableSet.of(Device.Type.ROADM),
46 + ImmutableMap.of("no-lldp", SuppressionRules.ANY_VALUE,
47 + "sendLLDP", "false"));
48 +
49 + private static void assertRulesEqual(SuppressionRules expected, SuppressionRules actual) {
50 + assertEquals(expected.getSuppressedDevice(),
51 + actual.getSuppressedDevice());
52 + assertEquals(expected.getSuppressedDeviceType(),
53 + actual.getSuppressedDeviceType());
54 + assertEquals(expected.getSuppressedAnnotation(),
55 + actual.getSuppressedAnnotation());
56 + }
57 +
58 + @Test
59 + public void testRead() throws URISyntaxException, IOException {
60 + Path path = Paths.get(Resources.getResource("lldp_suppression.json").toURI());
61 +
62 + SuppressionRulesStore store = new SuppressionRulesStore(path.toString());
63 +
64 + SuppressionRules rules = store.read();
65 +
66 + assertRulesEqual(testData, rules);
67 + }
68 +
69 + @Test
70 + public void testWrite() throws IOException {
71 + File newFile = tempFolder.newFile();
72 + SuppressionRulesStore store = new SuppressionRulesStore(newFile);
73 + store.write(testData);
74 +
75 + SuppressionRulesStore reload = new SuppressionRulesStore(newFile);
76 + SuppressionRules rules = reload.read();
77 +
78 + assertRulesEqual(testData, rules);
79 + }
80 +}
1 +package org.onosproject.provider.lldp.impl;
2 +
3 +import static org.junit.Assert.*;
4 +import static org.onosproject.net.DeviceId.deviceId;
5 +
6 +import org.junit.Before;
7 +import org.junit.Test;
8 +import org.onlab.packet.ChassisId;
9 +import org.onosproject.net.Annotations;
10 +import org.onosproject.net.DefaultAnnotations;
11 +import org.onosproject.net.DefaultDevice;
12 +import org.onosproject.net.DefaultPort;
13 +import org.onosproject.net.Device;
14 +import org.onosproject.net.DeviceId;
15 +import org.onosproject.net.Port;
16 +import org.onosproject.net.PortNumber;
17 +import org.onosproject.net.provider.ProviderId;
18 +
19 +import com.google.common.collect.ImmutableMap;
20 +import com.google.common.collect.ImmutableSet;
21 +
22 +public class SuppressionRulesTest {
23 +
24 + private static final DeviceId NON_SUPPRESSED_DID = deviceId("of:1111000000000000");
25 + private static final DeviceId SUPPRESSED_DID = deviceId("of:2222000000000000");
26 + private static final ProviderId PID = new ProviderId("of", "foo");
27 + private static final String MFR = "whitebox";
28 + private static final String HW = "1.1.x";
29 + private static final String SW1 = "3.8.1";
30 + private static final String SN = "43311-12345";
31 + private static final ChassisId CID = new ChassisId();
32 +
33 + private static final PortNumber P1 = PortNumber.portNumber(1);
34 +
35 + private SuppressionRules rules;
36 +
37 + @Before
38 + public void setUp() throws Exception {
39 + rules = new SuppressionRules(ImmutableSet.of(SUPPRESSED_DID),
40 + ImmutableSet.of(Device.Type.ROADM),
41 + ImmutableMap.of("no-lldp", SuppressionRules.ANY_VALUE,
42 + "sendLLDP", "false"));
43 + }
44 +
45 + @Test
46 + public void testSuppressedDeviceId() {
47 + Device device = new DefaultDevice(PID,
48 + SUPPRESSED_DID,
49 + Device.Type.SWITCH,
50 + MFR, HW, SW1, SN, CID);
51 + assertTrue(rules.isSuppressed(device));
52 + }
53 +
54 + @Test
55 + public void testSuppressedDeviceType() {
56 + Device device = new DefaultDevice(PID,
57 + NON_SUPPRESSED_DID,
58 + Device.Type.ROADM,
59 + MFR, HW, SW1, SN, CID);
60 + assertTrue(rules.isSuppressed(device));
61 + }
62 +
63 + @Test
64 + public void testSuppressedDeviceAnnotation() {
65 + Annotations annotation = DefaultAnnotations.builder()
66 + .set("no-lldp", "random")
67 + .build();
68 +
69 + Device device = new DefaultDevice(PID,
70 + NON_SUPPRESSED_DID,
71 + Device.Type.SWITCH,
72 + MFR, HW, SW1, SN, CID, annotation);
73 + assertTrue(rules.isSuppressed(device));
74 + }
75 +
76 + @Test
77 + public void testSuppressedDeviceAnnotationExact() {
78 + Annotations annotation = DefaultAnnotations.builder()
79 + .set("sendLLDP", "false")
80 + .build();
81 +
82 + Device device = new DefaultDevice(PID,
83 + NON_SUPPRESSED_DID,
84 + Device.Type.SWITCH,
85 + MFR, HW, SW1, SN, CID, annotation);
86 + assertTrue(rules.isSuppressed(device));
87 + }
88 +
89 + @Test
90 + public void testNotSuppressedDevice() {
91 + Device device = new DefaultDevice(PID,
92 + NON_SUPPRESSED_DID,
93 + Device.Type.SWITCH,
94 + MFR, HW, SW1, SN, CID);
95 + assertFalse(rules.isSuppressed(device));
96 + }
97 +
98 + @Test
99 + public void testSuppressedPortOnSuppressedDevice() {
100 + Device device = new DefaultDevice(PID,
101 + SUPPRESSED_DID,
102 + Device.Type.SWITCH,
103 + MFR, HW, SW1, SN, CID);
104 + Port port = new DefaultPort(device, P1, true);
105 +
106 + assertTrue(rules.isSuppressed(port));
107 + }
108 +
109 + @Test
110 + public void testSuppressedPortAnnotation() {
111 + Annotations annotation = DefaultAnnotations.builder()
112 + .set("no-lldp", "random")
113 + .build();
114 + Device device = new DefaultDevice(PID,
115 + NON_SUPPRESSED_DID,
116 + Device.Type.SWITCH,
117 + MFR, HW, SW1, SN, CID);
118 + Port port = new DefaultPort(device, P1, true, annotation);
119 +
120 + assertTrue(rules.isSuppressed(port));
121 + }
122 +
123 + @Test
124 + public void testSuppressedPortAnnotationExact() {
125 + Annotations annotation = DefaultAnnotations.builder()
126 + .set("sendLLDP", "false")
127 + .build();
128 + Device device = new DefaultDevice(PID,
129 + NON_SUPPRESSED_DID,
130 + Device.Type.SWITCH,
131 + MFR, HW, SW1, SN, CID);
132 + Port port = new DefaultPort(device, P1, true, annotation);
133 +
134 + assertTrue(rules.isSuppressed(port));
135 + }
136 +
137 + @Test
138 + public void testNotSuppressedPort() {
139 + Device device = new DefaultDevice(PID,
140 + NON_SUPPRESSED_DID,
141 + Device.Type.SWITCH,
142 + MFR, HW, SW1, SN, CID);
143 + Port port = new DefaultPort(device, P1, true);
144 +
145 + assertFalse(rules.isSuppressed(port));
146 + }
147 +}
1 +{
2 + "deviceId" : [ "of:2222000000000000" ],
3 + "deviceType" : [ "ROADM" ],
4 + "annotation" : { "no-lldp" : null, "sendLLDP" : "false" }
5 +}
6 +