alshabib

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Conflicts:
	core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java

Change-Id: I23a7b1bff399c95499a39f7a00563650f58b7210
Showing 92 changed files with 2077 additions and 226 deletions
...@@ -4,19 +4,17 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -4,19 +4,17 @@ import static com.google.common.base.Preconditions.checkNotNull;
4 4
5 import java.util.Set; 5 import java.util.Set;
6 6
7 -import org.apache.commons.lang.NotImplementedException;
8 import org.onlab.onos.net.ConnectPoint; 7 import org.onlab.onos.net.ConnectPoint;
9 import org.onlab.onos.net.host.HostService; 8 import org.onlab.onos.net.host.HostService;
10 import org.onlab.onos.net.host.PortAddresses; 9 import org.onlab.onos.net.host.PortAddresses;
11 import org.onlab.onos.sdnip.config.Interface; 10 import org.onlab.onos.sdnip.config.Interface;
12 import org.onlab.packet.IpAddress; 11 import org.onlab.packet.IpAddress;
12 +import org.onlab.packet.IpPrefix;
13 13
14 import com.google.common.collect.Sets; 14 import com.google.common.collect.Sets;
15 15
16 -
17 -
18 /** 16 /**
19 - * Provides IntefaceService using PortAddresses data from the HostService. 17 + * Provides InterfaceService using PortAddresses data from the HostService.
20 */ 18 */
21 public class HostToInterfaceAdaptor implements InterfaceService { 19 public class HostToInterfaceAdaptor implements InterfaceService {
22 20
...@@ -52,8 +50,17 @@ public class HostToInterfaceAdaptor implements InterfaceService { ...@@ -52,8 +50,17 @@ public class HostToInterfaceAdaptor implements InterfaceService {
52 50
53 @Override 51 @Override
54 public Interface getMatchingInterface(IpAddress ipAddress) { 52 public Interface getMatchingInterface(IpAddress ipAddress) {
55 - // TODO implement 53 + checkNotNull(ipAddress);
56 - throw new NotImplementedException("getMatchingInteface is not yet implemented"); 54 +
55 + for (PortAddresses portAddresses : hostService.getAddressBindings()) {
56 + for (IpPrefix p : portAddresses.ips()) {
57 + if (p.contains(ipAddress)) {
58 + return new Interface(portAddresses);
59 + }
60 + }
61 + }
62 +
63 + return null;
57 } 64 }
58 65
59 } 66 }
......
...@@ -64,6 +64,7 @@ public class SdnIp implements SdnIpService { ...@@ -64,6 +64,7 @@ public class SdnIp implements SdnIpService {
64 bgpSessionManager.startUp(2000); // TODO 64 bgpSessionManager.startUp(2000); // TODO
65 65
66 // TODO need to disable link discovery on external ports 66 // TODO need to disable link discovery on external ports
67 +
67 } 68 }
68 69
69 @Deactivate 70 @Deactivate
......
1 +package org.onlab.onos.sdnip;
2 +
3 +import static org.easymock.EasyMock.createMock;
4 +import static org.easymock.EasyMock.expect;
5 +import static org.easymock.EasyMock.replay;
6 +import static org.easymock.EasyMock.reset;
7 +import static org.junit.Assert.assertEquals;
8 +import static org.junit.Assert.assertNull;
9 +import static org.junit.Assert.assertTrue;
10 +
11 +import java.util.Map;
12 +import java.util.Set;
13 +
14 +import org.junit.Before;
15 +import org.junit.Test;
16 +import org.onlab.onos.net.ConnectPoint;
17 +import org.onlab.onos.net.DeviceId;
18 +import org.onlab.onos.net.PortNumber;
19 +import org.onlab.onos.net.host.HostService;
20 +import org.onlab.onos.net.host.PortAddresses;
21 +import org.onlab.onos.sdnip.config.Interface;
22 +import org.onlab.packet.IpAddress;
23 +import org.onlab.packet.IpPrefix;
24 +import org.onlab.packet.MacAddress;
25 +
26 +import com.google.common.collect.Maps;
27 +import com.google.common.collect.Sets;
28 +
29 +/**
30 + * Unit tests for the HostToInterfaceAdaptor class.
31 + */
32 +public class HostToInterfaceAdaptorTest {
33 +
34 + private HostService hostService;
35 + private HostToInterfaceAdaptor adaptor;
36 +
37 + private Set<PortAddresses> portAddresses;
38 + private Map<ConnectPoint, Interface> interfaces;
39 +
40 + private static final ConnectPoint CP1 = new ConnectPoint(
41 + DeviceId.deviceId("of:1"), PortNumber.portNumber(1));
42 + private static final ConnectPoint CP2 = new ConnectPoint(
43 + DeviceId.deviceId("of:1"), PortNumber.portNumber(2));
44 + private static final ConnectPoint CP3 = new ConnectPoint(
45 + DeviceId.deviceId("of:2"), PortNumber.portNumber(1));
46 +
47 + private static final ConnectPoint NON_EXISTENT_CP = new ConnectPoint(
48 + DeviceId.deviceId("doesnotexist"), PortNumber.portNumber(1));
49 +
50 + private static final PortAddresses DEFAULT_PA = new PortAddresses(
51 + NON_EXISTENT_CP, null, null);
52 +
53 +
54 + @Before
55 + public void setUp() throws Exception {
56 + hostService = createMock(HostService.class);
57 +
58 + portAddresses = Sets.newHashSet();
59 + interfaces = Maps.newHashMap();
60 +
61 + createPortAddressesAndInterface(CP1,
62 + Sets.newHashSet(IpPrefix.valueOf("192.168.1.1/24")),
63 + MacAddress.valueOf("00:00:00:00:00:01"));
64 +
65 + // Two addresses in the same subnet
66 + createPortAddressesAndInterface(CP2,
67 + Sets.newHashSet(IpPrefix.valueOf("192.168.2.1/24"),
68 + IpPrefix.valueOf("192.168.2.2/24")),
69 + MacAddress.valueOf("00:00:00:00:00:02"));
70 +
71 + // Two addresses in different subnets
72 + createPortAddressesAndInterface(CP3,
73 + Sets.newHashSet(IpPrefix.valueOf("192.168.3.1/24"),
74 + IpPrefix.valueOf("192.168.4.1/24")),
75 + MacAddress.valueOf("00:00:00:00:00:03"));
76 +
77 + expect(hostService.getAddressBindings()).andReturn(portAddresses).anyTimes();
78 +
79 + replay(hostService);
80 +
81 + adaptor = new HostToInterfaceAdaptor(hostService);
82 + }
83 +
84 + /**
85 + * Creates both a PortAddresses and an Interface for the given inputs and
86 + * places them in the correct global data stores.
87 + *
88 + * @param cp the connect point
89 + * @param ips the set of IP addresses
90 + * @param mac the MAC address
91 + */
92 + private void createPortAddressesAndInterface(
93 + ConnectPoint cp, Set<IpPrefix> ips, MacAddress mac) {
94 + PortAddresses pa = new PortAddresses(cp, ips, mac);
95 + portAddresses.add(pa);
96 + expect(hostService.getAddressBindingsForPort(cp)).andReturn(pa).anyTimes();
97 +
98 + Interface intf = new Interface(cp, ips, mac);
99 + interfaces.put(cp, intf);
100 + }
101 +
102 + /**
103 + * Tests {@link HostToInterfaceAdaptor#getInterfaces()}.
104 + * Verifies that the set of interfaces returned matches what is expected
105 + * based on the input PortAddresses data.
106 + */
107 + @Test
108 + public void testGetInterfaces() {
109 + Set<Interface> adaptorIntfs = adaptor.getInterfaces();
110 +
111 + assertEquals(3, adaptorIntfs.size());
112 + assertTrue(adaptorIntfs.contains(this.interfaces.get(CP1)));
113 + assertTrue(adaptorIntfs.contains(this.interfaces.get(CP2)));
114 + assertTrue(adaptorIntfs.contains(this.interfaces.get(CP3)));
115 + }
116 +
117 + /**
118 + * Tests {@link HostToInterfaceAdaptor#getInterface(ConnectPoint)}.
119 + * Verifies that the correct interface is returned for a given connect
120 + * point.
121 + */
122 + @Test
123 + public void testGetInterface() {
124 + assertEquals(this.interfaces.get(CP1), adaptor.getInterface(CP1));
125 + assertEquals(this.interfaces.get(CP2), adaptor.getInterface(CP2));
126 + assertEquals(this.interfaces.get(CP3), adaptor.getInterface(CP3));
127 +
128 + // Try and get an interface for a connect point with no addresses
129 + reset(hostService);
130 + expect(hostService.getAddressBindingsForPort(NON_EXISTENT_CP))
131 + .andReturn(DEFAULT_PA).anyTimes();
132 + replay(hostService);
133 +
134 + assertNull(adaptor.getInterface(NON_EXISTENT_CP));
135 + }
136 +
137 + /**
138 + * Tests {@link HostToInterfaceAdaptor#getInterface(ConnectPoint)} in the
139 + * case that the input connect point is null.
140 + * Verifies that a NullPointerException is thrown.
141 + */
142 + @Test(expected = NullPointerException.class)
143 + public void testGetInterfaceNull() {
144 + adaptor.getInterface(null);
145 + }
146 +
147 + /**
148 + * Tests {@link HostToInterfaceAdaptor#getMatchingInterface(IpAddress)}.
149 + * Verifies that the correct interface is returned based on the given IP
150 + * address.
151 + */
152 + @Test
153 + public void testGetMatchingInterface() {
154 + assertEquals(this.interfaces.get(CP1),
155 + adaptor.getMatchingInterface(IpAddress.valueOf("192.168.1.100")));
156 + assertEquals(this.interfaces.get(CP2),
157 + adaptor.getMatchingInterface(IpAddress.valueOf("192.168.2.100")));
158 + assertEquals(this.interfaces.get(CP3),
159 + adaptor.getMatchingInterface(IpAddress.valueOf("192.168.3.100")));
160 + assertEquals(this.interfaces.get(CP3),
161 + adaptor.getMatchingInterface(IpAddress.valueOf("192.168.4.100")));
162 +
163 + // Try and match an address we don't have subnet configured for
164 + assertNull(adaptor.getMatchingInterface(IpAddress.valueOf("1.1.1.1")));
165 + }
166 +
167 + /**
168 + * Tests {@link HostToInterfaceAdaptor#getMatchingInterface(IpAddress)} in the
169 + * case that the input IP address is null.
170 + * Verifies that a NullPointerException is thrown.
171 + */
172 + @Test(expected = NullPointerException.class)
173 + public void testGetMatchingInterfaceNull() {
174 + adaptor.getMatchingInterface(null);
175 + }
176 +
177 +}
...@@ -18,10 +18,13 @@ ...@@ -18,10 +18,13 @@
18 */ 18 */
19 package org.onlab.onos.cli; 19 package org.onlab.onos.cli;
20 20
21 +import com.fasterxml.jackson.databind.ObjectMapper;
22 +import com.fasterxml.jackson.databind.node.ObjectNode;
21 import org.apache.karaf.shell.commands.Option; 23 import org.apache.karaf.shell.commands.Option;
22 import org.apache.karaf.shell.console.OsgiCommandSupport; 24 import org.apache.karaf.shell.console.OsgiCommandSupport;
23 import org.onlab.onos.ApplicationId; 25 import org.onlab.onos.ApplicationId;
24 import org.onlab.onos.CoreService; 26 import org.onlab.onos.CoreService;
27 +import org.onlab.onos.net.Annotations;
25 import org.onlab.osgi.DefaultServiceDirectory; 28 import org.onlab.osgi.DefaultServiceDirectory;
26 import org.onlab.osgi.ServiceNotFoundException; 29 import org.onlab.osgi.ServiceNotFoundException;
27 30
...@@ -76,6 +79,34 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { ...@@ -76,6 +79,34 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport {
76 } 79 }
77 80
78 /** 81 /**
82 + * Produces a string image of the specified key/value annotations.
83 + *
84 + * @param annotations key/value annotations
85 + * @return string image with ", k1=v1, k2=v2, ..." pairs
86 + */
87 + public static String annotations(Annotations annotations) {
88 + StringBuilder sb = new StringBuilder();
89 + for (String key : annotations.keys()) {
90 + sb.append(", ").append(key).append('=').append(annotations.value(key));
91 + }
92 + return sb.toString();
93 + }
94 +
95 + /**
96 + * Produces a JSON object from the specified key/value annotations.
97 + *
98 + * @param annotations key/value annotations
99 + * @return JSON object
100 + */
101 + public static ObjectNode annotations(ObjectMapper mapper, Annotations annotations) {
102 + ObjectNode result = mapper.createObjectNode();
103 + for (String key : annotations.keys()) {
104 + result.put(key, annotations.value(key));
105 + }
106 + return result;
107 + }
108 +
109 + /**
79 * Executes this command. 110 * Executes this command.
80 */ 111 */
81 protected abstract void execute(); 112 protected abstract void execute();
......
...@@ -43,7 +43,7 @@ import static org.onlab.onos.net.DeviceId.deviceId; ...@@ -43,7 +43,7 @@ import static org.onlab.onos.net.DeviceId.deviceId;
43 description = "Lists all ports or all ports of a device") 43 description = "Lists all ports or all ports of a device")
44 public class DevicePortsListCommand extends DevicesListCommand { 44 public class DevicePortsListCommand extends DevicesListCommand {
45 45
46 - private static final String FMT = " port=%s, state=%s"; 46 + private static final String FMT = " port=%s, state=%s%s";
47 47
48 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports", 48 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports",
49 required = false, multiValued = false) 49 required = false, multiValued = false)
...@@ -112,7 +112,8 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -112,7 +112,8 @@ public class DevicePortsListCommand extends DevicesListCommand {
112 if (isIncluded(port)) { 112 if (isIncluded(port)) {
113 ports.add(mapper.createObjectNode() 113 ports.add(mapper.createObjectNode()
114 .put("port", port.number().toString()) 114 .put("port", port.number().toString())
115 - .put("isEnabled", port.isEnabled())); 115 + .put("isEnabled", port.isEnabled())
116 + .set("annotations", annotations(mapper, port.annotations())));
116 } 117 }
117 } 118 }
118 return result.put("device", device.id().toString()).set("ports", ports); 119 return result.put("device", device.id().toString()).set("ports", ports);
...@@ -131,7 +132,8 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -131,7 +132,8 @@ public class DevicePortsListCommand extends DevicesListCommand {
131 Collections.sort(ports, Comparators.PORT_COMPARATOR); 132 Collections.sort(ports, Comparators.PORT_COMPARATOR);
132 for (Port port : ports) { 133 for (Port port : ports) {
133 if (isIncluded(port)) { 134 if (isIncluded(port)) {
134 - print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled"); 135 + print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled",
136 + annotations(port.annotations()));
135 } 137 }
136 } 138 }
137 } 139 }
......
...@@ -41,7 +41,7 @@ import static com.google.common.collect.Lists.newArrayList; ...@@ -41,7 +41,7 @@ import static com.google.common.collect.Lists.newArrayList;
41 public class DevicesListCommand extends AbstractShellCommand { 41 public class DevicesListCommand extends AbstractShellCommand {
42 42
43 private static final String FMT = 43 private static final String FMT =
44 - "id=%s, available=%s, role=%s, type=%s, mfr=%s, hw=%s, sw=%s, serial=%s"; 44 + "id=%s, available=%s, role=%s, type=%s, mfr=%s, hw=%s, sw=%s, serial=%s%s";
45 45
46 @Override 46 @Override
47 protected void execute() { 47 protected void execute() {
...@@ -89,7 +89,8 @@ public class DevicesListCommand extends AbstractShellCommand { ...@@ -89,7 +89,8 @@ public class DevicesListCommand extends AbstractShellCommand {
89 .put("mfr", device.manufacturer()) 89 .put("mfr", device.manufacturer())
90 .put("hw", device.hwVersion()) 90 .put("hw", device.hwVersion())
91 .put("sw", device.swVersion()) 91 .put("sw", device.swVersion())
92 - .put("serial", device.serialNumber()); 92 + .put("serial", device.serialNumber())
93 + .set("annotations", annotations(mapper, device.annotations()));
93 } 94 }
94 return result; 95 return result;
95 } 96 }
...@@ -117,7 +118,7 @@ public class DevicesListCommand extends AbstractShellCommand { ...@@ -117,7 +118,7 @@ public class DevicesListCommand extends AbstractShellCommand {
117 print(FMT, device.id(), service.isAvailable(device.id()), 118 print(FMT, device.id(), service.isAvailable(device.id()),
118 service.getRole(device.id()), device.type(), 119 service.getRole(device.id()), device.type(),
119 device.manufacturer(), device.hwVersion(), device.swVersion(), 120 device.manufacturer(), device.hwVersion(), device.swVersion(),
120 - device.serialNumber()); 121 + device.serialNumber(), annotations(device.annotations()));
121 } 122 }
122 } 123 }
123 124
......
...@@ -42,7 +42,7 @@ import static com.google.common.collect.Lists.newArrayList; ...@@ -42,7 +42,7 @@ import static com.google.common.collect.Lists.newArrayList;
42 public class HostsListCommand extends AbstractShellCommand { 42 public class HostsListCommand extends AbstractShellCommand {
43 43
44 private static final String FMT = 44 private static final String FMT =
45 - "id=%s, mac=%s, location=%s/%s, vlan=%s, ip(s)=%s"; 45 + "id=%s, mac=%s, location=%s/%s, vlan=%s, ip(s)=%s%s";
46 46
47 @Override 47 @Override
48 protected void execute() { 48 protected void execute() {
...@@ -80,6 +80,7 @@ public class HostsListCommand extends AbstractShellCommand { ...@@ -80,6 +80,7 @@ public class HostsListCommand extends AbstractShellCommand {
80 .put("vlan", host.vlan().toString()); 80 .put("vlan", host.vlan().toString());
81 result.set("location", loc); 81 result.set("location", loc);
82 result.set("ips", ips); 82 result.set("ips", ips);
83 + result.set("annotations", annotations(mapper, host.annotations()));
83 return result; 84 return result;
84 } 85 }
85 86
...@@ -105,7 +106,8 @@ public class HostsListCommand extends AbstractShellCommand { ...@@ -105,7 +106,8 @@ public class HostsListCommand extends AbstractShellCommand {
105 print(FMT, host.id(), host.mac(), 106 print(FMT, host.id(), host.mac(),
106 host.location().deviceId(), 107 host.location().deviceId(),
107 host.location().port(), 108 host.location().port(),
108 - host.vlan(), host.ipAddresses()); 109 + host.vlan(), host.ipAddresses(),
110 + annotations(host.annotations()));
109 } 111 }
110 } 112 }
111 } 113 }
......
...@@ -38,7 +38,7 @@ import static org.onlab.onos.net.DeviceId.deviceId; ...@@ -38,7 +38,7 @@ import static org.onlab.onos.net.DeviceId.deviceId;
38 description = "Lists all infrastructure links") 38 description = "Lists all infrastructure links")
39 public class LinksListCommand extends AbstractShellCommand { 39 public class LinksListCommand extends AbstractShellCommand {
40 40
41 - private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s"; 41 + private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s%s";
42 private static final String COMPACT = "%s/%s-%s/%s"; 42 private static final String COMPACT = "%s/%s-%s/%s";
43 43
44 @Argument(index = 0, name = "uri", description = "Device ID", 44 @Argument(index = 0, name = "uri", description = "Device ID",
...@@ -85,6 +85,7 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -85,6 +85,7 @@ public class LinksListCommand extends AbstractShellCommand {
85 ObjectNode result = mapper.createObjectNode(); 85 ObjectNode result = mapper.createObjectNode();
86 result.set("src", json(mapper, link.src())); 86 result.set("src", json(mapper, link.src()));
87 result.set("dst", json(mapper, link.dst())); 87 result.set("dst", json(mapper, link.dst()));
88 + result.set("annotations", annotations(mapper, link.annotations()));
88 return result; 89 return result;
89 } 90 }
90 91
...@@ -109,7 +110,8 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -109,7 +110,8 @@ public class LinksListCommand extends AbstractShellCommand {
109 */ 110 */
110 public static String linkString(Link link) { 111 public static String linkString(Link link) {
111 return String.format(FMT, link.src().deviceId(), link.src().port(), 112 return String.format(FMT, link.src().deviceId(), link.src().port(),
112 - link.dst().deviceId(), link.dst().port(), link.type()); 113 + link.dst().deviceId(), link.dst().port(), link.type(),
114 + annotations(link.annotations()));
113 } 115 }
114 116
115 /** 117 /**
......
...@@ -13,7 +13,7 @@ public interface DeviceProvider extends Provider { ...@@ -13,7 +13,7 @@ public interface DeviceProvider extends Provider {
13 13
14 /** 14 /**
15 * Triggers an asynchronous probe of the specified device, intended to 15 * Triggers an asynchronous probe of the specified device, intended to
16 - * determine whether the host is present or not. An indirect result of this 16 + * determine whether the device is present or not. An indirect result of this
17 * should be invocation of 17 * should be invocation of
18 * {@link org.onlab.onos.net.device.DeviceProviderService#deviceConnected} )} or 18 * {@link org.onlab.onos.net.device.DeviceProviderService#deviceConnected} )} or
19 * {@link org.onlab.onos.net.device.DeviceProviderService#deviceDisconnected} 19 * {@link org.onlab.onos.net.device.DeviceProviderService#deviceDisconnected}
......
1 -package org.onlab.onos.net.intent; 1 +/*
2 -//TODO is this the right package? 2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.net.flow;
3 20
4 import static com.google.common.base.Preconditions.checkNotNull; 21 import static com.google.common.base.Preconditions.checkNotNull;
5 22
......
1 -package org.onlab.onos.net.intent; 1 +/*
2 -//TODO is this the right package? 2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.net.flow;
3 20
4 import java.util.Objects; 21 import java.util.Objects;
5 22
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import java.util.List; 21 import java.util.List;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.net.flow;
20 +
21 +/**
22 + * An interface of the class which is assigned to BatchOperation.
23 + */
24 +public interface BatchOperationTarget {
25 +
26 +}
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import java.util.List; 21 import java.util.List;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import static com.google.common.base.MoreObjects.toStringHelper; 21 import static com.google.common.base.MoreObjects.toStringHelper;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import static com.google.common.base.MoreObjects.toStringHelper; 21 import static com.google.common.base.MoreObjects.toStringHelper;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import java.util.HashMap; 21 import java.util.HashMap;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import java.util.LinkedList; 21 import java.util.LinkedList;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 21
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import com.google.common.base.Objects; 21 import com.google.common.base.Objects;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import org.onlab.onos.net.DeviceId; 21 import org.onlab.onos.net.DeviceId;
4 -import org.onlab.onos.net.intent.BatchOperationTarget;
5 22
6 /** 23 /**
7 * Represents a generalized match &amp; action pair to be applied to 24 * Represents a generalized match &amp; action pair to be applied to
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation; 21 import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
4 -import org.onlab.onos.net.intent.BatchOperationEntry;
5 22
6 23
7 public class FlowRuleBatchEntry 24 public class FlowRuleBatchEntry
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import java.util.Collection; 21 import java.util.Collection;
4 22
5 -import org.onlab.onos.net.intent.BatchOperation;
6 -
7 public class FlowRuleBatchOperation 23 public class FlowRuleBatchOperation
8 extends BatchOperation<FlowRuleBatchEntry> { 24 extends BatchOperation<FlowRuleBatchEntry> {
9 25
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import org.onlab.onos.event.AbstractEvent; 21 import org.onlab.onos.event.AbstractEvent;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import org.onlab.onos.event.EventListener; 21 import org.onlab.onos.event.EventListener;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import java.util.concurrent.Future; 21 import java.util.concurrent.Future;
4 22
5 import org.onlab.onos.ApplicationId; 23 import org.onlab.onos.ApplicationId;
6 -import org.onlab.onos.net.intent.BatchOperation;
7 import org.onlab.onos.net.provider.Provider; 24 import org.onlab.onos.net.provider.Provider;
8 25
9 /** 26 /**
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import org.onlab.onos.net.provider.ProviderRegistry; 21 import org.onlab.onos.net.provider.ProviderRegistry;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import org.onlab.onos.net.DeviceId; 21 import org.onlab.onos.net.DeviceId;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import java.util.concurrent.Future; 21 import java.util.concurrent.Future;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import org.onlab.onos.ApplicationId; 21 import org.onlab.onos.ApplicationId;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import org.onlab.onos.store.StoreDelegate; 21 import org.onlab.onos.store.StoreDelegate;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 21
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import java.util.Set; 21 import java.util.Set;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import java.util.List; 21 import java.util.List;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow; 19 package org.onlab.onos.net.flow;
2 20
3 import org.onlab.onos.net.PortNumber; 21 import org.onlab.onos.net.PortNumber;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow.criteria; 19 package org.onlab.onos.net.flow.criteria;
2 20
3 import static com.google.common.base.MoreObjects.toStringHelper; 21 import static com.google.common.base.MoreObjects.toStringHelper;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow.criteria; 19 package org.onlab.onos.net.flow.criteria;
2 20
3 21
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +
1 /** 20 /**
2 * Traffic selection criteria model. 21 * Traffic selection criteria model.
3 */ 22 */
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow.instructions; 19 package org.onlab.onos.net.flow.instructions;
2 20
3 /** 21 /**
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow.instructions; 19 package org.onlab.onos.net.flow.instructions;
2 20
3 import static com.google.common.base.MoreObjects.toStringHelper; 21 import static com.google.common.base.MoreObjects.toStringHelper;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow.instructions; 19 package org.onlab.onos.net.flow.instructions;
2 20
3 import static com.google.common.base.MoreObjects.toStringHelper; 21 import static com.google.common.base.MoreObjects.toStringHelper;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.flow.instructions; 19 package org.onlab.onos.net.flow.instructions;
2 20
3 import static com.google.common.base.MoreObjects.toStringHelper; 21 import static com.google.common.base.MoreObjects.toStringHelper;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +
1 /** 20 /**
2 * Traffic treatment model. 21 * Traffic treatment model.
3 */ 22 */
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +
1 /** 20 /**
2 * Flow rule model &amp; related services API definitions. 21 * Flow rule model &amp; related services API definitions.
3 */ 22 */
......
1 -package org.onlab.onos.net.intent;
2 -//TODO is this the right package?
3 -
4 -/**
5 - * An interface of the class which is assigned to BatchOperation.
6 - */
7 -public interface BatchOperationTarget {
8 -
9 -}
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import com.google.common.collect.ImmutableSet; 21 import com.google.common.collect.ImmutableSet;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import com.google.common.base.MoreObjects; 21 import com.google.common.base.MoreObjects;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import org.onlab.onos.ApplicationId; 21 import org.onlab.onos.ApplicationId;
4 import org.onlab.onos.net.NetworkResource; 22 import org.onlab.onos.net.NetworkResource;
23 +import org.onlab.onos.net.flow.BatchOperationTarget;
5 24
6 import java.util.Collection; 25 import java.util.Collection;
7 import java.util.Objects; 26 import java.util.Objects;
......
1 -package org.onlab.onos.net.intent;
2 -
3 -/**
4 - * A list of intent operations.
5 - */
6 -public class IntentBatchOperation extends
7 - BatchOperation<BatchOperationEntry<IntentBatchOperation.Operator, ?>> {
8 - /**
9 - * The intent operators.
10 - */
11 - public enum Operator {
12 - ADD,
13 - REMOVE,
14 - }
15 -
16 - /**
17 - * Adds an add-intent operation.
18 - *
19 - * @param intent the intent to be added
20 - * @return the IntentBatchOperation object if succeeded, null otherwise
21 - */
22 - public IntentBatchOperation addAddIntentOperation(Intent intent) {
23 - return (null == super.addOperation(
24 - new BatchOperationEntry<Operator, Intent>(Operator.ADD, intent)))
25 - ? null : this;
26 - }
27 -
28 - /**
29 - * Adds a remove-intent operation.
30 - *
31 - * @param id the ID of intent to be removed
32 - * @return the IntentBatchOperation object if succeeded, null otherwise
33 - */
34 - public IntentBatchOperation addRemoveIntentOperation(IntentId id) {
35 - return (null == super.addOperation(
36 - new BatchOperationEntry<Operator, IntentId>(Operator.REMOVE, id)))
37 - ? null : this;
38 - }
39 -}
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import java.util.List; 21 import java.util.List;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import org.onlab.onos.event.AbstractEvent; 21 import org.onlab.onos.event.AbstractEvent;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 /** 21 /**
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import java.util.Map; 21 import java.util.Map;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
21 +import org.onlab.onos.net.flow.BatchOperationTarget;
22 +
3 /** 23 /**
4 * Intent identifier suitable as an external key. 24 * Intent identifier suitable as an external key.
5 * <p/> 25 * <p/>
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import java.util.List; 21 import java.util.List;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import org.onlab.onos.event.EventListener; 21 import org.onlab.onos.event.EventListener;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.net.intent;
20 +
21 +/**
22 + * Abstraction of an intent-related operation, e.g. add, remove, replace.
23 + */
24 +public class IntentOperation {
25 +
26 + private final Type type;
27 + private final IntentId intentId;
28 + private final Intent intent;
29 +
30 + /**
31 + * Operation type.
32 + */
33 + enum Type {
34 + /**
35 + * Indicates that an intent should be added.
36 + */
37 + SUBMIT,
38 +
39 + /**
40 + * Indicates that an intent should be removed.
41 + */
42 + WITHDRAW,
43 +
44 + /**
45 + * Indicates that an intent should be replaced with another.
46 + */
47 + REPLACE
48 + }
49 +
50 + /**
51 + * Creates an intent operation.
52 + *
53 + * @param type operation type
54 + * @param intentId identifier of the intent subject to the operation
55 + * @param intent intent subject
56 + */
57 + IntentOperation(Type type, IntentId intentId, Intent intent) {
58 + this.type = type;
59 + this.intentId = intentId;
60 + this.intent = intent;
61 + }
62 +
63 + /**
64 + * Returns the type of the operation.
65 + *
66 + * @return operation type
67 + */
68 + public Type type() {
69 + return type;
70 + }
71 +
72 + /**
73 + * Returns the identifier of the intent to which this operation applies.
74 + *
75 + * @return intent identifier
76 + */
77 + public IntentId intentId() {
78 + return intentId;
79 + }
80 +
81 + /**
82 + * Returns the intent to which this operation applied. For remove,
83 + * this can be null.
84 + *
85 + * @return intent that is the subject of the operation; null for remove
86 + */
87 + public Intent intent() {
88 + return intent;
89 + }
90 +
91 +}
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
21 +import com.google.common.collect.ImmutableList;
22 +
23 +import java.util.List;
24 +
25 +import static com.google.common.base.Preconditions.checkNotNull;
26 +import static org.onlab.onos.net.intent.IntentOperation.Type.REPLACE;
27 +import static org.onlab.onos.net.intent.IntentOperation.Type.SUBMIT;
28 +import static org.onlab.onos.net.intent.IntentOperation.Type.WITHDRAW;
29 +
3 /** 30 /**
4 - * Abstraction of a batch of intent submit/withdraw operations. 31 + * Batch of intent submit/withdraw/replace operations.
5 */ 32 */
6 -public interface IntentOperations { 33 +public final class IntentOperations {
34 +
35 + private final List<IntentOperation> operations;
36 +
37 + /**
38 + * Creates a batch of intent operations using the supplied list.
39 + *
40 + * @param operations list of intent operations
41 + */
42 + private IntentOperations(List<IntentOperation> operations) {
43 + this.operations = operations;
44 + }
45 +
46 + /**
47 + * List of operations that need to be executed as a unit.
48 + *
49 + * @return list of intent operations
50 + */
51 + public List<IntentOperation> operations() {
52 + return operations;
53 + }
54 +
55 + /**
56 + * Returns a builder for intent operation batches.
57 + *
58 + * @return intent operations builder
59 + */
60 + public static Builder builder() {
61 + return new Builder();
62 + }
63 +
64 + /**
65 + * Builder for batches of intent operations.
66 + */
67 + public static final class Builder {
68 +
69 + private final ImmutableList.Builder<IntentOperation> builder = ImmutableList.builder();
70 +
71 + // Public construction is forbidden.
72 + private Builder() {
73 + }
74 +
75 + /**
76 + * Adds an intent submit operation.
77 + *
78 + * @param intent intent to be submitted
79 + * @return self
80 + */
81 + public Builder addSubmitOperation(Intent intent) {
82 + checkNotNull(intent, "Intent cannot be null");
83 + builder.add(new IntentOperation(SUBMIT, intent.id(), intent));
84 + return this;
85 + }
86 +
87 + /**
88 + * Adds an intent submit operation.
89 + *
90 + * @param oldIntentId intent to be replaced
91 + * @param newIntent replacement intent
92 + * @return self
93 + */
94 + public Builder addReplaceOperation(IntentId oldIntentId, Intent newIntent) {
95 + checkNotNull(oldIntentId, "Intent ID cannot be null");
96 + checkNotNull(newIntent, "Intent cannot be null");
97 + builder.add(new IntentOperation(REPLACE, oldIntentId, newIntent));
98 + return this;
99 + }
100 +
101 + /**
102 + * Adds an intent submit operation.
103 + *
104 + * @param intentId identifier of the intent to be withdrawn
105 + * @return self
106 + */
107 + public Builder addWithdrawOperation(IntentId intentId) {
108 + checkNotNull(intentId, "Intent ID cannot be null");
109 + builder.add(new IntentOperation(WITHDRAW, intentId, null));
110 + return this;
111 + }
7 112
8 - // TODO: elaborate once the revised BatchOperation scheme is in place 113 + /**
114 + * Builds a batch of intent operations.
115 + *
116 + * @return immutable batch of intent operations
117 + */
118 + public IntentOperations build() {
119 + return new IntentOperations(builder.build());
120 + }
9 121
122 + }
10 } 123 }
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 21
4 import java.util.List; 22 import java.util.List;
23 +import java.util.concurrent.Future;
5 24
6 /** 25 /**
7 * Service for application submitting or withdrawing their intents. 26 * Service for application submitting or withdrawing their intents.
...@@ -28,6 +47,14 @@ public interface IntentService { ...@@ -28,6 +47,14 @@ public interface IntentService {
28 void withdraw(Intent intent); 47 void withdraw(Intent intent);
29 48
30 /** 49 /**
50 + * Replaces the specified intent with a new one.
51 + *
52 + * @param oldIntentId identifier of the old intent being replaced
53 + * @param newIntent new intent replacing the old one
54 + */
55 + void replace(IntentId oldIntentId, Intent newIntent);
56 +
57 + /**
31 * Submits a batch of submit &amp; withdraw operations. Such a batch is 58 * Submits a batch of submit &amp; withdraw operations. Such a batch is
32 * assumed to be processed together. 59 * assumed to be processed together.
33 * <p/> 60 * <p/>
...@@ -36,7 +63,7 @@ public interface IntentService { ...@@ -36,7 +63,7 @@ public interface IntentService {
36 * 63 *
37 * @param operations batch of intent operations 64 * @param operations batch of intent operations
38 */ 65 */
39 - void execute(IntentOperations operations); 66 + Future<IntentOperations> execute(IntentOperations operations);
40 67
41 /** 68 /**
42 * Returns an iterable of intents currently in the system. 69 * Returns an iterable of intents currently in the system.
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 /** 21 /**
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import org.onlab.onos.store.Store; 21 import org.onlab.onos.store.Store;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import org.onlab.onos.store.StoreDelegate; 21 import org.onlab.onos.store.StoreDelegate;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import com.google.common.base.MoreObjects; 21 import com.google.common.base.MoreObjects;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import com.google.common.base.MoreObjects; 21 import com.google.common.base.MoreObjects;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import com.google.common.base.MoreObjects; 21 import com.google.common.base.MoreObjects;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import com.google.common.base.MoreObjects; 21 import com.google.common.base.MoreObjects;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
1 package org.onlab.onos.net.intent; 19 package org.onlab.onos.net.intent;
2 20
3 import com.google.common.base.MoreObjects; 21 import com.google.common.base.MoreObjects;
......
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +
1 /** 20 /**
2 * Set of abstractions for conveying high-level intents for treatment of 21 * Set of abstractions for conveying high-level intents for treatment of
3 * selected network traffic by allowing applications to express the 22 * selected network traffic by allowing applications to express the
......
...@@ -9,6 +9,7 @@ import java.util.Map; ...@@ -9,6 +9,7 @@ import java.util.Map;
9 import java.util.Set; 9 import java.util.Set;
10 import java.util.concurrent.ExecutorService; 10 import java.util.concurrent.ExecutorService;
11 import java.util.concurrent.Executors; 11 import java.util.concurrent.Executors;
12 +import java.util.concurrent.Future;
12 13
13 /** 14 /**
14 * Fake implementation of the intent service to assist in developing tests of 15 * Fake implementation of the intent service to assist in developing tests of
...@@ -171,11 +172,17 @@ public class FakeIntentManager implements TestableIntentService { ...@@ -171,11 +172,17 @@ public class FakeIntentManager implements TestableIntentService {
171 } 172 }
172 173
173 @Override 174 @Override
174 - public void execute(IntentOperations operations) { 175 + public void replace(IntentId oldIntentId, Intent newIntent) {
175 // TODO: implement later 176 // TODO: implement later
176 } 177 }
177 178
178 @Override 179 @Override
180 + public Future<IntentOperations> execute(IntentOperations operations) {
181 + // TODO: implement later
182 + return null;
183 + }
184 +
185 + @Override
179 public Set<Intent> getIntents() { 186 public Set<Intent> getIntents() {
180 return Collections.unmodifiableSet(new HashSet<>(intents.values())); 187 return Collections.unmodifiableSet(new HashSet<>(intents.values()));
181 } 188 }
......
...@@ -161,6 +161,17 @@ public class DeviceManager ...@@ -161,6 +161,17 @@ public class DeviceManager
161 } 161 }
162 } 162 }
163 163
164 + // Queries a device for port information.
165 + private void queryPortInfo(DeviceId deviceId) {
166 + Device device = store.getDevice(deviceId);
167 + // FIXME: Device might not be there yet. (eventual consistent)
168 + if (device == null) {
169 + return;
170 + }
171 + DeviceProvider provider = getProvider(device.providerId());
172 + provider.triggerProbe(device);
173 + }
174 +
164 @Override 175 @Override
165 public void removeDevice(DeviceId deviceId) { 176 public void removeDevice(DeviceId deviceId) {
166 checkNotNull(deviceId, DEVICE_ID_NULL); 177 checkNotNull(deviceId, DEVICE_ID_NULL);
...@@ -210,8 +221,6 @@ public class DeviceManager ...@@ -210,8 +221,6 @@ public class DeviceManager
210 log.info("Device {} connected", deviceId); 221 log.info("Device {} connected", deviceId);
211 // check my Role 222 // check my Role
212 MastershipRole role = mastershipService.requestRoleFor(deviceId); 223 MastershipRole role = mastershipService.requestRoleFor(deviceId);
213 - log.info("## - our role for {} is {} [master is {}]", deviceId, role,
214 - mastershipService.getMasterFor(deviceId));
215 if (role != MastershipRole.MASTER) { 224 if (role != MastershipRole.MASTER) {
216 // TODO: Do we need to explicitly tell the Provider that 225 // TODO: Do we need to explicitly tell the Provider that
217 // this instance is no longer the MASTER? probably not 226 // this instance is no longer the MASTER? probably not
...@@ -265,7 +274,6 @@ public class DeviceManager ...@@ -265,7 +274,6 @@ public class DeviceManager
265 // but if I was the last STANDBY connection, etc. and no one else 274 // but if I was the last STANDBY connection, etc. and no one else
266 // was there to mark the device offline, this instance may need to 275 // was there to mark the device offline, this instance may need to
267 // temporarily request for Master Role and mark offline. 276 // temporarily request for Master Role and mark offline.
268 - log.info("## for {} role is {}", deviceId, mastershipService.getLocalRole(deviceId));
269 if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) { 277 if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) {
270 log.debug("Device {} disconnected, but I am not the master", deviceId); 278 log.debug("Device {} disconnected, but I am not the master", deviceId);
271 //let go of ability to be backup 279 //let go of ability to be backup
...@@ -373,7 +381,6 @@ public class DeviceManager ...@@ -373,7 +381,6 @@ public class DeviceManager
373 final DeviceId did = event.subject(); 381 final DeviceId did = event.subject();
374 final NodeId myNodeId = clusterService.getLocalNode().id(); 382 final NodeId myNodeId = clusterService.getLocalNode().id();
375 383
376 - log.info("## got Mastershipevent for dev {}", did);
377 if (myNodeId.equals(event.roleInfo().master())) { 384 if (myNodeId.equals(event.roleInfo().master())) {
378 MastershipTerm term = termService.getMastershipTerm(did); 385 MastershipTerm term = termService.getMastershipTerm(did);
379 386
...@@ -384,7 +391,6 @@ public class DeviceManager ...@@ -384,7 +391,6 @@ public class DeviceManager
384 return; 391 return;
385 } 392 }
386 393
387 - log.info("## setting term for CPS as new master for {}", did);
388 // only set the new term if I am the master 394 // only set the new term if I am the master
389 deviceClockProviderService.setMastershipTerm(did, term); 395 deviceClockProviderService.setMastershipTerm(did, term);
390 396
...@@ -404,6 +410,7 @@ public class DeviceManager ...@@ -404,6 +410,7 @@ public class DeviceManager
404 device.serialNumber(), device.chassisId())); 410 device.serialNumber(), device.chassisId()));
405 } 411 }
406 //TODO re-collect device information to fix potential staleness 412 //TODO re-collect device information to fix potential staleness
413 + queryPortInfo(did);
407 applyRole(did, MastershipRole.MASTER); 414 applyRole(did, MastershipRole.MASTER);
408 } else if (event.roleInfo().backups().contains(myNodeId)) { 415 } else if (event.roleInfo().backups().contains(myNodeId)) {
409 applyRole(did, MastershipRole.STANDBY); 416 applyRole(did, MastershipRole.STANDBY);
......
...@@ -126,7 +126,13 @@ public class IntentManager ...@@ -126,7 +126,13 @@ public class IntentManager
126 126
127 // FIXME: implement this method 127 // FIXME: implement this method
128 @Override 128 @Override
129 - public void execute(IntentOperations operations) { 129 + public void replace(IntentId oldIntentId, Intent newIntent) {
130 + throw new UnsupportedOperationException("execute() is not implemented yet");
131 + }
132 +
133 + // FIXME: implement this method
134 + @Override
135 + public Future<IntentOperations> execute(IntentOperations operations) {
130 throw new UnsupportedOperationException("execute() is not implemented yet"); 136 throw new UnsupportedOperationException("execute() is not implemented yet");
131 } 137 }
132 138
......
...@@ -15,6 +15,7 @@ public class TestEventDispatcher extends DefaultEventSinkRegistry ...@@ -15,6 +15,7 @@ public class TestEventDispatcher extends DefaultEventSinkRegistry
15 implements EventDeliveryService { 15 implements EventDeliveryService {
16 16
17 @Override 17 @Override
18 + @SuppressWarnings("unchecked")
18 public void post(Event event) { 19 public void post(Event event) {
19 EventSink sink = getSink(event.getClass()); 20 EventSink sink = getSink(event.getClass());
20 checkState(sink != null, "No sink for event %s", event); 21 checkState(sink != null, "No sink for event %s", event);
......
1 package org.onlab.onos.net.flow.impl; 1 package org.onlab.onos.net.flow.impl;
2 2
3 -import static java.util.Collections.EMPTY_LIST; 3 +
4 -import static org.junit.Assert.assertEquals; 4 +
5 -import static org.junit.Assert.assertFalse;
6 -import static org.junit.Assert.assertNotNull;
7 -import static org.junit.Assert.assertTrue;
8 -import static org.junit.Assert.fail;
9 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.*; 5 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.*;
10 6
7 +
11 import java.util.ArrayList; 8 import java.util.ArrayList;
12 import java.util.Collections; 9 import java.util.Collections;
13 import java.util.HashMap; 10 import java.util.HashMap;
...@@ -53,7 +50,7 @@ import org.onlab.onos.net.flow.TrafficSelector; ...@@ -53,7 +50,7 @@ import org.onlab.onos.net.flow.TrafficSelector;
53 import org.onlab.onos.net.flow.TrafficTreatment; 50 import org.onlab.onos.net.flow.TrafficTreatment;
54 import org.onlab.onos.net.flow.criteria.Criterion; 51 import org.onlab.onos.net.flow.criteria.Criterion;
55 import org.onlab.onos.net.flow.instructions.Instruction; 52 import org.onlab.onos.net.flow.instructions.Instruction;
56 -import org.onlab.onos.net.intent.BatchOperation; 53 +import org.onlab.onos.net.flow.BatchOperation;
57 import org.onlab.onos.net.provider.AbstractProvider; 54 import org.onlab.onos.net.provider.AbstractProvider;
58 import org.onlab.onos.net.provider.ProviderId; 55 import org.onlab.onos.net.provider.ProviderId;
59 import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore; 56 import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore;
...@@ -63,6 +60,16 @@ import com.google.common.collect.ImmutableMap; ...@@ -63,6 +60,16 @@ import com.google.common.collect.ImmutableMap;
63 import com.google.common.collect.Lists; 60 import com.google.common.collect.Lists;
64 import com.google.common.collect.Sets; 61 import com.google.common.collect.Sets;
65 62
63 +import static java.util.Collections.EMPTY_LIST;
64 +import static org.junit.Assert.assertEquals;
65 +import static org.junit.Assert.assertFalse;
66 +import static org.junit.Assert.assertNotNull;
67 +import static org.junit.Assert.assertTrue;
68 +import static org.junit.Assert.fail;
69 +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
70 +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
71 +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
72 +
66 /** 73 /**
67 * Test codifying the flow rule service & flow rule provider service contracts. 74 * Test codifying the flow rule service & flow rule provider service contracts.
68 */ 75 */
...@@ -175,6 +182,7 @@ public class FlowRuleManagerTest { ...@@ -175,6 +182,7 @@ public class FlowRuleManagerTest {
175 182
176 // TODO: If preserving iteration order is a requirement, redo FlowRuleStore. 183 // TODO: If preserving iteration order is a requirement, redo FlowRuleStore.
177 //backing store is sensitive to the order of additions/removals 184 //backing store is sensitive to the order of additions/removals
185 + @SuppressWarnings("unchecked")
178 private boolean validateState(Map<FlowRule, FlowEntryState> expected) { 186 private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
179 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected); 187 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
180 Iterable<FlowEntry> rules = service.getFlowEntries(DID); 188 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
...@@ -542,6 +550,7 @@ public class FlowRuleManagerTest { ...@@ -542,6 +550,7 @@ public class FlowRuleManagerTest {
542 } 550 }
543 551
544 @Override 552 @Override
553 + @SuppressWarnings("unchecked")
545 public CompletedBatchOperation get() 554 public CompletedBatchOperation get()
546 throws InterruptedException, ExecutionException { 555 throws InterruptedException, ExecutionException {
547 return new CompletedBatchOperation(true, EMPTY_LIST); 556 return new CompletedBatchOperation(true, EMPTY_LIST);
......
...@@ -290,12 +290,17 @@ public class GossipDeviceStore ...@@ -290,12 +290,17 @@ public class GossipDeviceStore
290 private DeviceEvent updateDevice(ProviderId providerId, 290 private DeviceEvent updateDevice(ProviderId providerId,
291 Device oldDevice, 291 Device oldDevice,
292 Device newDevice, Timestamp newTimestamp) { 292 Device newDevice, Timestamp newTimestamp) {
293 -
294 // We allow only certain attributes to trigger update 293 // We allow only certain attributes to trigger update
295 - if (!Objects.equals(oldDevice.hwVersion(), newDevice.hwVersion()) || 294 + boolean propertiesChanged =
296 - !Objects.equals(oldDevice.swVersion(), newDevice.swVersion()) || 295 + !Objects.equals(oldDevice.hwVersion(), newDevice.hwVersion()) ||
297 - !AnnotationsUtil.isEqual(oldDevice.annotations(), newDevice.annotations())) { 296 + !Objects.equals(oldDevice.swVersion(), newDevice.swVersion());
298 - 297 + boolean annotationsChanged =
298 + !AnnotationsUtil.isEqual(oldDevice.annotations(), newDevice.annotations());
299 +
300 + // Primary providers can respond to all changes, but ancillary ones
301 + // should respond only to annotation changes.
302 + if ((providerId.isAncillary() && annotationsChanged) ||
303 + (!providerId.isAncillary() && (propertiesChanged || annotationsChanged))) {
299 boolean replaced = devices.replace(newDevice.id(), oldDevice, newDevice); 304 boolean replaced = devices.replace(newDevice.id(), oldDevice, newDevice);
300 if (!replaced) { 305 if (!replaced) {
301 verify(replaced, 306 verify(replaced,
......
...@@ -35,6 +35,8 @@ public class InternalDeviceEventSerializer extends Serializer<InternalDeviceEven ...@@ -35,6 +35,8 @@ public class InternalDeviceEventSerializer extends Serializer<InternalDeviceEven
35 Class<InternalDeviceEvent> type) { 35 Class<InternalDeviceEvent> type) {
36 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input); 36 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input);
37 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input); 37 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
38 +
39 + @SuppressWarnings("unchecked")
38 Timestamped<DeviceDescription> deviceDescription 40 Timestamped<DeviceDescription> deviceDescription
39 = (Timestamped<DeviceDescription>) kryo.readClassAndObject(input); 41 = (Timestamped<DeviceDescription>) kryo.readClassAndObject(input);
40 42
......
...@@ -37,6 +37,8 @@ public class InternalPortEventSerializer extends Serializer<InternalPortEvent> { ...@@ -37,6 +37,8 @@ public class InternalPortEventSerializer extends Serializer<InternalPortEvent> {
37 Class<InternalPortEvent> type) { 37 Class<InternalPortEvent> type) {
38 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input); 38 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input);
39 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input); 39 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
40 +
41 + @SuppressWarnings("unchecked")
40 Timestamped<List<PortDescription>> portDescriptions 42 Timestamped<List<PortDescription>> portDescriptions
41 = (Timestamped<List<PortDescription>>) kryo.readClassAndObject(input); 43 = (Timestamped<List<PortDescription>>) kryo.readClassAndObject(input);
42 44
......
...@@ -70,15 +70,16 @@ public class SimpleDeviceStore ...@@ -70,15 +70,16 @@ public class SimpleDeviceStore
70 70
71 public static final String DEVICE_NOT_FOUND = "Device with ID %s not found"; 71 public static final String DEVICE_NOT_FOUND = "Device with ID %s not found";
72 72
73 - // collection of Description given from various providers 73 + // Collection of Description given from various providers
74 private final ConcurrentMap<DeviceId, Map<ProviderId, DeviceDescriptions>> 74 private final ConcurrentMap<DeviceId, Map<ProviderId, DeviceDescriptions>>
75 - deviceDescs = Maps.newConcurrentMap(); 75 + deviceDescs = Maps.newConcurrentMap();
76 76
77 - // cache of Device and Ports generated by compositing descriptions from providers 77 + // Cache of Device and Ports generated by compositing descriptions from providers
78 private final ConcurrentMap<DeviceId, Device> devices = Maps.newConcurrentMap(); 78 private final ConcurrentMap<DeviceId, Device> devices = Maps.newConcurrentMap();
79 - private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, Port>> devicePorts = Maps.newConcurrentMap(); 79 + private final ConcurrentMap<DeviceId, ConcurrentMap<PortNumber, Port>>
80 + devicePorts = Maps.newConcurrentMap();
80 81
81 - // available(=UP) devices 82 + // Available (=UP) devices
82 private final Set<DeviceId> availableDevices = Sets.newConcurrentHashSet(); 83 private final Set<DeviceId> availableDevices = Sets.newConcurrentHashSet();
83 84
84 85
...@@ -113,19 +114,17 @@ public class SimpleDeviceStore ...@@ -113,19 +114,17 @@ public class SimpleDeviceStore
113 114
114 @Override 115 @Override
115 public DeviceEvent createOrUpdateDevice(ProviderId providerId, 116 public DeviceEvent createOrUpdateDevice(ProviderId providerId,
116 - DeviceId deviceId, 117 + DeviceId deviceId,
117 - DeviceDescription deviceDescription) { 118 + DeviceDescription deviceDescription) {
118 -
119 Map<ProviderId, DeviceDescriptions> providerDescs 119 Map<ProviderId, DeviceDescriptions> providerDescs
120 - = getOrCreateDeviceDescriptions(deviceId); 120 + = getOrCreateDeviceDescriptions(deviceId);
121 121
122 synchronized (providerDescs) { 122 synchronized (providerDescs) {
123 // locking per device 123 // locking per device
124 -
125 DeviceDescriptions descs 124 DeviceDescriptions descs
126 - = getOrCreateProviderDeviceDescriptions(providerDescs, 125 + = getOrCreateProviderDeviceDescriptions(providerDescs,
127 - providerId, 126 + providerId,
128 - deviceDescription); 127 + deviceDescription);
129 128
130 Device oldDevice = devices.get(deviceId); 129 Device oldDevice = devices.get(deviceId);
131 // update description 130 // update description
...@@ -145,12 +144,11 @@ public class SimpleDeviceStore ...@@ -145,12 +144,11 @@ public class SimpleDeviceStore
145 // Creates the device and returns the appropriate event if necessary. 144 // Creates the device and returns the appropriate event if necessary.
146 // Guarded by deviceDescs value (=Device lock) 145 // Guarded by deviceDescs value (=Device lock)
147 private DeviceEvent createDevice(ProviderId providerId, Device newDevice) { 146 private DeviceEvent createDevice(ProviderId providerId, Device newDevice) {
148 -
149 // update composed device cache 147 // update composed device cache
150 Device oldDevice = devices.putIfAbsent(newDevice.id(), newDevice); 148 Device oldDevice = devices.putIfAbsent(newDevice.id(), newDevice);
151 verify(oldDevice == null, 149 verify(oldDevice == null,
152 - "Unexpected Device in cache. PID:%s [old=%s, new=%s]", 150 + "Unexpected Device in cache. PID:%s [old=%s, new=%s]",
153 - providerId, oldDevice, newDevice); 151 + providerId, oldDevice, newDevice);
154 152
155 if (!providerId.isAncillary()) { 153 if (!providerId.isAncillary()) {
156 availableDevices.add(newDevice.id()); 154 availableDevices.add(newDevice.id());
...@@ -162,17 +160,24 @@ public class SimpleDeviceStore ...@@ -162,17 +160,24 @@ public class SimpleDeviceStore
162 // Updates the device and returns the appropriate event if necessary. 160 // Updates the device and returns the appropriate event if necessary.
163 // Guarded by deviceDescs value (=Device lock) 161 // Guarded by deviceDescs value (=Device lock)
164 private DeviceEvent updateDevice(ProviderId providerId, Device oldDevice, Device newDevice) { 162 private DeviceEvent updateDevice(ProviderId providerId, Device oldDevice, Device newDevice) {
165 -
166 // We allow only certain attributes to trigger update 163 // We allow only certain attributes to trigger update
167 - if (!Objects.equals(oldDevice.hwVersion(), newDevice.hwVersion()) || 164 + boolean propertiesChanged =
168 - !Objects.equals(oldDevice.swVersion(), newDevice.swVersion()) || 165 + !Objects.equals(oldDevice.hwVersion(), newDevice.hwVersion()) ||
169 - !AnnotationsUtil.isEqual(oldDevice.annotations(), newDevice.annotations())) { 166 + !Objects.equals(oldDevice.swVersion(), newDevice.swVersion());
167 + boolean annotationsChanged =
168 + !AnnotationsUtil.isEqual(oldDevice.annotations(), newDevice.annotations());
169 +
170 + // Primary providers can respond to all changes, but ancillary ones
171 + // should respond only to annotation changes.
172 + if ((providerId.isAncillary() && annotationsChanged) ||
173 + (!providerId.isAncillary() && (propertiesChanged || annotationsChanged))) {
170 174
171 boolean replaced = devices.replace(newDevice.id(), oldDevice, newDevice); 175 boolean replaced = devices.replace(newDevice.id(), oldDevice, newDevice);
172 if (!replaced) { 176 if (!replaced) {
177 + // FIXME: Is the enclosing if required here?
173 verify(replaced, 178 verify(replaced,
174 - "Replacing devices cache failed. PID:%s [expected:%s, found:%s, new=%s]", 179 + "Replacing devices cache failed. PID:%s [expected:%s, found:%s, new=%s]",
175 - providerId, oldDevice, devices.get(newDevice.id()) 180 + providerId, oldDevice, devices.get(newDevice.id())
176 , newDevice); 181 , newDevice);
177 } 182 }
178 if (!providerId.isAncillary()) { 183 if (!providerId.isAncillary()) {
...@@ -193,7 +198,7 @@ public class SimpleDeviceStore ...@@ -193,7 +198,7 @@ public class SimpleDeviceStore
193 @Override 198 @Override
194 public DeviceEvent markOffline(DeviceId deviceId) { 199 public DeviceEvent markOffline(DeviceId deviceId) {
195 Map<ProviderId, DeviceDescriptions> providerDescs 200 Map<ProviderId, DeviceDescriptions> providerDescs
196 - = getOrCreateDeviceDescriptions(deviceId); 201 + = getOrCreateDeviceDescriptions(deviceId);
197 202
198 // locking device 203 // locking device
199 synchronized (providerDescs) { 204 synchronized (providerDescs) {
...@@ -212,9 +217,8 @@ public class SimpleDeviceStore ...@@ -212,9 +217,8 @@ public class SimpleDeviceStore
212 217
213 @Override 218 @Override
214 public List<DeviceEvent> updatePorts(ProviderId providerId, 219 public List<DeviceEvent> updatePorts(ProviderId providerId,
215 - DeviceId deviceId, 220 + DeviceId deviceId,
216 - List<PortDescription> portDescriptions) { 221 + List<PortDescription> portDescriptions) {
217 -
218 Device device = devices.get(deviceId); 222 Device device = devices.get(deviceId);
219 checkArgument(device != null, DEVICE_NOT_FOUND, deviceId); 223 checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
220 224
...@@ -226,8 +230,8 @@ public class SimpleDeviceStore ...@@ -226,8 +230,8 @@ public class SimpleDeviceStore
226 DeviceDescriptions descs = descsMap.get(providerId); 230 DeviceDescriptions descs = descsMap.get(providerId);
227 // every provider must provide DeviceDescription. 231 // every provider must provide DeviceDescription.
228 checkArgument(descs != null, 232 checkArgument(descs != null,
229 - "Device description for Device ID %s from Provider %s was not found", 233 + "Device description for Device ID %s from Provider %s was not found",
230 - deviceId, providerId); 234 + deviceId, providerId);
231 235
232 Map<PortNumber, Port> ports = getPortMap(deviceId); 236 Map<PortNumber, Port> ports = getPortMap(deviceId);
233 237
...@@ -247,8 +251,8 @@ public class SimpleDeviceStore ...@@ -247,8 +251,8 @@ public class SimpleDeviceStore
247 newPort = composePort(device, number, descsMap); 251 newPort = composePort(device, number, descsMap);
248 252
249 events.add(oldPort == null ? 253 events.add(oldPort == null ?
250 - createPort(device, newPort, ports) : 254 + createPort(device, newPort, ports) :
251 - updatePort(device, oldPort, newPort, ports)); 255 + updatePort(device, oldPort, newPort, ports));
252 } 256 }
253 257
254 events.addAll(pruneOldPorts(device, ports, processed)); 258 events.addAll(pruneOldPorts(device, ports, processed));
...@@ -272,7 +276,7 @@ public class SimpleDeviceStore ...@@ -272,7 +276,7 @@ public class SimpleDeviceStore
272 Port newPort, 276 Port newPort,
273 Map<PortNumber, Port> ports) { 277 Map<PortNumber, Port> ports) {
274 if (oldPort.isEnabled() != newPort.isEnabled() || 278 if (oldPort.isEnabled() != newPort.isEnabled() ||
275 - !AnnotationsUtil.isEqual(oldPort.annotations(), newPort.annotations())) { 279 + !AnnotationsUtil.isEqual(oldPort.annotations(), newPort.annotations())) {
276 280
277 ports.put(oldPort.number(), newPort); 281 ports.put(oldPort.number(), newPort);
278 return new DeviceEvent(PORT_UPDATED, device, newPort); 282 return new DeviceEvent(PORT_UPDATED, device, newPort);
...@@ -303,7 +307,7 @@ public class SimpleDeviceStore ...@@ -303,7 +307,7 @@ public class SimpleDeviceStore
303 // exist, it creates and registers a new one. 307 // exist, it creates and registers a new one.
304 private ConcurrentMap<PortNumber, Port> getPortMap(DeviceId deviceId) { 308 private ConcurrentMap<PortNumber, Port> getPortMap(DeviceId deviceId) {
305 return createIfAbsentUnchecked(devicePorts, deviceId, 309 return createIfAbsentUnchecked(devicePorts, deviceId,
306 - NewConcurrentHashMap.<PortNumber, Port>ifNeeded()); 310 + NewConcurrentHashMap.<PortNumber, Port>ifNeeded());
307 } 311 }
308 312
309 private Map<ProviderId, DeviceDescriptions> getOrCreateDeviceDescriptions( 313 private Map<ProviderId, DeviceDescriptions> getOrCreateDeviceDescriptions(
...@@ -325,9 +329,8 @@ public class SimpleDeviceStore ...@@ -325,9 +329,8 @@ public class SimpleDeviceStore
325 329
326 // Guarded by deviceDescs value (=Device lock) 330 // Guarded by deviceDescs value (=Device lock)
327 private DeviceDescriptions getOrCreateProviderDeviceDescriptions( 331 private DeviceDescriptions getOrCreateProviderDeviceDescriptions(
328 - Map<ProviderId, DeviceDescriptions> device, 332 + Map<ProviderId, DeviceDescriptions> device,
329 - ProviderId providerId, DeviceDescription deltaDesc) { 333 + ProviderId providerId, DeviceDescription deltaDesc) {
330 -
331 synchronized (device) { 334 synchronized (device) {
332 DeviceDescriptions r = device.get(providerId); 335 DeviceDescriptions r = device.get(providerId);
333 if (r == null) { 336 if (r == null) {
...@@ -340,7 +343,7 @@ public class SimpleDeviceStore ...@@ -340,7 +343,7 @@ public class SimpleDeviceStore
340 343
341 @Override 344 @Override
342 public DeviceEvent updatePortStatus(ProviderId providerId, DeviceId deviceId, 345 public DeviceEvent updatePortStatus(ProviderId providerId, DeviceId deviceId,
343 - PortDescription portDescription) { 346 + PortDescription portDescription) {
344 Device device = devices.get(deviceId); 347 Device device = devices.get(deviceId);
345 checkArgument(device != null, DEVICE_NOT_FOUND, deviceId); 348 checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
346 349
...@@ -351,8 +354,8 @@ public class SimpleDeviceStore ...@@ -351,8 +354,8 @@ public class SimpleDeviceStore
351 DeviceDescriptions descs = descsMap.get(providerId); 354 DeviceDescriptions descs = descsMap.get(providerId);
352 // assuming all providers must give DeviceDescription first 355 // assuming all providers must give DeviceDescription first
353 checkArgument(descs != null, 356 checkArgument(descs != null,
354 - "Device description for Device ID %s from Provider %s was not found", 357 + "Device description for Device ID %s from Provider %s was not found",
355 - deviceId, providerId); 358 + deviceId, providerId);
356 359
357 ConcurrentMap<PortNumber, Port> ports = getPortMap(deviceId); 360 ConcurrentMap<PortNumber, Port> ports = getPortMap(deviceId);
358 final PortNumber number = portDescription.portNumber(); 361 final PortNumber number = portDescription.portNumber();
...@@ -404,19 +407,19 @@ public class SimpleDeviceStore ...@@ -404,19 +407,19 @@ public class SimpleDeviceStore
404 availableDevices.remove(deviceId); 407 availableDevices.remove(deviceId);
405 descs.clear(); 408 descs.clear();
406 return device == null ? null : 409 return device == null ? null :
407 - new DeviceEvent(DEVICE_REMOVED, device, null); 410 + new DeviceEvent(DEVICE_REMOVED, device, null);
408 } 411 }
409 } 412 }
410 413
411 /** 414 /**
412 * Returns a Device, merging description given from multiple Providers. 415 * Returns a Device, merging description given from multiple Providers.
413 * 416 *
414 - * @param deviceId device identifier 417 + * @param deviceId device identifier
415 * @param providerDescs Collection of Descriptions from multiple providers 418 * @param providerDescs Collection of Descriptions from multiple providers
416 * @return Device instance 419 * @return Device instance
417 */ 420 */
418 private Device composeDevice(DeviceId deviceId, 421 private Device composeDevice(DeviceId deviceId,
419 - Map<ProviderId, DeviceDescriptions> providerDescs) { 422 + Map<ProviderId, DeviceDescriptions> providerDescs) {
420 423
421 checkArgument(!providerDescs.isEmpty(), "No Device descriptions supplied"); 424 checkArgument(!providerDescs.isEmpty(), "No Device descriptions supplied");
422 425
...@@ -447,21 +450,21 @@ public class SimpleDeviceStore ...@@ -447,21 +450,21 @@ public class SimpleDeviceStore
447 annotations = merge(annotations, e.getValue().getDeviceDesc().annotations()); 450 annotations = merge(annotations, e.getValue().getDeviceDesc().annotations());
448 } 451 }
449 452
450 - return new DefaultDevice(primary, deviceId , type, manufacturer, 453 + return new DefaultDevice(primary, deviceId, type, manufacturer,
451 - hwVersion, swVersion, serialNumber, 454 + hwVersion, swVersion, serialNumber,
452 - chassisId, annotations); 455 + chassisId, annotations);
453 } 456 }
454 457
455 /** 458 /**
456 * Returns a Port, merging description given from multiple Providers. 459 * Returns a Port, merging description given from multiple Providers.
457 * 460 *
458 - * @param device device the port is on 461 + * @param device device the port is on
459 - * @param number port number 462 + * @param number port number
460 * @param descsMap Collection of Descriptions from multiple providers 463 * @param descsMap Collection of Descriptions from multiple providers
461 * @return Port instance 464 * @return Port instance
462 */ 465 */
463 private Port composePort(Device device, PortNumber number, 466 private Port composePort(Device device, PortNumber number,
464 - Map<ProviderId, DeviceDescriptions> descsMap) { 467 + Map<ProviderId, DeviceDescriptions> descsMap) {
465 468
466 ProviderId primary = pickPrimaryPID(descsMap); 469 ProviderId primary = pickPrimaryPID(descsMap);
467 DeviceDescriptions primDescs = descsMap.get(primary); 470 DeviceDescriptions primDescs = descsMap.get(primary);
......
...@@ -110,8 +110,7 @@ public interface OpenFlowSwitch { ...@@ -110,8 +110,7 @@ public interface OpenFlowSwitch {
110 * 110 *
111 * @param role the failed role 111 * @param role the failed role
112 */ 112 */
113 - void returnRoleAssertFailure(RoleState role); 113 + public void returnRoleAssertFailure(RoleState role);
114 -
115 114
116 /** 115 /**
117 * Indicates if this switch is optical. 116 * Indicates if this switch is optical.
...@@ -120,5 +119,4 @@ public interface OpenFlowSwitch { ...@@ -120,5 +119,4 @@ public interface OpenFlowSwitch {
120 */ 119 */
121 public boolean isOptical(); 120 public boolean isOptical();
122 121
123 -
124 } 122 }
......
...@@ -20,6 +20,12 @@ public interface OpenFlowSwitchListener { ...@@ -20,6 +20,12 @@ public interface OpenFlowSwitchListener {
20 public void switchRemoved(Dpid dpid); 20 public void switchRemoved(Dpid dpid);
21 21
22 /** 22 /**
23 + * Notify that the switch has changed in some way.
24 + * @param dpid the switch that changed
25 + */
26 + public void switchChanged(Dpid dpid);
27 +
28 + /**
23 * Notify that a port has changed. 29 * Notify that a port has changed.
24 * @param dpid the switch on which the change happened. 30 * @param dpid the switch on which the change happened.
25 * @param status the new state of the port. 31 * @param status the new state of the port.
......
...@@ -565,6 +565,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -565,6 +565,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
565 @Override 565 @Override
566 void processOFStatisticsReply(OFChannelHandler h, 566 void processOFStatisticsReply(OFChannelHandler h,
567 OFStatsReply m) { 567 OFStatsReply m) {
568 + if (m.getStatsType().equals(OFStatsType.PORT_DESC)) {
569 + h.sw.setPortDescReply((OFPortDescStatsReply) m);
570 + }
568 h.dispatchMessage(m); 571 h.dispatchMessage(m);
569 } 572 }
570 573
...@@ -608,6 +611,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -608,6 +611,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
608 h.dispatchMessage(m); 611 h.dispatchMessage(m);
609 } 612 }
610 613
614 + @Override
615 + void processOFFeaturesReply(OFChannelHandler h, OFFeaturesReply m) {
616 + h.sw.setFeaturesReply(m);
617 + h.dispatchMessage(m);
618 + }
619 +
611 }; 620 };
612 621
613 private final boolean handshakeComplete; 622 private final boolean handshakeComplete;
......
...@@ -27,6 +27,8 @@ import org.onlab.onos.openflow.controller.driver.OpenFlowAgent; ...@@ -27,6 +27,8 @@ import org.onlab.onos.openflow.controller.driver.OpenFlowAgent;
27 import org.projectfloodlight.openflow.protocol.OFMessage; 27 import org.projectfloodlight.openflow.protocol.OFMessage;
28 import org.projectfloodlight.openflow.protocol.OFPacketIn; 28 import org.projectfloodlight.openflow.protocol.OFPacketIn;
29 import org.projectfloodlight.openflow.protocol.OFPortStatus; 29 import org.projectfloodlight.openflow.protocol.OFPortStatus;
30 +import org.projectfloodlight.openflow.protocol.OFStatsReply;
31 +import org.projectfloodlight.openflow.protocol.OFStatsType;
30 import org.slf4j.Logger; 32 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory; 33 import org.slf4j.LoggerFactory;
32 34
...@@ -146,6 +148,11 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -146,6 +148,11 @@ public class OpenFlowControllerImpl implements OpenFlowController {
146 l.portChanged(dpid, (OFPortStatus) msg); 148 l.portChanged(dpid, (OFPortStatus) msg);
147 } 149 }
148 break; 150 break;
151 + case FEATURES_REPLY:
152 + for (OpenFlowSwitchListener l : ofSwitchListener) {
153 + l.switchChanged(dpid);
154 + }
155 + break;
149 case PACKET_IN: 156 case PACKET_IN:
150 OpenFlowPacketContext pktCtx = DefaultOpenFlowPacketContext 157 OpenFlowPacketContext pktCtx = DefaultOpenFlowPacketContext
151 .packetContextFromPacketIn(this.getSwitch(dpid), 158 .packetContextFromPacketIn(this.getSwitch(dpid),
...@@ -154,9 +161,15 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -154,9 +161,15 @@ public class OpenFlowControllerImpl implements OpenFlowController {
154 p.handlePacket(pktCtx); 161 p.handlePacket(pktCtx);
155 } 162 }
156 break; 163 break;
164 + case STATS_REPLY:
165 + OFStatsReply reply = (OFStatsReply) msg;
166 + if (reply.getStatsType().equals(OFStatsType.PORT_DESC)) {
167 + for (OpenFlowSwitchListener l : ofSwitchListener) {
168 + l.switchChanged(dpid);
169 + }
170 + }
157 case FLOW_REMOVED: 171 case FLOW_REMOVED:
158 case ERROR: 172 case ERROR:
159 - case STATS_REPLY:
160 case BARRIER_REPLY: 173 case BARRIER_REPLY:
161 executor.submit(new OFMessageHandler(dpid, msg)); 174 executor.submit(new OFMessageHandler(dpid, msg));
162 break; 175 break;
......
...@@ -23,7 +23,9 @@ import org.onlab.onos.openflow.controller.OpenFlowController; ...@@ -23,7 +23,9 @@ import org.onlab.onos.openflow.controller.OpenFlowController;
23 import org.onlab.onos.openflow.controller.OpenFlowSwitch; 23 import org.onlab.onos.openflow.controller.OpenFlowSwitch;
24 import org.onlab.onos.openflow.controller.OpenFlowSwitchListener; 24 import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
25 import org.onlab.onos.openflow.controller.RoleState; 25 import org.onlab.onos.openflow.controller.RoleState;
26 +import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
26 import org.onlab.packet.ChassisId; 27 import org.onlab.packet.ChassisId;
28 +import org.projectfloodlight.openflow.protocol.OFFactory;
27 import org.projectfloodlight.openflow.protocol.OFPortConfig; 29 import org.projectfloodlight.openflow.protocol.OFPortConfig;
28 import org.projectfloodlight.openflow.protocol.OFPortDesc; 30 import org.projectfloodlight.openflow.protocol.OFPortDesc;
29 import org.projectfloodlight.openflow.protocol.OFPortState; 31 import org.projectfloodlight.openflow.protocol.OFPortState;
...@@ -89,6 +91,28 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -89,6 +91,28 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
89 @Override 91 @Override
90 public void triggerProbe(Device device) { 92 public void triggerProbe(Device device) {
91 LOG.info("Triggering probe on device {}", device.id()); 93 LOG.info("Triggering probe on device {}", device.id());
94 +
95 + // 1. check device liveness
96 + // FIXME if possible, we might want this to be part of
97 + // OpenFlowSwitch interface so the driver interface isn't misused.
98 + OpenFlowSwitch sw = controller.getSwitch(dpid(device.id().uri()));
99 + if (!((OpenFlowSwitchDriver) sw).isConnected()) {
100 + providerService.deviceDisconnected(device.id());
101 + return;
102 + }
103 +
104 + // 2. Prompt an update of port information. Do we have an XID for this?
105 + OFFactory fact = sw.factory();
106 + switch (fact.getVersion()) {
107 + case OF_10:
108 + sw.sendMsg(fact.buildFeaturesRequest().setXid(0).build());
109 + break;
110 + case OF_13:
111 + sw.sendMsg(fact.buildPortDescStatsRequest().setXid(0).build());
112 + break;
113 + default:
114 + LOG.warn("Unhandled protocol version");
115 + }
92 } 116 }
93 117
94 @Override 118 @Override
...@@ -141,6 +165,17 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -141,6 +165,17 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
141 providerService.deviceDisconnected(deviceId(uri(dpid))); 165 providerService.deviceDisconnected(deviceId(uri(dpid)));
142 } 166 }
143 167
168 +
169 + @Override
170 + public void switchChanged(Dpid dpid) {
171 + if (providerService == null) {
172 + return;
173 + }
174 + DeviceId did = deviceId(uri(dpid));
175 + OpenFlowSwitch sw = controller.getSwitch(dpid);
176 + providerService.updatePorts(did, buildPortDescriptions(sw.getPorts()));
177 + }
178 +
144 @Override 179 @Override
145 public void portChanged(Dpid dpid, OFPortStatus status) { 180 public void portChanged(Dpid dpid, OFPortStatus status) {
146 PortDescription portDescription = buildPortDescription(status.getDesc()); 181 PortDescription portDescription = buildPortDescription(status.getDesc());
......
...@@ -31,7 +31,7 @@ import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation; ...@@ -31,7 +31,7 @@ import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
31 import org.onlab.onos.net.flow.FlowRuleProvider; 31 import org.onlab.onos.net.flow.FlowRuleProvider;
32 import org.onlab.onos.net.flow.FlowRuleProviderRegistry; 32 import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
33 import org.onlab.onos.net.flow.FlowRuleProviderService; 33 import org.onlab.onos.net.flow.FlowRuleProviderService;
34 -import org.onlab.onos.net.intent.BatchOperation; 34 +import org.onlab.onos.net.flow.BatchOperation;
35 import org.onlab.onos.net.provider.AbstractProvider; 35 import org.onlab.onos.net.provider.AbstractProvider;
36 import org.onlab.onos.net.provider.ProviderId; 36 import org.onlab.onos.net.provider.ProviderId;
37 import org.onlab.onos.net.topology.TopologyService; 37 import org.onlab.onos.net.topology.TopologyService;
...@@ -243,6 +243,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -243,6 +243,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
243 } 243 }
244 244
245 @Override 245 @Override
246 + public void switchChanged(Dpid dpid) {
247 + }
248 +
249 + @Override
246 public void portChanged(Dpid dpid, OFPortStatus status) { 250 public void portChanged(Dpid dpid, OFPortStatus status) {
247 //TODO: Decide whether to evict flows internal store. 251 //TODO: Decide whether to evict flows internal store.
248 } 252 }
...@@ -323,6 +327,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -323,6 +327,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
323 } 327 }
324 return false; 328 return false;
325 } 329 }
330 +
326 } 331 }
327 332
328 private class InstallationFuture implements Future<CompletedBatchOperation> { 333 private class InstallationFuture implements Future<CompletedBatchOperation> {
......
...@@ -118,6 +118,12 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid ...@@ -118,6 +118,12 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
118 DeviceId.deviceId("of:" + Long.toHexString(dpid.value()))); 118 DeviceId.deviceId("of:" + Long.toHexString(dpid.value())));
119 } 119 }
120 120
121 +
122 + @Override
123 + public void switchChanged(Dpid dpid) {
124 + //might not need to do anything since DeviceManager is notified
125 + }
126 +
121 @Override 127 @Override
122 public void portChanged(Dpid dpid, OFPortStatus status) { 128 public void portChanged(Dpid dpid, OFPortStatus status) {
123 LinkDiscovery ld = discoverers.get(dpid); 129 LinkDiscovery ld = discoverers.get(dpid);
......
...@@ -6,6 +6,7 @@ import com.google.common.collect.MutableClassToInstanceMap; ...@@ -6,6 +6,7 @@ import com.google.common.collect.MutableClassToInstanceMap;
6 /** 6 /**
7 * Service directory implementation suitable for testing. 7 * Service directory implementation suitable for testing.
8 */ 8 */
9 +@SuppressWarnings("unchecked")
9 public class TestServiceDirectory implements ServiceDirectory { 10 public class TestServiceDirectory implements ServiceDirectory {
10 11
11 private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create(); 12 private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create();
......
1 +/*
2 + Geometry library - based on work by Mike Bostock.
3 + */
4 +
5 +(function() {
6 +
7 + if (typeof geo == 'undefined') {
8 + geo = {};
9 + }
10 +
11 + var tolerance = 1e-10;
12 +
13 + function eq(a, b) {
14 + return (Math.abs(a - b) < tolerance);
15 + }
16 +
17 + function gt(a, b) {
18 + return (a - b > -tolerance);
19 + }
20 +
21 + function lt(a, b) {
22 + return gt(b, a);
23 + }
24 +
25 + geo.eq = eq;
26 + geo.gt = gt;
27 + geo.lt = lt;
28 +
29 + geo.LineSegment = function(x1, y1, x2, y2) {
30 + this.x1 = x1;
31 + this.y1 = y1;
32 + this.x2 = x2;
33 + this.y2 = y2;
34 +
35 + // Ax + By = C
36 + this.a = y2 - y1;
37 + this.b = x1 - x2;
38 + this.c = x1 * this.a + y1 * this.b;
39 +
40 + if (eq(this.a, 0) && eq(this.b, 0)) {
41 + throw new Error(
42 + 'Cannot construct a LineSegment with two equal endpoints.');
43 + }
44 + };
45 +
46 + geo.LineSegment.prototype.intersect = function(that) {
47 + var d = (this.x1 - this.x2) * (that.y1 - that.y2) -
48 + (this.y1 - this.y2) * (that.x1 - that.x2);
49 +
50 + if (eq(d, 0)) {
51 + // The two lines are parallel or very close.
52 + return {
53 + x : NaN,
54 + y : NaN
55 + };
56 + }
57 +
58 + var t1 = this.x1 * this.y2 - this.y1 * this.x2,
59 + t2 = that.x1 * that.y2 - that.y1 * that.x2,
60 + x = (t1 * (that.x1 - that.x2) - t2 * (this.x1 - this.x2)) / d,
61 + y = (t1 * (that.y1 - that.y2) - t2 * (this.y1 - this.y2)) / d,
62 + in1 = (gt(x, Math.min(this.x1, this.x2)) && lt(x, Math.max(this.x1, this.x2)) &&
63 + gt(y, Math.min(this.y1, this.y2)) && lt(y, Math.max(this.y1, this.y2))),
64 + in2 = (gt(x, Math.min(that.x1, that.x2)) && lt(x, Math.max(that.x1, that.x2)) &&
65 + gt(y, Math.min(that.y1, that.y2)) && lt(y, Math.max(that.y1, that.y2)));
66 +
67 + return {
68 + x : x,
69 + y : y,
70 + in1 : in1,
71 + in2 : in2
72 + };
73 + };
74 +
75 + geo.LineSegment.prototype.x = function(y) {
76 + // x = (C - By) / a;
77 + if (this.a) {
78 + return (this.c - this.b * y) / this.a;
79 + } else {
80 + // a == 0 -> horizontal line
81 + return NaN;
82 + }
83 + };
84 +
85 + geo.LineSegment.prototype.y = function(x) {
86 + // y = (C - Ax) / b;
87 + if (this.b) {
88 + return (this.c - this.a * x) / this.b;
89 + } else {
90 + // b == 0 -> vertical line
91 + return NaN;
92 + }
93 + };
94 +
95 + geo.LineSegment.prototype.length = function() {
96 + return Math.sqrt(
97 + (this.y2 - this.y1) * (this.y2 - this.y1) +
98 + (this.x2 - this.x1) * (this.x2 - this.x1));
99 + };
100 +
101 + geo.LineSegment.prototype.offset = function(x, y) {
102 + return new geo.LineSegment(
103 + this.x1 + x, this.y1 + y,
104 + this.x2 + x, this.y2 + y);
105 + };
106 +
107 +})();
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
14 <link rel="stylesheet" href="base.css"> 14 <link rel="stylesheet" href="base.css">
15 <link rel="stylesheet" href="onos.css"> 15 <link rel="stylesheet" href="onos.css">
16 16
17 + <script src="geometry.js"></script>
17 <script src="onosui.js"></script> 18 <script src="onosui.js"></script>
18 19
19 </head> 20 </head>
...@@ -32,20 +33,20 @@ ...@@ -32,20 +33,20 @@
32 <div id="view"></div> 33 <div id="view"></div>
33 </div> 34 </div>
34 35
35 - // Initialize the UI... 36 + <!-- Initialize the UI...-->
36 <script type="text/javascript"> 37 <script type="text/javascript">
37 var ONOS = $.onos({note: "config, if needed"}); 38 var ONOS = $.onos({note: "config, if needed"});
38 </script> 39 </script>
39 40
40 - // include module files 41 + <!-- include module files-->
41 - // + mast.js 42 + <!-- + mast.js-->
42 - // + nav.js 43 + <!-- + nav.js-->
43 - // + .... application views 44 + <!-- + .... application views-->
44 45
45 - // for now, we are just bootstrapping the network visualization 46 + <!-- for now, we are just bootstrapping the network visualization-->
46 <script src="network.js" type="text/javascript"></script> 47 <script src="network.js" type="text/javascript"></script>
47 48
48 - // finally, build the UI 49 + <!-- finally, build the UI-->
49 <script type="text/javascript"> 50 <script type="text/javascript">
50 $(ONOS.buildUi); 51 $(ONOS.buildUi);
51 </script> 52 </script>
......
...@@ -10,11 +10,16 @@ ...@@ -10,11 +10,16 @@
10 var api = onos.api; 10 var api = onos.api;
11 11
12 var config = { 12 var config = {
13 + layering: false,
13 jsonUrl: 'network.json', 14 jsonUrl: 'network.json',
15 + iconUrl: {
16 + pkt: 'pkt.png',
17 + opt: 'opt.png'
18 + },
14 mastHeight: 32, 19 mastHeight: 32,
15 force: { 20 force: {
16 - linkDistance: 150, 21 + linkDistance: 240,
17 - linkStrength: 0.9, 22 + linkStrength: 0.8,
18 charge: -400, 23 charge: -400,
19 ticksWithoutCollisions: 50, 24 ticksWithoutCollisions: 50,
20 marginLR: 20, 25 marginLR: 20,
...@@ -26,8 +31,9 @@ ...@@ -26,8 +31,9 @@
26 } 31 }
27 }, 32 },
28 labels: { 33 labels: {
29 - padLR: 3, 34 + imgPad: 22,
30 - padTB: 2, 35 + padLR: 8,
36 + padTB: 6,
31 marginLR: 3, 37 marginLR: 3,
32 marginTB: 2 38 marginTB: 2
33 }, 39 },
...@@ -53,7 +59,7 @@ ...@@ -53,7 +59,7 @@
53 d3.json(config.jsonUrl, function (err, data) { 59 d3.json(config.jsonUrl, function (err, data) {
54 if (err) { 60 if (err) {
55 alert('Oops! Error reading JSON...\n\n' + 61 alert('Oops! Error reading JSON...\n\n' +
56 - 'URL: ' + jsonUrl + '\n\n' + 62 + 'URL: ' + config.jsonUrl + '\n\n' +
57 'Error: ' + err.message); 63 'Error: ' + err.message);
58 return; 64 return;
59 } 65 }
...@@ -100,7 +106,7 @@ ...@@ -100,7 +106,7 @@
100 106
101 network.data.nodes.forEach(function(n) { 107 network.data.nodes.forEach(function(n) {
102 var ypc = yPosConstraintForNode(n), 108 var ypc = yPosConstraintForNode(n),
103 - ix = Math.random() * 0.8 * nw + 0.1 * nw, 109 + ix = Math.random() * 0.6 * nw + 0.2 * nw,
104 iy = ypc * nh, 110 iy = ypc * nh,
105 node = { 111 node = {
106 id: n.id, 112 id: n.id,
...@@ -153,10 +159,48 @@ ...@@ -153,10 +159,48 @@
153 .attr('height', view.height) 159 .attr('height', view.height)
154 .append('g') 160 .append('g')
155 .attr('transform', config.force.translate()); 161 .attr('transform', config.force.translate());
162 +// .attr('id', 'zoomable')
163 +// .call(d3.behavior.zoom().on("zoom", zoomRedraw));
164 +
165 +// function zoomRedraw() {
166 +// d3.select("#zoomable").attr("transform",
167 +// "translate(" + d3.event.translate + ")"
168 +// + " scale(" + d3.event.scale + ")");
169 +// }
170 +
171 + // TODO: svg.append('defs') for markers?
172 +
173 + // TODO: move glow/blur stuff to util script
174 + var glow = network.svg.append('filter')
175 + .attr('x', '-50%')
176 + .attr('y', '-50%')
177 + .attr('width', '200%')
178 + .attr('height', '200%')
179 + .attr('id', 'blue-glow');
180 +
181 + glow.append('feColorMatrix')
182 + .attr('type', 'matrix')
183 + .attr('values', '0 0 0 0 0 ' +
184 + '0 0 0 0 0 ' +
185 + '0 0 0 0 .7 ' +
186 + '0 0 0 1 0 ');
187 +
188 + glow.append('feGaussianBlur')
189 + .attr('stdDeviation', 3)
190 + .attr('result', 'coloredBlur');
191 +
192 + glow.append('feMerge').selectAll('feMergeNode')
193 + .data(['coloredBlur', 'SourceGraphic'])
194 + .enter().append('feMergeNode')
195 + .attr('in', String);
156 196
157 - // TODO: svg.append('defs')
158 - // TODO: glow/blur stuff
159 // TODO: legend (and auto adjust on scroll) 197 // TODO: legend (and auto adjust on scroll)
198 +// $('#view').on('scroll', function() {
199 +//
200 +// });
201 +
202 +
203 +
160 204
161 network.link = network.svg.append('g').selectAll('.link') 205 network.link = network.svg.append('g').selectAll('.link')
162 .data(network.force.links(), function(d) {return d.id}) 206 .data(network.force.links(), function(d) {return d.id})
...@@ -164,37 +208,103 @@ ...@@ -164,37 +208,103 @@
164 .attr('class', 'link'); 208 .attr('class', 'link');
165 209
166 // TODO: drag behavior 210 // TODO: drag behavior
167 - // TODO: closest node deselect 211 + network.draggedThreshold = d3.scale.linear()
212 + .domain([0, 0.1])
213 + .range([5, 20])
214 + .clamp(true);
215 +
216 + function dragged(d) {
217 + var threshold = network.draggedThreshold(network.force.alpha()),
218 + dx = d.oldX - d.px,
219 + dy = d.oldY - d.py;
220 + if (Math.abs(dx) >= threshold || Math.abs(dy) >= threshold) {
221 + d.dragged = true;
222 + }
223 + return d.dragged;
224 + }
225 +
226 + network.drag = d3.behavior.drag()
227 + .origin(function(d) { return d; })
228 + .on('dragstart', function(d) {
229 + d.oldX = d.x;
230 + d.oldY = d.y;
231 + d.dragged = false;
232 + d.fixed |= 2;
233 + })
234 + .on('drag', function(d) {
235 + d.px = d3.event.x;
236 + d.py = d3.event.y;
237 + if (dragged(d)) {
238 + if (!network.force.alpha()) {
239 + network.force.alpha(.025);
240 + }
241 + }
242 + })
243 + .on('dragend', function(d) {
244 + if (!dragged(d)) {
245 + selectObject(d, this);
246 + }
247 + d.fixed &= ~6;
248 + });
249 +
250 + $('#view').on('click', function(e) {
251 + if (!$(e.target).closest('.node').length) {
252 + deselectObject();
253 + }
254 + });
255 +
168 256
169 - // TODO: add drag, mouseover, mouseout behaviors
170 network.node = network.svg.selectAll('.node') 257 network.node = network.svg.selectAll('.node')
171 .data(network.force.nodes(), function(d) {return d.id}) 258 .data(network.force.nodes(), function(d) {return d.id})
172 .enter().append('g') 259 .enter().append('g')
173 - .attr('class', 'node') 260 + .attr('class', function(d) {
261 + return 'node ' + d.type;
262 + })
174 .attr('transform', function(d) { 263 .attr('transform', function(d) {
175 return translate(d.x, d.y); 264 return translate(d.x, d.y);
176 }) 265 })
177 - // .call(network.drag) 266 + .call(network.drag)
178 - .on('mouseover', function(d) {}) 267 + .on('mouseover', function(d) {
179 - .on('mouseout', function(d) {}); 268 + if (!selected.obj) {
269 + if (network.mouseoutTimeout) {
270 + clearTimeout(network.mouseoutTimeout);
271 + network.mouseoutTimeout = null;
272 + }
273 + highlightObject(d);
274 + }
275 + })
276 + .on('mouseout', function(d) {
277 + if (!selected.obj) {
278 + if (network.mouseoutTimeout) {
279 + clearTimeout(network.mouseoutTimeout);
280 + network.mouseoutTimeout = null;
281 + }
282 + network.mouseoutTimeout = setTimeout(function() {
283 + highlightObject(null);
284 + }, 160);
285 + }
286 + });
180 287
181 - // TODO: augment stroke and fill functions
182 network.nodeRect = network.node.append('rect') 288 network.nodeRect = network.node.append('rect')
183 - // TODO: css for node rects
184 .attr('rx', 5) 289 .attr('rx', 5)
185 .attr('ry', 5) 290 .attr('ry', 5)
186 - .attr('stroke', function(d) { return '#000'}) 291 + .attr('width', 126)
187 - .attr('fill', function(d) { return '#ddf'}) 292 + .attr('height', 40);
188 - .attr('width', 60)
189 - .attr('height', 24);
190 293
191 network.node.each(function(d) { 294 network.node.each(function(d) {
192 var node = d3.select(this), 295 var node = d3.select(this),
193 - rect = node.select('rect'); 296 + rect = node.select('rect'),
194 - var text = node.append('text') 297 + img = node.append('svg:image')
195 - .text(d.id) 298 + .attr('x', -16)
196 - .attr('dx', '1em') 299 + .attr('y', -16)
197 - .attr('dy', '2.1em'); 300 + .attr('width', 32)
301 + .attr('height', 32)
302 + .attr('xlink:href', iconUrl(d)),
303 + text = node.append('text')
304 + .text(d.id)
305 + .attr('dy', '1.1em'),
306 + dummy;
307 +
198 }); 308 });
199 309
200 // this function is scheduled to happen soon after the given thread ends 310 // this function is scheduled to happen soon after the given thread ends
...@@ -207,12 +317,64 @@ ...@@ -207,12 +317,64 @@
207 first = true; 317 first = true;
208 318
209 // NOTE: probably unnecessary code if we only have one line. 319 // NOTE: probably unnecessary code if we only have one line.
320 + text.each(function() {
321 + var box = this.getBBox();
322 + if (first || box.x < bounds.x1) {
323 + bounds.x1 = box.x;
324 + }
325 + if (first || box.y < bounds.y1) {
326 + bounds.y1 = box.y;
327 + }
328 + if (first || box.x + box.width < bounds.x2) {
329 + bounds.x2 = box.x + box.width;
330 + }
331 + if (first || box.y + box.height < bounds.y2) {
332 + bounds.y2 = box.y + box.height;
333 + }
334 + first = false;
335 + }).attr('text-anchor', 'middle');
336 +
337 + var lab = config.labels,
338 + oldWidth = bounds.x2 - bounds.x1;
339 +
340 + bounds.x1 -= oldWidth / 2;
341 + bounds.x2 -= oldWidth / 2;
342 +
343 + bounds.x1 -= (lab.padLR + lab.imgPad);
344 + bounds.y1 -= lab.padTB;
345 + bounds.x2 += lab.padLR;
346 + bounds.y2 += lab.padTB;
347 +
348 + node.select('rect')
349 + .attr('x', bounds.x1)
350 + .attr('y', bounds.y1)
351 + .attr('width', bounds.x2 - bounds.x1)
352 + .attr('height', bounds.y2 - bounds.y1);
353 +
354 + node.select('image')
355 + .attr('x', bounds.x1);
356 +
357 + d.extent = {
358 + left: bounds.x1 - lab.marginLR,
359 + right: bounds.x2 + lab.marginLR,
360 + top: bounds.y1 - lab.marginTB,
361 + bottom: bounds.y2 + lab.marginTB
362 + };
363 +
364 + d.edge = {
365 + left : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x1, bounds.y2),
366 + right : new geo.LineSegment(bounds.x2, bounds.y1, bounds.x2, bounds.y2),
367 + top : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x2, bounds.y1),
368 + bottom : new geo.LineSegment(bounds.x1, bounds.y2, bounds.x2, bounds.y2)
369 + };
370 +
371 + // ====
210 }); 372 });
211 373
212 network.numTicks = 0; 374 network.numTicks = 0;
213 network.preventCollisions = false; 375 network.preventCollisions = false;
214 network.force.start(); 376 network.force.start();
215 - for (var i = 0; i < config.ticksWithoutCollisions; i++) { 377 + for (var i = 0; i < config.force.ticksWithoutCollisions; i++) {
216 network.force.tick(); 378 network.force.tick();
217 } 379 }
218 network.preventCollisions = true; 380 network.preventCollisions = true;
...@@ -221,22 +383,78 @@ ...@@ -221,22 +383,78 @@
221 383
222 } 384 }
223 385
386 + function iconUrl(d) {
387 + return config.iconUrl[d.type];
388 + }
389 +
224 function translate(x, y) { 390 function translate(x, y) {
225 return 'translate(' + x + ',' + y + ')'; 391 return 'translate(' + x + ',' + y + ')';
226 } 392 }
227 393
394 + function preventCollisions() {
395 + var quadtree = d3.geom.quadtree(network.nodes);
396 +
397 + network.nodes.forEach(function(n) {
398 + var nx1 = n.x + n.extent.left,
399 + nx2 = n.x + n.extent.right,
400 + ny1 = n.y + n.extent.top,
401 + ny2 = n.y + n.extent.bottom;
402 +
403 + quadtree.visit(function(quad, x1, y1, x2, y2) {
404 + if (quad.point && quad.point !== n) {
405 + // check if the rectangles intersect
406 + var p = quad.point,
407 + px1 = p.x + p.extent.left,
408 + px2 = p.x + p.extent.right,
409 + py1 = p.y + p.extent.top,
410 + py2 = p.y + p.extent.bottom,
411 + ix = (px1 <= nx2 && nx1 <= px2 && py1 <= ny2 && ny1 <= py2);
412 + if (ix) {
413 + var xa1 = nx2 - px1, // shift n left , p right
414 + xa2 = px2 - nx1, // shift n right, p left
415 + ya1 = ny2 - py1, // shift n up , p down
416 + ya2 = py2 - ny1, // shift n down , p up
417 + adj = Math.min(xa1, xa2, ya1, ya2);
418 +
419 + if (adj == xa1) {
420 + n.x -= adj / 2;
421 + p.x += adj / 2;
422 + } else if (adj == xa2) {
423 + n.x += adj / 2;
424 + p.x -= adj / 2;
425 + } else if (adj == ya1) {
426 + n.y -= adj / 2;
427 + p.y += adj / 2;
428 + } else if (adj == ya2) {
429 + n.y += adj / 2;
430 + p.y -= adj / 2;
431 + }
432 + }
433 + return ix;
434 + }
435 + });
436 +
437 + });
438 + }
228 439
229 function tick(e) { 440 function tick(e) {
230 network.numTicks++; 441 network.numTicks++;
231 442
232 - // adjust the y-coord of each node, based on y-pos constraints 443 + if (config.layering) {
233 -// network.nodes.forEach(function (n) { 444 + // adjust the y-coord of each node, based on y-pos constraints
234 -// var z = e.alpha * n.constraint.weight; 445 + network.nodes.forEach(function (n) {
235 -// if (!isNaN(n.constraint.y)) { 446 + var z = e.alpha * n.constraint.weight;
236 -// n.y = (n.constraint.y * z + n.y * (1 - z)); 447 + if (!isNaN(n.constraint.y)) {
237 -// } 448 + n.y = (n.constraint.y * z + n.y * (1 - z));
238 -// }); 449 + }
450 + });
451 + }
239 452
453 + if (network.preventCollisions) {
454 + preventCollisions();
455 + }
456 +
457 + // TODO: use intersection technique for source end of link also
240 network.link 458 network.link
241 .attr('x1', function(d) { 459 .attr('x1', function(d) {
242 return d.source.x; 460 return d.source.x;
...@@ -244,11 +462,24 @@ ...@@ -244,11 +462,24 @@
244 .attr('y1', function(d) { 462 .attr('y1', function(d) {
245 return d.source.y; 463 return d.source.y;
246 }) 464 })
247 - .attr('x2', function(d) { 465 + .each(function(d) {
248 - return d.target.x; 466 + var x = d.target.x,
249 - }) 467 + y = d.target.y,
250 - .attr('y2', function(d) { 468 + line = new geo.LineSegment(d.source.x, d.source.y, x, y);
251 - return d.target.y; 469 +
470 + for (var e in d.target.edge) {
471 + var ix = line.intersect(d.target.edge[e].offset(x,y));
472 + if (ix.in1 && ix.in2) {
473 + x = ix.x;
474 + y = ix.y;
475 + break;
476 + }
477 + }
478 +
479 + d3.select(this)
480 + .attr('x2', x)
481 + .attr('y2', y);
482 +
252 }); 483 });
253 484
254 network.node 485 network.node
......
...@@ -7,50 +7,50 @@ ...@@ -7,50 +7,50 @@
7 }, 7 },
8 "nodes": [ 8 "nodes": [
9 { 9 {
10 - "id": "switch-1", 10 + "id": "sample1",
11 "type": "opt", 11 "type": "opt",
12 "status": "good" 12 "status": "good"
13 }, 13 },
14 { 14 {
15 - "id": "switch-2", 15 + "id": "00:00:00:00:00:00:00:02",
16 "type": "opt", 16 "type": "opt",
17 "status": "good" 17 "status": "good"
18 }, 18 },
19 { 19 {
20 - "id": "switch-3", 20 + "id": "00:00:00:00:00:00:00:03",
21 "type": "opt", 21 "type": "opt",
22 "status": "good" 22 "status": "good"
23 }, 23 },
24 { 24 {
25 - "id": "switch-4", 25 + "id": "00:00:00:00:00:00:00:04",
26 "type": "opt", 26 "type": "opt",
27 "status": "good" 27 "status": "good"
28 }, 28 },
29 { 29 {
30 - "id": "switch-11", 30 + "id": "00:00:00:00:00:00:00:11",
31 "type": "pkt", 31 "type": "pkt",
32 "status": "good" 32 "status": "good"
33 }, 33 },
34 { 34 {
35 - "id": "switch-12", 35 + "id": "00:00:00:00:00:00:00:12",
36 "type": "pkt", 36 "type": "pkt",
37 "status": "good" 37 "status": "good"
38 }, 38 },
39 { 39 {
40 - "id": "switch-13", 40 + "id": "00:00:00:00:00:00:00:13",
41 "type": "pkt", 41 "type": "pkt",
42 "status": "good" 42 "status": "good"
43 } 43 }
44 ], 44 ],
45 "links": [ 45 "links": [
46 - { "src": "switch-1", "dst": "switch-2" }, 46 + { "src": "sample1", "dst": "00:00:00:00:00:00:00:02" },
47 - { "src": "switch-1", "dst": "switch-3" }, 47 + { "src": "sample1", "dst": "00:00:00:00:00:00:00:03" },
48 - { "src": "switch-1", "dst": "switch-4" }, 48 + { "src": "sample1", "dst": "00:00:00:00:00:00:00:04" },
49 - { "src": "switch-2", "dst": "switch-3" }, 49 + { "src": "00:00:00:00:00:00:00:02", "dst": "00:00:00:00:00:00:00:03" },
50 - { "src": "switch-2", "dst": "switch-4" }, 50 + { "src": "00:00:00:00:00:00:00:02", "dst": "00:00:00:00:00:00:00:04" },
51 - { "src": "switch-3", "dst": "switch-4" }, 51 + { "src": "00:00:00:00:00:00:00:03", "dst": "00:00:00:00:00:00:00:04" },
52 - { "src": "switch-13", "dst": "switch-3" }, 52 + { "src": "00:00:00:00:00:00:00:13", "dst": "00:00:00:00:00:00:00:03" },
53 - { "src": "switch-12", "dst": "switch-2" }, 53 + { "src": "00:00:00:00:00:00:00:12", "dst": "00:00:00:00:00:00:00:02" },
54 - { "src": "switch-11", "dst": "switch-1" } 54 + { "src": "00:00:00:00:00:00:00:11", "dst": "sample1" }
55 ] 55 ]
56 } 56 }
......
...@@ -13,7 +13,7 @@ body, html { ...@@ -13,7 +13,7 @@ body, html {
13 */ 13 */
14 14
15 span.title { 15 span.title {
16 - color: red; 16 + color: darkblue;
17 font-size: 16pt; 17 font-size: 16pt;
18 font-style: italic; 18 font-style: italic;
19 } 19 }
...@@ -30,7 +30,7 @@ span.right { ...@@ -30,7 +30,7 @@ span.right {
30 * === DEBUGGING ====== 30 * === DEBUGGING ======
31 */ 31 */
32 svg { 32 svg {
33 - border: 1px dashed red; 33 + /*border: 1px dashed red;*/
34 } 34 }
35 35
36 36
...@@ -64,36 +64,47 @@ marker#end { ...@@ -64,36 +64,47 @@ marker#end {
64 -moz-transition: opacity 250ms; 64 -moz-transition: opacity 250ms;
65 } 65 }
66 66
67 -.node text { 67 +/*differentiate between packet and optical nodes*/
68 - fill: #000; 68 +svg .node.pkt rect {
69 + fill: #77a;
70 +}
71 +
72 +svg .node.opt rect {
73 + fill: #7a7;
74 +}
75 +
76 +svg .node text {
77 + fill: white;
69 font: 10px sans-serif; 78 font: 10px sans-serif;
70 pointer-events: none; 79 pointer-events: none;
71 } 80 }
72 81
73 -.node.selected rect { 82 +svg .node.selected rect {
74 filter: url(#blue-glow); 83 filter: url(#blue-glow);
75 } 84 }
76 85
77 -.link.inactive, 86 +svg .link.inactive,
78 -.node.inactive rect, 87 +svg .node.inactive rect,
79 -.node.inactive text { 88 +svg .node.inactive text,
89 +svg .node.inactive image {
80 opacity: .2; 90 opacity: .2;
81 } 91 }
82 92
83 -.node.inactive.selected rect, 93 +svg .node.inactive.selected rect,
84 -.node.inactive.selected text { 94 +svg .node.inactive.selected text,
95 +svg .node.inactive.selected image {
85 opacity: .6; 96 opacity: .6;
86 } 97 }
87 98
88 -.legend { 99 +svg .legend {
89 position: fixed; 100 position: fixed;
90 } 101 }
91 102
92 -.legend .category rect { 103 +svg .legend .category rect {
93 stroke-width: 1px; 104 stroke-width: 1px;
94 } 105 }
95 106
96 -.legend .category text { 107 +svg .legend .category text {
97 fill: #000; 108 fill: #000;
98 font: 10px sans-serif; 109 font: 10px sans-serif;
99 pointer-events: none; 110 pointer-events: none;
...@@ -110,15 +121,15 @@ marker#end { ...@@ -110,15 +121,15 @@ marker#end {
110 #frame { 121 #frame {
111 width: 100%; 122 width: 100%;
112 height: 100%; 123 height: 100%;
113 - background-color: #ffd; 124 + background-color: #cdf;
114 } 125 }
115 126
116 #mast { 127 #mast {
117 height: 32px; 128 height: 32px;
118 - background-color: #dda; 129 + background-color: #abe;
119 vertical-align: baseline; 130 vertical-align: baseline;
120 } 131 }
121 132
122 #main { 133 #main {
123 - background-color: #99b; 134 + background-color: #99c;
124 } 135 }
......