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
2042 additions
and
191 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 & action pair to be applied to | 24 | * Represents a generalized match & 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 & related services API definitions. | 21 | * Flow rule model & related services API definitions. |
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.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. |
32 | + */ | ||
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 | ||
5 | */ | 59 | */ |
6 | -public interface IntentOperations { | 60 | + public static Builder builder() { |
61 | + return new Builder(); | ||
62 | + } | ||
7 | 63 | ||
8 | - // TODO: elaborate once the revised BatchOperation scheme is in place | 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 | + } | ||
112 | + | ||
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 & withdraw operations. Such a batch is | 58 | * Submits a batch of submit & 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 | ||
... | @@ -115,13 +116,11 @@ public class SimpleDeviceStore | ... | @@ -115,13 +116,11 @@ public class SimpleDeviceStore |
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, |
... | @@ -145,7 +144,6 @@ public class SimpleDeviceStore | ... | @@ -145,7 +144,6 @@ 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, |
... | @@ -162,14 +160,21 @@ public class SimpleDeviceStore | ... | @@ -162,14 +160,21 @@ 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()) |
... | @@ -214,7 +219,6 @@ public class SimpleDeviceStore | ... | @@ -214,7 +219,6 @@ public class SimpleDeviceStore |
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 | ||
... | @@ -327,7 +331,6 @@ public class SimpleDeviceStore | ... | @@ -327,7 +331,6 @@ public class SimpleDeviceStore |
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) { |
... | @@ -447,7 +450,7 @@ public class SimpleDeviceStore | ... | @@ -447,7 +450,7 @@ 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 | } | ... | ... |
... | @@ -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()); | ... | ... |
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
... | @@ -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> { | ... | ... |
providers/openflow/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
... | @@ -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(); | ... | ... |
web/gui/src/main/webapp/geometry.js
0 → 100644
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') |
298 | + .attr('x', -16) | ||
299 | + .attr('y', -16) | ||
300 | + .attr('width', 32) | ||
301 | + .attr('height', 32) | ||
302 | + .attr('xlink:href', iconUrl(d)), | ||
303 | + text = node.append('text') | ||
195 | .text(d.id) | 304 | .text(d.id) |
196 | - .attr('dx', '1em') | 305 | + .attr('dy', '1.1em'), |
197 | - .attr('dy', '2.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 | ||
443 | + if (config.layering) { | ||
232 | // adjust the y-coord of each node, based on y-pos constraints | 444 | // adjust the y-coord of each node, based on y-pos constraints |
233 | -// network.nodes.forEach(function (n) { | 445 | + network.nodes.forEach(function (n) { |
234 | -// var z = e.alpha * n.constraint.weight; | 446 | + var z = e.alpha * n.constraint.weight; |
235 | -// if (!isNaN(n.constraint.y)) { | 447 | + if (!isNaN(n.constraint.y)) { |
236 | -// n.y = (n.constraint.y * z + n.y * (1 - z)); | 448 | + n.y = (n.constraint.y * z + n.y * (1 - z)); |
237 | -// } | 449 | + } |
238 | -// }); | 450 | + }); |
451 | + } | ||
452 | + | ||
453 | + if (network.preventCollisions) { | ||
454 | + preventCollisions(); | ||
455 | + } | ||
239 | 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 | } | ... | ... |
web/gui/src/main/webapp/opt.png
0 → 100644
1.48 KB
web/gui/src/main/webapp/pkt.png
0 → 100644
2.07 KB
-
Please register or login to post a comment