Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
Showing
102 changed files
with
1356 additions
and
652 deletions
... | @@ -11,6 +11,9 @@ import org.onlab.onos.cluster.ClusterService; | ... | @@ -11,6 +11,9 @@ import org.onlab.onos.cluster.ClusterService; |
11 | import org.onlab.onos.net.device.DeviceEvent; | 11 | import org.onlab.onos.net.device.DeviceEvent; |
12 | import org.onlab.onos.net.device.DeviceListener; | 12 | import org.onlab.onos.net.device.DeviceListener; |
13 | import org.onlab.onos.net.device.DeviceService; | 13 | import org.onlab.onos.net.device.DeviceService; |
14 | +import org.onlab.onos.net.intent.IntentEvent; | ||
15 | +import org.onlab.onos.net.intent.IntentListener; | ||
16 | +import org.onlab.onos.net.intent.IntentService; | ||
14 | import org.slf4j.Logger; | 17 | import org.slf4j.Logger; |
15 | 18 | ||
16 | import static org.slf4j.LoggerFactory.getLogger; | 19 | import static org.slf4j.LoggerFactory.getLogger; |
... | @@ -29,13 +32,18 @@ public class FooComponent { | ... | @@ -29,13 +32,18 @@ public class FooComponent { |
29 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 32 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
30 | protected DeviceService deviceService; | 33 | protected DeviceService deviceService; |
31 | 34 | ||
35 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
36 | + protected IntentService intentService; | ||
37 | + | ||
32 | private final ClusterEventListener clusterListener = new InnerClusterListener(); | 38 | private final ClusterEventListener clusterListener = new InnerClusterListener(); |
33 | private final DeviceListener deviceListener = new InnerDeviceListener(); | 39 | private final DeviceListener deviceListener = new InnerDeviceListener(); |
40 | + private final IntentListener intentListener = new InnerIntentListener(); | ||
34 | 41 | ||
35 | @Activate | 42 | @Activate |
36 | public void activate() { | 43 | public void activate() { |
37 | clusterService.addListener(clusterListener); | 44 | clusterService.addListener(clusterListener); |
38 | deviceService.addListener(deviceListener); | 45 | deviceService.addListener(deviceListener); |
46 | + intentService.addListener(intentListener); | ||
39 | log.info("Started"); | 47 | log.info("Started"); |
40 | } | 48 | } |
41 | 49 | ||
... | @@ -43,6 +51,7 @@ public class FooComponent { | ... | @@ -43,6 +51,7 @@ public class FooComponent { |
43 | public void deactivate() { | 51 | public void deactivate() { |
44 | clusterService.removeListener(clusterListener); | 52 | clusterService.removeListener(clusterListener); |
45 | deviceService.removeListener(deviceListener); | 53 | deviceService.removeListener(deviceListener); |
54 | + intentService.removeListener(intentListener); | ||
46 | log.info("Stopped"); | 55 | log.info("Stopped"); |
47 | } | 56 | } |
48 | 57 | ||
... | @@ -59,6 +68,23 @@ public class FooComponent { | ... | @@ -59,6 +68,23 @@ public class FooComponent { |
59 | log.info("YEEEEHAAAAW! {}", event); | 68 | log.info("YEEEEHAAAAW! {}", event); |
60 | } | 69 | } |
61 | } | 70 | } |
71 | + | ||
72 | + private class InnerIntentListener implements IntentListener { | ||
73 | + @Override | ||
74 | + public void event(IntentEvent event) { | ||
75 | + String message; | ||
76 | + if (event.type() == IntentEvent.Type.SUBMITTED) { | ||
77 | + message = "WOW! It looks like someone has some intentions: {}"; | ||
78 | + } else if (event.type() == IntentEvent.Type.INSTALLED) { | ||
79 | + message = "AWESOME! So far things are going great: {}"; | ||
80 | + } else if (event.type() == IntentEvent.Type.WITHDRAWN) { | ||
81 | + message = "HMMM! Ambitions are fading apparently: {}"; | ||
82 | + } else { | ||
83 | + message = "CRAP!!! Things are not turning out as intended: {}"; | ||
84 | + } | ||
85 | + log.info(message, event.subject()); | ||
86 | + } | ||
87 | + } | ||
62 | } | 88 | } |
63 | 89 | ||
64 | 90 | ... | ... |
1 | +package org.onlab.onos.cli; | ||
2 | + | ||
3 | +import org.apache.karaf.shell.commands.Command; | ||
4 | +import org.onlab.onos.cluster.ClusterService; | ||
5 | +import org.onlab.onos.net.device.DeviceService; | ||
6 | +import org.onlab.onos.net.flow.FlowRuleService; | ||
7 | +import org.onlab.onos.net.host.HostService; | ||
8 | +import org.onlab.onos.net.intent.IntentService; | ||
9 | +import org.onlab.onos.net.link.LinkService; | ||
10 | +import org.onlab.onos.net.topology.Topology; | ||
11 | +import org.onlab.onos.net.topology.TopologyService; | ||
12 | + | ||
13 | +/** | ||
14 | + * Provides summary of ONOS model. | ||
15 | + */ | ||
16 | +@Command(scope = "onos", name = "summary", | ||
17 | + description = "Provides summary of ONOS model") | ||
18 | +public class SummaryCommand extends AbstractShellCommand { | ||
19 | + | ||
20 | + @Override | ||
21 | + protected void execute() { | ||
22 | + TopologyService topologyService = get(TopologyService.class); | ||
23 | + Topology topology = topologyService.currentTopology(); | ||
24 | + print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d", | ||
25 | + get(ClusterService.class).getNodes().size(), | ||
26 | + get(DeviceService.class).getDeviceCount(), | ||
27 | + get(LinkService.class).getLinkCount(), | ||
28 | + get(HostService.class).getHostCount(), | ||
29 | + topologyService.getClusters(topology).size(), | ||
30 | + topology.pathCount(), | ||
31 | + get(FlowRuleService.class).getFlowRuleCount(), | ||
32 | + get(IntentService.class).getIntentCount()); | ||
33 | + } | ||
34 | + | ||
35 | +} |
... | @@ -35,7 +35,7 @@ public class DevicesListCommand extends AbstractShellCommand { | ... | @@ -35,7 +35,7 @@ public class DevicesListCommand extends AbstractShellCommand { |
35 | * @param service device service | 35 | * @param service device service |
36 | * @return sorted device list | 36 | * @return sorted device list |
37 | */ | 37 | */ |
38 | - protected List<Device> getSortedDevices(DeviceService service) { | 38 | + protected static List<Device> getSortedDevices(DeviceService service) { |
39 | List<Device> devices = newArrayList(service.getDevices()); | 39 | List<Device> devices = newArrayList(service.getDevices()); |
40 | Collections.sort(devices, Comparators.ELEMENT_COMPARATOR); | 40 | Collections.sort(devices, Comparators.ELEMENT_COMPARATOR); |
41 | return devices; | 41 | return devices; | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | import static com.google.common.collect.Lists.newArrayList; | 3 | import static com.google.common.collect.Lists.newArrayList; |
4 | +import static org.onlab.onos.cli.net.DevicesListCommand.getSortedDevices; | ||
4 | 5 | ||
5 | import java.util.Collections; | 6 | import java.util.Collections; |
6 | import java.util.List; | 7 | import java.util.List; |
... | @@ -46,7 +47,7 @@ public class FlowsListCommand extends AbstractShellCommand { | ... | @@ -46,7 +47,7 @@ public class FlowsListCommand extends AbstractShellCommand { |
46 | DeviceService deviceService = get(DeviceService.class); | 47 | DeviceService deviceService = get(DeviceService.class); |
47 | FlowRuleService service = get(FlowRuleService.class); | 48 | FlowRuleService service = get(FlowRuleService.class); |
48 | Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service); | 49 | Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service); |
49 | - for (Device d : flows.keySet()) { | 50 | + for (Device d : getSortedDevices(deviceService)) { |
50 | printFlows(d, flows.get(d)); | 51 | printFlows(d, flows.get(d)); |
51 | } | 52 | } |
52 | } | 53 | } |
... | @@ -57,14 +58,15 @@ public class FlowsListCommand extends AbstractShellCommand { | ... | @@ -57,14 +58,15 @@ public class FlowsListCommand extends AbstractShellCommand { |
57 | * @param service device service | 58 | * @param service device service |
58 | * @return sorted device list | 59 | * @return sorted device list |
59 | */ | 60 | */ |
60 | - protected Map<Device, List<FlowEntry>> getSortedFlows(DeviceService deviceService, FlowRuleService service) { | 61 | + protected Map<Device, List<FlowEntry>> getSortedFlows(DeviceService deviceService, |
62 | + FlowRuleService service) { | ||
61 | Map<Device, List<FlowEntry>> flows = Maps.newHashMap(); | 63 | Map<Device, List<FlowEntry>> flows = Maps.newHashMap(); |
62 | List<FlowEntry> rules; | 64 | List<FlowEntry> rules; |
63 | FlowEntryState s = null; | 65 | FlowEntryState s = null; |
64 | if (state != null && !state.equals("any")) { | 66 | if (state != null && !state.equals("any")) { |
65 | s = FlowEntryState.valueOf(state.toUpperCase()); | 67 | s = FlowEntryState.valueOf(state.toUpperCase()); |
66 | } | 68 | } |
67 | - Iterable<Device> devices = uri == null ? deviceService.getDevices() : | 69 | + Iterable<Device> devices = uri == null ? deviceService.getDevices() : |
68 | Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri))); | 70 | Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri))); |
69 | for (Device d : devices) { | 71 | for (Device d : devices) { |
70 | if (s == null) { | 72 | if (s == null) { |
... | @@ -89,18 +91,16 @@ public class FlowsListCommand extends AbstractShellCommand { | ... | @@ -89,18 +91,16 @@ public class FlowsListCommand extends AbstractShellCommand { |
89 | * @param flows the set of flows for that device. | 91 | * @param flows the set of flows for that device. |
90 | */ | 92 | */ |
91 | protected void printFlows(Device d, List<FlowEntry> flows) { | 93 | protected void printFlows(Device d, List<FlowEntry> flows) { |
92 | - print("Device: " + d.id()); | 94 | + boolean empty = flows == null || flows.isEmpty(); |
93 | - if (flows == null | flows.isEmpty()) { | 95 | + print("deviceId=%s, flowRuleCount=%d", d.id(), empty ? 0 : flows.size()); |
94 | - print(" %s", "No flows."); | 96 | + if (!empty) { |
95 | - return; | 97 | + for (FlowEntry f : flows) { |
96 | - } | 98 | + print(FMT, Long.toHexString(f.id().value()), f.state(), f.bytes(), |
97 | - for (FlowEntry f : flows) { | 99 | + f.packets(), f.life(), f.priority()); |
98 | - print(FMT, Long.toHexString(f.id().value()), f.state(), f.bytes(), | 100 | + print(SFMT, f.selector().criteria()); |
99 | - f.packets(), f.life(), f.priority()); | 101 | + print(TFMT, f.treatment().instructions()); |
100 | - print(SFMT, f.selector().criteria()); | 102 | + } |
101 | - print(TFMT, f.treatment().instructions()); | ||
102 | } | 103 | } |
103 | - | ||
104 | } | 104 | } |
105 | 105 | ||
106 | } | 106 | } | ... | ... |
... | @@ -24,7 +24,7 @@ public class IntentIdCompleter implements Completer { | ... | @@ -24,7 +24,7 @@ public class IntentIdCompleter implements Completer { |
24 | Iterator<Intent> it = service.getIntents().iterator(); | 24 | Iterator<Intent> it = service.getIntents().iterator(); |
25 | SortedSet<String> strings = delegate.getStrings(); | 25 | SortedSet<String> strings = delegate.getStrings(); |
26 | while (it.hasNext()) { | 26 | while (it.hasNext()) { |
27 | - strings.add(it.next().getId().toString()); | 27 | + strings.add(it.next().id().toString()); |
28 | } | 28 | } |
29 | 29 | ||
30 | // Now let the completer do the work for figuring out what to offer. | 30 | // Now let the completer do the work for figuring out what to offer. | ... | ... |
... | @@ -10,9 +10,9 @@ import org.onlab.onos.net.intent.IntentService; | ... | @@ -10,9 +10,9 @@ import org.onlab.onos.net.intent.IntentService; |
10 | /** | 10 | /** |
11 | * Removes host-to-host connectivity intent. | 11 | * Removes host-to-host connectivity intent. |
12 | */ | 12 | */ |
13 | -@Command(scope = "onos", name = "remove-host-intent", | 13 | +@Command(scope = "onos", name = "remove-intent", |
14 | - description = "Removes host-to-host connectivity intent") | 14 | + description = "Removes the specified intent") |
15 | -public class RemoveHostToHostIntentCommand extends AbstractShellCommand { | 15 | +public class IntentRemoveCommand extends AbstractShellCommand { |
16 | 16 | ||
17 | @Argument(index = 0, name = "id", description = "Intent ID", | 17 | @Argument(index = 0, name = "id", description = "Intent ID", |
18 | required = true, multiValued = false) | 18 | required = true, multiValued = false) | ... | ... |
... | @@ -17,8 +17,8 @@ public class IntentsListCommand extends AbstractShellCommand { | ... | @@ -17,8 +17,8 @@ public class IntentsListCommand extends AbstractShellCommand { |
17 | protected void execute() { | 17 | protected void execute() { |
18 | IntentService service = get(IntentService.class); | 18 | IntentService service = get(IntentService.class); |
19 | for (Intent intent : service.getIntents()) { | 19 | for (Intent intent : service.getIntents()) { |
20 | - IntentState state = service.getIntentState(intent.getId()); | 20 | + IntentState state = service.getIntentState(intent.id()); |
21 | - print("%s %s %s", intent.getId(), state, intent); | 21 | + print("%s %s %s", intent.id(), state, intent); |
22 | } | 22 | } |
23 | } | 23 | } |
24 | 24 | ... | ... |
1 | package org.onlab.onos.cli.net; | 1 | package org.onlab.onos.cli.net; |
2 | 2 | ||
3 | +import org.apache.karaf.shell.commands.Argument; | ||
3 | import org.apache.karaf.shell.commands.Command; | 4 | import org.apache.karaf.shell.commands.Command; |
4 | import org.onlab.onos.net.Device; | 5 | import org.onlab.onos.net.Device; |
5 | import org.onlab.onos.net.Host; | 6 | import org.onlab.onos.net.Host; |
... | @@ -18,8 +19,22 @@ import org.onlab.onos.net.intent.IntentState; | ... | @@ -18,8 +19,22 @@ import org.onlab.onos.net.intent.IntentState; |
18 | description = "Wipes-out the entire network information base, i.e. devices, links, hosts") | 19 | description = "Wipes-out the entire network information base, i.e. devices, links, hosts") |
19 | public class WipeOutCommand extends ClustersListCommand { | 20 | public class WipeOutCommand extends ClustersListCommand { |
20 | 21 | ||
22 | + | ||
23 | + private static final String DISCLAIMER = "Yes, I know it will delete everything!"; | ||
24 | + | ||
25 | + @Argument(index = 0, name = "disclaimer", description = "Device ID", | ||
26 | + required = true, multiValued = false) | ||
27 | + String disclaimer = null; | ||
28 | + | ||
21 | @Override | 29 | @Override |
22 | protected void execute() { | 30 | protected void execute() { |
31 | + if (!disclaimer.equals(DISCLAIMER)) { | ||
32 | + print("I'm afraid I can't do that..."); | ||
33 | + print("You have to acknowledge by: " + DISCLAIMER); | ||
34 | + return; | ||
35 | + } | ||
36 | + | ||
37 | + print("Good bye..."); | ||
23 | DeviceAdminService deviceAdminService = get(DeviceAdminService.class); | 38 | DeviceAdminService deviceAdminService = get(DeviceAdminService.class); |
24 | DeviceService deviceService = get(DeviceService.class); | 39 | DeviceService deviceService = get(DeviceService.class); |
25 | for (Device device : deviceService.getDevices()) { | 40 | for (Device device : deviceService.getDevices()) { |
... | @@ -34,7 +49,7 @@ public class WipeOutCommand extends ClustersListCommand { | ... | @@ -34,7 +49,7 @@ public class WipeOutCommand extends ClustersListCommand { |
34 | 49 | ||
35 | IntentService intentService = get(IntentService.class); | 50 | IntentService intentService = get(IntentService.class); |
36 | for (Intent intent : intentService.getIntents()) { | 51 | for (Intent intent : intentService.getIntents()) { |
37 | - if (intentService.getIntentState(intent.getId()) == IntentState.INSTALLED) { | 52 | + if (intentService.getIntentState(intent.id()) == IntentState.INSTALLED) { |
38 | intentService.withdraw(intent); | 53 | intentService.withdraw(intent); |
39 | } | 54 | } |
40 | } | 55 | } | ... | ... |
158 KB
... | @@ -2,6 +2,9 @@ | ... | @@ -2,6 +2,9 @@ |
2 | 2 | ||
3 | <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | 3 | <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> |
4 | <command> | 4 | <command> |
5 | + <action class="org.onlab.onos.cli.SummaryCommand"/> | ||
6 | + </command> | ||
7 | + <command> | ||
5 | <action class="org.onlab.onos.cli.NodesListCommand"/> | 8 | <action class="org.onlab.onos.cli.NodesListCommand"/> |
6 | </command> | 9 | </command> |
7 | <command> | 10 | <command> |
... | @@ -61,15 +64,15 @@ | ... | @@ -61,15 +64,15 @@ |
61 | <action class="org.onlab.onos.cli.net.IntentsListCommand"/> | 64 | <action class="org.onlab.onos.cli.net.IntentsListCommand"/> |
62 | </command> | 65 | </command> |
63 | <command> | 66 | <command> |
64 | - <action class="org.onlab.onos.cli.net.AddHostToHostIntentCommand"/> | 67 | + <action class="org.onlab.onos.cli.net.IntentRemoveCommand"/> |
65 | <completers> | 68 | <completers> |
66 | - <ref component-id="hostIdCompleter"/> | 69 | + <ref component-id="intentIdCompleter"/> |
67 | </completers> | 70 | </completers> |
68 | </command> | 71 | </command> |
69 | <command> | 72 | <command> |
70 | - <action class="org.onlab.onos.cli.net.RemoveHostToHostIntentCommand"/> | 73 | + <action class="org.onlab.onos.cli.net.AddHostToHostIntentCommand"/> |
71 | <completers> | 74 | <completers> |
72 | - <ref component-id="intentIdCompleter"/> | 75 | + <ref component-id="hostIdCompleter"/> |
73 | </completers> | 76 | </completers> |
74 | </command> | 77 | </command> |
75 | 78 | ... | ... |
... | @@ -115,7 +115,7 @@ public class DefaultFlowRule implements FlowRule { | ... | @@ -115,7 +115,7 @@ public class DefaultFlowRule implements FlowRule { |
115 | } | 115 | } |
116 | 116 | ||
117 | public int hash() { | 117 | public int hash() { |
118 | - return Objects.hash(deviceId, selector, id); | 118 | + return Objects.hash(deviceId, selector, treatment); |
119 | } | 119 | } |
120 | 120 | ||
121 | @Override | 121 | @Override |
... | @@ -132,7 +132,7 @@ public class DefaultFlowRule implements FlowRule { | ... | @@ -132,7 +132,7 @@ public class DefaultFlowRule implements FlowRule { |
132 | if (obj instanceof DefaultFlowRule) { | 132 | if (obj instanceof DefaultFlowRule) { |
133 | DefaultFlowRule that = (DefaultFlowRule) obj; | 133 | DefaultFlowRule that = (DefaultFlowRule) obj; |
134 | return Objects.equals(deviceId, that.deviceId) && | 134 | return Objects.equals(deviceId, that.deviceId) && |
135 | - //Objects.equals(id, that.id) && | 135 | + Objects.equals(id, that.id) && |
136 | Objects.equals(priority, that.priority) && | 136 | Objects.equals(priority, that.priority) && |
137 | Objects.equals(selector, that.selector); | 137 | Objects.equals(selector, that.selector); |
138 | 138 | ||
... | @@ -143,7 +143,7 @@ public class DefaultFlowRule implements FlowRule { | ... | @@ -143,7 +143,7 @@ public class DefaultFlowRule implements FlowRule { |
143 | @Override | 143 | @Override |
144 | public String toString() { | 144 | public String toString() { |
145 | return toStringHelper(this) | 145 | return toStringHelper(this) |
146 | - .add("id", id) | 146 | + .add("id", Long.toHexString(id.value())) |
147 | .add("deviceId", deviceId) | 147 | .add("deviceId", deviceId) |
148 | .add("priority", priority) | 148 | .add("priority", priority) |
149 | .add("selector", selector.criteria()) | 149 | .add("selector", selector.criteria()) |
... | @@ -154,7 +154,7 @@ public class DefaultFlowRule implements FlowRule { | ... | @@ -154,7 +154,7 @@ public class DefaultFlowRule implements FlowRule { |
154 | 154 | ||
155 | @Override | 155 | @Override |
156 | public int timeout() { | 156 | public int timeout() { |
157 | - return timeout > MAX_TIMEOUT ? MAX_TIMEOUT : this.timeout; | 157 | + return timeout; |
158 | } | 158 | } |
159 | 159 | ||
160 | } | 160 | } | ... | ... |
1 | package org.onlab.onos.net.flow; | 1 | package org.onlab.onos.net.flow; |
2 | 2 | ||
3 | +import static org.slf4j.LoggerFactory.getLogger; | ||
4 | + | ||
5 | +import java.util.Collections; | ||
6 | +import java.util.LinkedList; | ||
7 | +import java.util.List; | ||
8 | +import java.util.Objects; | ||
9 | + | ||
3 | import org.onlab.onos.net.PortNumber; | 10 | import org.onlab.onos.net.PortNumber; |
4 | import org.onlab.onos.net.flow.instructions.Instruction; | 11 | import org.onlab.onos.net.flow.instructions.Instruction; |
5 | import org.onlab.onos.net.flow.instructions.Instructions; | 12 | import org.onlab.onos.net.flow.instructions.Instructions; |
... | @@ -8,12 +15,6 @@ import org.onlab.packet.MacAddress; | ... | @@ -8,12 +15,6 @@ import org.onlab.packet.MacAddress; |
8 | import org.onlab.packet.VlanId; | 15 | import org.onlab.packet.VlanId; |
9 | import org.slf4j.Logger; | 16 | import org.slf4j.Logger; |
10 | 17 | ||
11 | -import java.util.Collections; | ||
12 | -import java.util.LinkedList; | ||
13 | -import java.util.List; | ||
14 | - | ||
15 | -import static org.slf4j.LoggerFactory.getLogger; | ||
16 | - | ||
17 | /** | 18 | /** |
18 | * Default traffic treatment implementation. | 19 | * Default traffic treatment implementation. |
19 | */ | 20 | */ |
... | @@ -44,6 +45,25 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { | ... | @@ -44,6 +45,25 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { |
44 | return new Builder(); | 45 | return new Builder(); |
45 | } | 46 | } |
46 | 47 | ||
48 | + //FIXME: Order of instructions may affect hashcode | ||
49 | + @Override | ||
50 | + public int hashCode() { | ||
51 | + return Objects.hash(instructions); | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public boolean equals(Object obj) { | ||
56 | + if (this == obj) { | ||
57 | + return true; | ||
58 | + } | ||
59 | + if (obj instanceof DefaultTrafficTreatment) { | ||
60 | + DefaultTrafficTreatment that = (DefaultTrafficTreatment) obj; | ||
61 | + return Objects.equals(instructions, that.instructions); | ||
62 | + | ||
63 | + } | ||
64 | + return false; | ||
65 | + } | ||
66 | + | ||
47 | /** | 67 | /** |
48 | * Builds a list of treatments following the following order. | 68 | * Builds a list of treatments following the following order. |
49 | * Modifications -> Group -> Output (including drop) | 69 | * Modifications -> Group -> Output (including drop) |
... | @@ -66,6 +86,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { | ... | @@ -66,6 +86,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { |
66 | private Builder() { | 86 | private Builder() { |
67 | } | 87 | } |
68 | 88 | ||
89 | + @Override | ||
69 | public Builder add(Instruction instruction) { | 90 | public Builder add(Instruction instruction) { |
70 | if (drop) { | 91 | if (drop) { |
71 | return this; | 92 | return this; | ... | ... |
... | @@ -13,6 +13,13 @@ import org.onlab.onos.net.DeviceId; | ... | @@ -13,6 +13,13 @@ import org.onlab.onos.net.DeviceId; |
13 | public interface FlowRuleService { | 13 | public interface FlowRuleService { |
14 | 14 | ||
15 | /** | 15 | /** |
16 | + * Returns the number of flow rules in the system. | ||
17 | + * | ||
18 | + * @return flow rule count | ||
19 | + */ | ||
20 | + int getFlowRuleCount(); | ||
21 | + | ||
22 | + /** | ||
16 | * Returns the collection of flow entries applied on the specified device. | 23 | * Returns the collection of flow entries applied on the specified device. |
17 | * This will include flow rules which may not yet have been applied to | 24 | * This will include flow rules which may not yet have been applied to |
18 | * the device. | 25 | * the device. |
... | @@ -59,6 +66,8 @@ public interface FlowRuleService { | ... | @@ -59,6 +66,8 @@ public interface FlowRuleService { |
59 | */ | 66 | */ |
60 | Iterable<FlowRule> getFlowRulesById(ApplicationId id); | 67 | Iterable<FlowRule> getFlowRulesById(ApplicationId id); |
61 | 68 | ||
69 | + //Future<CompletedBatchOperation> applyBatch(BatchOperation<FlowRuleBatchEntry>) | ||
70 | + | ||
62 | /** | 71 | /** |
63 | * Adds the specified flow rule listener. | 72 | * Adds the specified flow rule listener. |
64 | * | 73 | * |
... | @@ -72,7 +81,4 @@ public interface FlowRuleService { | ... | @@ -72,7 +81,4 @@ public interface FlowRuleService { |
72 | * @param listener flow rule listener | 81 | * @param listener flow rule listener |
73 | */ | 82 | */ |
74 | void removeListener(FlowRuleListener listener); | 83 | void removeListener(FlowRuleListener listener); |
75 | - | ||
76 | - | ||
77 | - | ||
78 | } | 84 | } | ... | ... |
... | @@ -10,7 +10,15 @@ import org.onlab.onos.store.Store; | ... | @@ -10,7 +10,15 @@ import org.onlab.onos.store.Store; |
10 | public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> { | 10 | public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> { |
11 | 11 | ||
12 | /** | 12 | /** |
13 | + * Returns the number of flow rule in the store. | ||
14 | + * | ||
15 | + * @return number of flow rules | ||
16 | + */ | ||
17 | + int getFlowRuleCount(); | ||
18 | + | ||
19 | + /** | ||
13 | * Returns the stored flow. | 20 | * Returns the stored flow. |
21 | + * | ||
14 | * @param rule the rule to look for | 22 | * @param rule the rule to look for |
15 | * @return a flow rule | 23 | * @return a flow rule |
16 | */ | 24 | */ |
... | @@ -60,5 +68,4 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat | ... | @@ -60,5 +68,4 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat |
60 | * @return flow_removed event, or null if nothing removed | 68 | * @return flow_removed event, or null if nothing removed |
61 | */ | 69 | */ |
62 | FlowRuleEvent removeFlowRule(FlowEntry rule); | 70 | FlowRuleEvent removeFlowRule(FlowEntry rule); |
63 | - | ||
64 | } | 71 | } | ... | ... |
... | @@ -3,6 +3,8 @@ package org.onlab.onos.net.flow.instructions; | ... | @@ -3,6 +3,8 @@ package org.onlab.onos.net.flow.instructions; |
3 | import static com.google.common.base.MoreObjects.toStringHelper; | 3 | import static com.google.common.base.MoreObjects.toStringHelper; |
4 | import static com.google.common.base.Preconditions.checkNotNull; | 4 | import static com.google.common.base.Preconditions.checkNotNull; |
5 | 5 | ||
6 | +import java.util.Objects; | ||
7 | + | ||
6 | import org.onlab.onos.net.PortNumber; | 8 | import org.onlab.onos.net.PortNumber; |
7 | import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType; | 9 | import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType; |
8 | import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; | 10 | import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; |
... | @@ -117,6 +119,24 @@ public final class Instructions { | ... | @@ -117,6 +119,24 @@ public final class Instructions { |
117 | return toStringHelper(type()).toString(); | 119 | return toStringHelper(type()).toString(); |
118 | 120 | ||
119 | } | 121 | } |
122 | + | ||
123 | + @Override | ||
124 | + public int hashCode() { | ||
125 | + return Objects.hash(type()); | ||
126 | + } | ||
127 | + | ||
128 | + @Override | ||
129 | + public boolean equals(Object obj) { | ||
130 | + if (this == obj) { | ||
131 | + return true; | ||
132 | + } | ||
133 | + if (obj instanceof DropInstruction) { | ||
134 | + DropInstruction that = (DropInstruction) obj; | ||
135 | + return Objects.equals(type(), that.type()); | ||
136 | + | ||
137 | + } | ||
138 | + return false; | ||
139 | + } | ||
120 | } | 140 | } |
121 | 141 | ||
122 | 142 | ||
... | @@ -140,6 +160,26 @@ public final class Instructions { | ... | @@ -140,6 +160,26 @@ public final class Instructions { |
140 | return toStringHelper(type().toString()) | 160 | return toStringHelper(type().toString()) |
141 | .add("port", port).toString(); | 161 | .add("port", port).toString(); |
142 | } | 162 | } |
163 | + | ||
164 | + @Override | ||
165 | + public int hashCode() { | ||
166 | + return Objects.hash(port, type()); | ||
167 | + } | ||
168 | + | ||
169 | + @Override | ||
170 | + public boolean equals(Object obj) { | ||
171 | + if (this == obj) { | ||
172 | + return true; | ||
173 | + } | ||
174 | + if (obj instanceof OutputInstruction) { | ||
175 | + OutputInstruction that = (OutputInstruction) obj; | ||
176 | + Objects.equals(port, that.port); | ||
177 | + | ||
178 | + } | ||
179 | + return false; | ||
180 | + } | ||
143 | } | 181 | } |
144 | 182 | ||
145 | } | 183 | } |
184 | + | ||
185 | + | ... | ... |
... | @@ -2,6 +2,8 @@ package org.onlab.onos.net.flow.instructions; | ... | @@ -2,6 +2,8 @@ package org.onlab.onos.net.flow.instructions; |
2 | 2 | ||
3 | import static com.google.common.base.MoreObjects.toStringHelper; | 3 | import static com.google.common.base.MoreObjects.toStringHelper; |
4 | 4 | ||
5 | +import java.util.Objects; | ||
6 | + | ||
5 | import org.onlab.packet.MacAddress; | 7 | import org.onlab.packet.MacAddress; |
6 | import org.onlab.packet.VlanId; | 8 | import org.onlab.packet.VlanId; |
7 | 9 | ||
... | @@ -74,6 +76,25 @@ public abstract class L2ModificationInstruction implements Instruction { | ... | @@ -74,6 +76,25 @@ public abstract class L2ModificationInstruction implements Instruction { |
74 | .add("mac", mac).toString(); | 76 | .add("mac", mac).toString(); |
75 | } | 77 | } |
76 | 78 | ||
79 | + @Override | ||
80 | + public int hashCode() { | ||
81 | + return Objects.hash(mac, subtype); | ||
82 | + } | ||
83 | + | ||
84 | + @Override | ||
85 | + public boolean equals(Object obj) { | ||
86 | + if (this == obj) { | ||
87 | + return true; | ||
88 | + } | ||
89 | + if (obj instanceof ModEtherInstruction) { | ||
90 | + ModEtherInstruction that = (ModEtherInstruction) obj; | ||
91 | + return Objects.equals(mac, that.mac) && | ||
92 | + Objects.equals(subtype, that.subtype); | ||
93 | + | ||
94 | + } | ||
95 | + return false; | ||
96 | + } | ||
97 | + | ||
77 | 98 | ||
78 | } | 99 | } |
79 | 100 | ||
... | @@ -103,6 +124,25 @@ public abstract class L2ModificationInstruction implements Instruction { | ... | @@ -103,6 +124,25 @@ public abstract class L2ModificationInstruction implements Instruction { |
103 | .add("id", vlanId).toString(); | 124 | .add("id", vlanId).toString(); |
104 | } | 125 | } |
105 | 126 | ||
127 | + @Override | ||
128 | + public int hashCode() { | ||
129 | + return Objects.hash(vlanId, subtype()); | ||
130 | + } | ||
131 | + | ||
132 | + @Override | ||
133 | + public boolean equals(Object obj) { | ||
134 | + if (this == obj) { | ||
135 | + return true; | ||
136 | + } | ||
137 | + if (obj instanceof ModVlanIdInstruction) { | ||
138 | + ModVlanIdInstruction that = (ModVlanIdInstruction) obj; | ||
139 | + return Objects.equals(vlanId, that.vlanId); | ||
140 | + | ||
141 | + } | ||
142 | + return false; | ||
143 | + } | ||
144 | + | ||
145 | + | ||
106 | } | 146 | } |
107 | 147 | ||
108 | /** | 148 | /** |
... | @@ -131,6 +171,24 @@ public abstract class L2ModificationInstruction implements Instruction { | ... | @@ -131,6 +171,24 @@ public abstract class L2ModificationInstruction implements Instruction { |
131 | .add("pcp", Long.toHexString(vlanPcp)).toString(); | 171 | .add("pcp", Long.toHexString(vlanPcp)).toString(); |
132 | } | 172 | } |
133 | 173 | ||
174 | + @Override | ||
175 | + public int hashCode() { | ||
176 | + return Objects.hash(vlanPcp, subtype()); | ||
177 | + } | ||
178 | + | ||
179 | + @Override | ||
180 | + public boolean equals(Object obj) { | ||
181 | + if (this == obj) { | ||
182 | + return true; | ||
183 | + } | ||
184 | + if (obj instanceof ModVlanPcpInstruction) { | ||
185 | + ModVlanPcpInstruction that = (ModVlanPcpInstruction) obj; | ||
186 | + return Objects.equals(vlanPcp, that.vlanPcp); | ||
187 | + | ||
188 | + } | ||
189 | + return false; | ||
190 | + } | ||
191 | + | ||
134 | } | 192 | } |
135 | 193 | ||
136 | 194 | ... | ... |
... | @@ -2,6 +2,8 @@ package org.onlab.onos.net.flow.instructions; | ... | @@ -2,6 +2,8 @@ package org.onlab.onos.net.flow.instructions; |
2 | 2 | ||
3 | import static com.google.common.base.MoreObjects.toStringHelper; | 3 | import static com.google.common.base.MoreObjects.toStringHelper; |
4 | 4 | ||
5 | +import java.util.Objects; | ||
6 | + | ||
5 | import org.onlab.packet.IpPrefix; | 7 | import org.onlab.packet.IpPrefix; |
6 | 8 | ||
7 | /** | 9 | /** |
... | @@ -66,5 +68,23 @@ public abstract class L3ModificationInstruction implements Instruction { | ... | @@ -66,5 +68,23 @@ public abstract class L3ModificationInstruction implements Instruction { |
66 | .add("ip", ip).toString(); | 68 | .add("ip", ip).toString(); |
67 | } | 69 | } |
68 | 70 | ||
71 | + @Override | ||
72 | + public int hashCode() { | ||
73 | + return Objects.hash(ip, subtype()); | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public boolean equals(Object obj) { | ||
78 | + if (this == obj) { | ||
79 | + return true; | ||
80 | + } | ||
81 | + if (obj instanceof ModIPInstruction) { | ||
82 | + ModIPInstruction that = (ModIPInstruction) obj; | ||
83 | + return Objects.equals(ip, that.ip); | ||
84 | + | ||
85 | + } | ||
86 | + return false; | ||
87 | + } | ||
88 | + | ||
69 | } | 89 | } |
70 | } | 90 | } | ... | ... |
... | @@ -24,7 +24,7 @@ public abstract class AbstractIntent implements Intent { | ... | @@ -24,7 +24,7 @@ public abstract class AbstractIntent implements Intent { |
24 | } | 24 | } |
25 | 25 | ||
26 | @Override | 26 | @Override |
27 | - public IntentId getId() { | 27 | + public IntentId id() { |
28 | return id; | 28 | return id; |
29 | } | 29 | } |
30 | 30 | ... | ... |
... | @@ -53,7 +53,7 @@ public abstract class ConnectivityIntent extends AbstractIntent { | ... | @@ -53,7 +53,7 @@ public abstract class ConnectivityIntent extends AbstractIntent { |
53 | * | 53 | * |
54 | * @return traffic match | 54 | * @return traffic match |
55 | */ | 55 | */ |
56 | - public TrafficSelector getTrafficSelector() { | 56 | + public TrafficSelector selector() { |
57 | return selector; | 57 | return selector; |
58 | } | 58 | } |
59 | 59 | ||
... | @@ -62,7 +62,7 @@ public abstract class ConnectivityIntent extends AbstractIntent { | ... | @@ -62,7 +62,7 @@ public abstract class ConnectivityIntent extends AbstractIntent { |
62 | * | 62 | * |
63 | * @return applied action | 63 | * @return applied action |
64 | */ | 64 | */ |
65 | - public TrafficTreatment getTrafficTreatment() { | 65 | + public TrafficTreatment treatment() { |
66 | return treatment; | 66 | return treatment; |
67 | } | 67 | } |
68 | 68 | ... | ... |
... | @@ -80,9 +80,9 @@ public class HostToHostIntent extends ConnectivityIntent { | ... | @@ -80,9 +80,9 @@ public class HostToHostIntent extends ConnectivityIntent { |
80 | @Override | 80 | @Override |
81 | public String toString() { | 81 | public String toString() { |
82 | return MoreObjects.toStringHelper(getClass()) | 82 | return MoreObjects.toStringHelper(getClass()) |
83 | - .add("id", getId()) | 83 | + .add("id", id()) |
84 | - .add("selector", getTrafficSelector()) | 84 | + .add("selector", selector()) |
85 | - .add("treatment", getTrafficTreatment()) | 85 | + .add("treatment", treatment()) |
86 | .add("one", one) | 86 | .add("one", one) |
87 | .add("two", two) | 87 | .add("two", two) |
88 | .toString(); | 88 | .toString(); | ... | ... |
1 | package org.onlab.onos.net.intent; | 1 | package org.onlab.onos.net.intent; |
2 | 2 | ||
3 | -import com.google.common.base.MoreObjects; | ||
4 | import org.onlab.onos.event.AbstractEvent; | 3 | import org.onlab.onos.event.AbstractEvent; |
5 | 4 | ||
6 | -import java.util.Objects; | ||
7 | - | ||
8 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
9 | - | ||
10 | /** | 5 | /** |
11 | * A class to represent an intent related event. | 6 | * A class to represent an intent related event. |
12 | */ | 7 | */ |
13 | -public class IntentEvent extends AbstractEvent<IntentState, Intent> { | 8 | +public class IntentEvent extends AbstractEvent<IntentEvent.Type, Intent> { |
14 | - | ||
15 | - // TODO: determine a suitable parent class; if one does not exist, consider | ||
16 | - // introducing one | ||
17 | 9 | ||
18 | - private final long time; | 10 | + public enum Type { |
19 | - private final Intent intent; | 11 | + /** |
20 | - private final IntentState state; | 12 | + * Signifies that a new intent has been submitted to the system. |
21 | - private final IntentState previous; | 13 | + */ |
14 | + SUBMITTED, | ||
22 | 15 | ||
23 | - /** | 16 | + /** |
24 | - * Creates an event describing a state change of an intent. | 17 | + * Signifies that an intent has been successfully installed. |
25 | - * | 18 | + */ |
26 | - * @param intent subject intent | 19 | + INSTALLED, |
27 | - * @param state new intent state | ||
28 | - * @param previous previous intent state | ||
29 | - * @param time time the event created in milliseconds since start of epoch | ||
30 | - * @throws NullPointerException if the intent or state is null | ||
31 | - */ | ||
32 | - public IntentEvent(Intent intent, IntentState state, IntentState previous, long time) { | ||
33 | - super(state, intent); | ||
34 | - this.intent = checkNotNull(intent); | ||
35 | - this.state = checkNotNull(state); | ||
36 | - this.previous = previous; | ||
37 | - this.time = time; | ||
38 | - } | ||
39 | 20 | ||
40 | - /** | 21 | + /** |
41 | - * Returns the state of the intent which caused the event. | 22 | + * Signifies that an intent has failed compilation or installation. |
42 | - * | 23 | + */ |
43 | - * @return the state of the intent | 24 | + FAILED, |
44 | - */ | ||
45 | - public IntentState getState() { | ||
46 | - return state; | ||
47 | - } | ||
48 | 25 | ||
49 | - /** | 26 | + /** |
50 | - * Returns the previous state of the intent which caused the event. | 27 | + * Signifies that an intent has been withdrawn from the system. |
51 | - * | 28 | + */ |
52 | - * @return the previous state of the intent | 29 | + WITHDRAWN |
53 | - */ | ||
54 | - public IntentState getPreviousState() { | ||
55 | - return previous; | ||
56 | } | 30 | } |
57 | 31 | ||
58 | /** | 32 | /** |
59 | - * Returns the intent associated with the event. | 33 | + * Creates an event of a given type and for the specified intent and the |
34 | + * current time. | ||
60 | * | 35 | * |
61 | - * @return the intent | 36 | + * @param type event type |
37 | + * @param intent subject intent | ||
38 | + * @param time time the event created in milliseconds since start of epoch | ||
62 | */ | 39 | */ |
63 | - public Intent getIntent() { | 40 | + public IntentEvent(Type type, Intent intent, long time) { |
64 | - return intent; | 41 | + super(type, intent, time); |
65 | } | 42 | } |
66 | 43 | ||
67 | /** | 44 | /** |
68 | - * Returns the time at which the event was created. | 45 | + * Creates an event of a given type and for the specified intent and the |
46 | + * current time. | ||
69 | * | 47 | * |
70 | - * @return the time in milliseconds since start of epoch | 48 | + * @param type event type |
49 | + * @param intent subject intent | ||
71 | */ | 50 | */ |
72 | - public long getTime() { | 51 | + public IntentEvent(Type type, Intent intent) { |
73 | - return time; | 52 | + super(type, intent); |
74 | - } | ||
75 | - | ||
76 | - @Override | ||
77 | - public boolean equals(Object o) { | ||
78 | - if (this == o) { | ||
79 | - return true; | ||
80 | - } | ||
81 | - if (o == null || getClass() != o.getClass()) { | ||
82 | - return false; | ||
83 | - } | ||
84 | - | ||
85 | - IntentEvent that = (IntentEvent) o; | ||
86 | - return Objects.equals(this.intent, that.intent) | ||
87 | - && Objects.equals(this.state, that.state) | ||
88 | - && Objects.equals(this.previous, that.previous) | ||
89 | - && Objects.equals(this.time, that.time); | ||
90 | } | 53 | } |
91 | 54 | ||
92 | - @Override | ||
93 | - public int hashCode() { | ||
94 | - return Objects.hash(intent, state, previous, time); | ||
95 | - } | ||
96 | - | ||
97 | - @Override | ||
98 | - public String toString() { | ||
99 | - return MoreObjects.toStringHelper(getClass()) | ||
100 | - .add("intent", intent) | ||
101 | - .add("state", state) | ||
102 | - .add("previous", previous) | ||
103 | - .add("time", time) | ||
104 | - .toString(); | ||
105 | - } | ||
106 | } | 55 | } | ... | ... |
1 | package org.onlab.onos.net.intent; | 1 | package org.onlab.onos.net.intent; |
2 | 2 | ||
3 | /** | 3 | /** |
4 | - * This class represents the states of an intent. | 4 | + * Representation of the phases an intent may attain during its lifecycle. |
5 | - * | ||
6 | - * <p> | ||
7 | - * Note: The state is expressed as enum, but there is possibility | ||
8 | - * in the future that we define specific class instead of enum to improve | ||
9 | - * the extensibility of state definition. | ||
10 | - * </p> | ||
11 | */ | 5 | */ |
12 | public enum IntentState { | 6 | public enum IntentState { |
13 | - // FIXME: requires discussion on State vs. EventType and a solid state-transition diagram | 7 | + |
14 | - // TODO: consider the impact of conflict detection | ||
15 | - // TODO: consider the impact that external events affect an installed intent | ||
16 | /** | 8 | /** |
17 | - * The beginning state. | 9 | + * Signifies that the intent has been submitted and will start compiling |
18 | - * | 10 | + * shortly. However, this compilation may not necessarily occur on the |
11 | + * local controller instance. | ||
12 | + * <p/> | ||
19 | * All intent in the runtime take this state first. | 13 | * All intent in the runtime take this state first. |
20 | */ | 14 | */ |
21 | SUBMITTED, | 15 | SUBMITTED, |
22 | 16 | ||
23 | /** | 17 | /** |
24 | - * The intent compilation has been completed. | 18 | + * Signifies that the intent is being compiled into installable intents. |
25 | - * | 19 | + * This is a transitional state after which the intent will enter either |
26 | - * An intent translation graph (tree) is completely created. | 20 | + * {@link #FAILED} state or {@link #INSTALLING} state. |
27 | - * Leaves of the graph are installable intent type. | 21 | + */ |
22 | + COMPILING, | ||
23 | + | ||
24 | + /** | ||
25 | + * Signifies that the resulting installable intents are being installed | ||
26 | + * into the network environment. This is a transitional state after which | ||
27 | + * the intent will enter either {@link #INSTALLED} state or | ||
28 | + * {@link #RECOMPILING} state. | ||
28 | */ | 29 | */ |
29 | - COMPILED, | 30 | + INSTALLING, |
30 | 31 | ||
31 | /** | 32 | /** |
32 | - * The intent has been successfully installed. | 33 | + * The intent has been successfully installed. This is a state where the |
34 | + * intent may remain parked until it is withdrawn by the application or | ||
35 | + * until the network environment changes in some way to make the original | ||
36 | + * set of installable intents untenable. | ||
33 | */ | 37 | */ |
34 | INSTALLED, | 38 | INSTALLED, |
35 | 39 | ||
36 | /** | 40 | /** |
37 | - * The intent is being withdrawn. | 41 | + * Signifies that the intent is being recompiled into installable intents |
38 | - * | 42 | + * as an attempt to adapt to an anomaly in the network environment. |
39 | - * When {@link IntentService#withdraw(Intent)} is called, | 43 | + * This is a transitional state after which the intent will enter either |
40 | - * the intent takes this state first. | 44 | + * {@link #FAILED} state or {@link #INSTALLING} state. |
45 | + * <p/> | ||
46 | + * Exit to the {@link #FAILED} state may be caused by failure to compile | ||
47 | + * or by compiling into the same set of installable intents which have | ||
48 | + * previously failed to be installed. | ||
49 | + */ | ||
50 | + RECOMPILING, | ||
51 | + | ||
52 | + /** | ||
53 | + * Indicates that the intent is being withdrawn. This is a transitional | ||
54 | + * state, triggered by invocation of the | ||
55 | + * {@link IntentService#withdraw(Intent)} but one with only one outcome, | ||
56 | + * which is the the intent being placed in the {@link #WITHDRAWN} state. | ||
41 | */ | 57 | */ |
42 | WITHDRAWING, | 58 | WITHDRAWING, |
43 | 59 | ||
44 | /** | 60 | /** |
45 | - * The intent has been successfully withdrawn. | 61 | + * Indicates that the intent has been successfully withdrawn. |
46 | */ | 62 | */ |
47 | WITHDRAWN, | 63 | WITHDRAWN, |
48 | 64 | ||
49 | /** | 65 | /** |
50 | - * The intent has failed to be compiled, installed, or withdrawn. | 66 | + * Signifies that the intent has failed compiling, installing or |
51 | - * | 67 | + * recompiling states. |
52 | - * When the intent failed to be withdrawn, it is still, at least partially installed. | ||
53 | */ | 68 | */ |
54 | - FAILED, | 69 | + FAILED |
55 | } | 70 | } | ... | ... |
... | @@ -10,10 +10,16 @@ import java.util.List; | ... | @@ -10,10 +10,16 @@ import java.util.List; |
10 | public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { | 10 | public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { |
11 | 11 | ||
12 | /** | 12 | /** |
13 | - * Creates a new intent. | 13 | + * Submits a new intent into the store. If the returned event is not |
14 | + * null, the manager is expected to dispatch the event and then to kick | ||
15 | + * off intent compilation process. Otherwise, another node has been elected | ||
16 | + * to perform the compilation process and the node will learn about | ||
17 | + * the submittal and results of the intent compilation via the delegate | ||
18 | + * mechanism. | ||
14 | * | 19 | * |
15 | - * @param intent intent | 20 | + * @param intent intent to be submitted |
16 | - * @return appropriate event or null if no change resulted | 21 | + * @return event indicating the intent was submitted or null if no |
22 | + * change resulted, e.g. duplicate intent | ||
17 | */ | 23 | */ |
18 | IntentEvent createIntent(Intent intent); | 24 | IntentEvent createIntent(Intent intent); |
19 | 25 | ||
... | @@ -68,10 +74,9 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { | ... | @@ -68,10 +74,9 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { |
68 | * | 74 | * |
69 | * @param intentId original intent identifier | 75 | * @param intentId original intent identifier |
70 | * @param installableIntents compiled installable intents | 76 | * @param installableIntents compiled installable intents |
71 | - * @return compiled state transition event | ||
72 | */ | 77 | */ |
73 | - IntentEvent addInstallableIntents(IntentId intentId, | 78 | + void addInstallableIntents(IntentId intentId, |
74 | - List<InstallableIntent> installableIntents); | 79 | + List<InstallableIntent> installableIntents); |
75 | 80 | ||
76 | /** | 81 | /** |
77 | * Returns the list of the installable events associated with the specified | 82 | * Returns the list of the installable events associated with the specified | ... | ... |
1 | package org.onlab.onos.net.intent; | 1 | package org.onlab.onos.net.intent; |
2 | 2 | ||
3 | -import static com.google.common.base.Preconditions.checkArgument; | 3 | +import com.google.common.base.MoreObjects; |
4 | -import static com.google.common.base.Preconditions.checkNotNull; | 4 | +import com.google.common.collect.Sets; |
5 | - | ||
6 | -import java.util.Objects; | ||
7 | -import java.util.Set; | ||
8 | - | ||
9 | import org.onlab.onos.net.ConnectPoint; | 5 | import org.onlab.onos.net.ConnectPoint; |
10 | import org.onlab.onos.net.flow.TrafficSelector; | 6 | import org.onlab.onos.net.flow.TrafficSelector; |
11 | import org.onlab.onos.net.flow.TrafficTreatment; | 7 | import org.onlab.onos.net.flow.TrafficTreatment; |
12 | 8 | ||
13 | -import com.google.common.base.MoreObjects; | 9 | +import java.util.Objects; |
14 | -import com.google.common.collect.Sets; | 10 | +import java.util.Set; |
11 | + | ||
12 | +import static com.google.common.base.Preconditions.checkArgument; | ||
13 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
15 | 14 | ||
16 | /** | 15 | /** |
17 | * Abstraction of multiple source to single destination connectivity intent. | 16 | * Abstraction of multiple source to single destination connectivity intent. |
18 | */ | 17 | */ |
19 | public class MultiPointToSinglePointIntent extends ConnectivityIntent { | 18 | public class MultiPointToSinglePointIntent extends ConnectivityIntent { |
20 | 19 | ||
21 | - private final Set<ConnectPoint> ingressPorts; | 20 | + private final Set<ConnectPoint> ingressPoints; |
22 | - private final ConnectPoint egressPort; | 21 | + private final ConnectPoint egressPoint; |
23 | 22 | ||
24 | /** | 23 | /** |
25 | * Creates a new multi-to-single point connectivity intent for the specified | 24 | * Creates a new multi-to-single point connectivity intent for the specified |
... | @@ -28,25 +27,25 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { | ... | @@ -28,25 +27,25 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { |
28 | * @param id intent identifier | 27 | * @param id intent identifier |
29 | * @param match traffic match | 28 | * @param match traffic match |
30 | * @param action action | 29 | * @param action action |
31 | - * @param ingressPorts set of ports from which ingress traffic originates | 30 | + * @param ingressPoints set of ports from which ingress traffic originates |
32 | - * @param egressPort port to which traffic will egress | 31 | + * @param egressPoint port to which traffic will egress |
33 | - * @throws NullPointerException if {@code ingressPorts} or | 32 | + * @throws NullPointerException if {@code ingressPoints} or |
34 | - * {@code egressPort} is null. | 33 | + * {@code egressPoint} is null. |
35 | - * @throws IllegalArgumentException if the size of {@code ingressPorts} is | 34 | + * @throws IllegalArgumentException if the size of {@code ingressPoints} is |
36 | * not more than 1 | 35 | * not more than 1 |
37 | */ | 36 | */ |
38 | public MultiPointToSinglePointIntent(IntentId id, TrafficSelector match, | 37 | public MultiPointToSinglePointIntent(IntentId id, TrafficSelector match, |
39 | TrafficTreatment action, | 38 | TrafficTreatment action, |
40 | - Set<ConnectPoint> ingressPorts, | 39 | + Set<ConnectPoint> ingressPoints, |
41 | - ConnectPoint egressPort) { | 40 | + ConnectPoint egressPoint) { |
42 | super(id, match, action); | 41 | super(id, match, action); |
43 | 42 | ||
44 | - checkNotNull(ingressPorts); | 43 | + checkNotNull(ingressPoints); |
45 | - checkArgument(!ingressPorts.isEmpty(), | 44 | + checkArgument(!ingressPoints.isEmpty(), |
46 | "there should be at least one ingress port"); | 45 | "there should be at least one ingress port"); |
47 | 46 | ||
48 | - this.ingressPorts = Sets.newHashSet(ingressPorts); | 47 | + this.ingressPoints = Sets.newHashSet(ingressPoints); |
49 | - this.egressPort = checkNotNull(egressPort); | 48 | + this.egressPoint = checkNotNull(egressPoint); |
50 | } | 49 | } |
51 | 50 | ||
52 | /** | 51 | /** |
... | @@ -54,8 +53,8 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { | ... | @@ -54,8 +53,8 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { |
54 | */ | 53 | */ |
55 | protected MultiPointToSinglePointIntent() { | 54 | protected MultiPointToSinglePointIntent() { |
56 | super(); | 55 | super(); |
57 | - this.ingressPorts = null; | 56 | + this.ingressPoints = null; |
58 | - this.egressPort = null; | 57 | + this.egressPoint = null; |
59 | } | 58 | } |
60 | 59 | ||
61 | /** | 60 | /** |
... | @@ -64,8 +63,8 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { | ... | @@ -64,8 +63,8 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { |
64 | * | 63 | * |
65 | * @return set of ingress ports | 64 | * @return set of ingress ports |
66 | */ | 65 | */ |
67 | - public Set<ConnectPoint> getIngressPorts() { | 66 | + public Set<ConnectPoint> ingressPoints() { |
68 | - return ingressPorts; | 67 | + return ingressPoints; |
69 | } | 68 | } |
70 | 69 | ||
71 | /** | 70 | /** |
... | @@ -73,8 +72,8 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { | ... | @@ -73,8 +72,8 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { |
73 | * | 72 | * |
74 | * @return egress port | 73 | * @return egress port |
75 | */ | 74 | */ |
76 | - public ConnectPoint getEgressPort() { | 75 | + public ConnectPoint egressPoint() { |
77 | - return egressPort; | 76 | + return egressPoint; |
78 | } | 77 | } |
79 | 78 | ||
80 | @Override | 79 | @Override |
... | @@ -90,23 +89,23 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { | ... | @@ -90,23 +89,23 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent { |
90 | } | 89 | } |
91 | 90 | ||
92 | MultiPointToSinglePointIntent that = (MultiPointToSinglePointIntent) o; | 91 | MultiPointToSinglePointIntent that = (MultiPointToSinglePointIntent) o; |
93 | - return Objects.equals(this.ingressPorts, that.ingressPorts) | 92 | + return Objects.equals(this.ingressPoints, that.ingressPoints) |
94 | - && Objects.equals(this.egressPort, that.egressPort); | 93 | + && Objects.equals(this.egressPoint, that.egressPoint); |
95 | } | 94 | } |
96 | 95 | ||
97 | @Override | 96 | @Override |
98 | public int hashCode() { | 97 | public int hashCode() { |
99 | - return Objects.hash(super.hashCode(), ingressPorts, egressPort); | 98 | + return Objects.hash(super.hashCode(), ingressPoints, egressPoint); |
100 | } | 99 | } |
101 | 100 | ||
102 | @Override | 101 | @Override |
103 | public String toString() { | 102 | public String toString() { |
104 | return MoreObjects.toStringHelper(getClass()) | 103 | return MoreObjects.toStringHelper(getClass()) |
105 | - .add("id", getId()) | 104 | + .add("id", id()) |
106 | - .add("match", getTrafficSelector()) | 105 | + .add("match", selector()) |
107 | - .add("action", getTrafficTreatment()) | 106 | + .add("action", treatment()) |
108 | - .add("ingressPorts", getIngressPorts()) | 107 | + .add("ingressPoints", ingressPoints()) |
109 | - .add("egressPort", getEgressPort()) | 108 | + .add("egressPoint", egressPoint()) |
110 | .toString(); | 109 | .toString(); |
111 | } | 110 | } |
112 | } | 111 | } | ... | ... |
... | @@ -46,7 +46,7 @@ public class PathIntent extends PointToPointIntent implements InstallableIntent | ... | @@ -46,7 +46,7 @@ public class PathIntent extends PointToPointIntent implements InstallableIntent |
46 | * | 46 | * |
47 | * @return traversed links | 47 | * @return traversed links |
48 | */ | 48 | */ |
49 | - public Path getPath() { | 49 | + public Path path() { |
50 | return path; | 50 | return path; |
51 | } | 51 | } |
52 | 52 | ||
... | @@ -79,11 +79,11 @@ public class PathIntent extends PointToPointIntent implements InstallableIntent | ... | @@ -79,11 +79,11 @@ public class PathIntent extends PointToPointIntent implements InstallableIntent |
79 | @Override | 79 | @Override |
80 | public String toString() { | 80 | public String toString() { |
81 | return MoreObjects.toStringHelper(getClass()) | 81 | return MoreObjects.toStringHelper(getClass()) |
82 | - .add("id", getId()) | 82 | + .add("id", id()) |
83 | - .add("match", getTrafficSelector()) | 83 | + .add("match", selector()) |
84 | - .add("action", getTrafficTreatment()) | 84 | + .add("action", treatment()) |
85 | - .add("ingressPort", getIngressPort()) | 85 | + .add("ingressPort", ingressPoint()) |
86 | - .add("egressPort", getEgressPort()) | 86 | + .add("egressPort", egressPoint()) |
87 | .add("path", path) | 87 | .add("path", path) |
88 | .toString(); | 88 | .toString(); |
89 | } | 89 | } | ... | ... |
... | @@ -14,27 +14,27 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -14,27 +14,27 @@ import static com.google.common.base.Preconditions.checkNotNull; |
14 | */ | 14 | */ |
15 | public class PointToPointIntent extends ConnectivityIntent { | 15 | public class PointToPointIntent extends ConnectivityIntent { |
16 | 16 | ||
17 | - private final ConnectPoint ingressPort; | 17 | + private final ConnectPoint ingressPoint; |
18 | - private final ConnectPoint egressPort; | 18 | + private final ConnectPoint egressPoint; |
19 | 19 | ||
20 | /** | 20 | /** |
21 | * Creates a new point-to-point intent with the supplied ingress/egress | 21 | * Creates a new point-to-point intent with the supplied ingress/egress |
22 | * ports. | 22 | * ports. |
23 | * | 23 | * |
24 | - * @param id intent identifier | 24 | + * @param id intent identifier |
25 | - * @param selector traffic selector | 25 | + * @param selector traffic selector |
26 | - * @param treatment treatment | 26 | + * @param treatment treatment |
27 | - * @param ingressPort ingress port | 27 | + * @param ingressPoint ingress port |
28 | - * @param egressPort egress port | 28 | + * @param egressPoint egress port |
29 | - * @throws NullPointerException if {@code ingressPort} or {@code egressPort} is null. | 29 | + * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null. |
30 | */ | 30 | */ |
31 | public PointToPointIntent(IntentId id, TrafficSelector selector, | 31 | public PointToPointIntent(IntentId id, TrafficSelector selector, |
32 | TrafficTreatment treatment, | 32 | TrafficTreatment treatment, |
33 | - ConnectPoint ingressPort, | 33 | + ConnectPoint ingressPoint, |
34 | - ConnectPoint egressPort) { | 34 | + ConnectPoint egressPoint) { |
35 | super(id, selector, treatment); | 35 | super(id, selector, treatment); |
36 | - this.ingressPort = checkNotNull(ingressPort); | 36 | + this.ingressPoint = checkNotNull(ingressPoint); |
37 | - this.egressPort = checkNotNull(egressPort); | 37 | + this.egressPoint = checkNotNull(egressPoint); |
38 | } | 38 | } |
39 | 39 | ||
40 | /** | 40 | /** |
... | @@ -42,8 +42,8 @@ public class PointToPointIntent extends ConnectivityIntent { | ... | @@ -42,8 +42,8 @@ public class PointToPointIntent extends ConnectivityIntent { |
42 | */ | 42 | */ |
43 | protected PointToPointIntent() { | 43 | protected PointToPointIntent() { |
44 | super(); | 44 | super(); |
45 | - this.ingressPort = null; | 45 | + this.ingressPoint = null; |
46 | - this.egressPort = null; | 46 | + this.egressPoint = null; |
47 | } | 47 | } |
48 | 48 | ||
49 | /** | 49 | /** |
... | @@ -52,8 +52,8 @@ public class PointToPointIntent extends ConnectivityIntent { | ... | @@ -52,8 +52,8 @@ public class PointToPointIntent extends ConnectivityIntent { |
52 | * | 52 | * |
53 | * @return ingress port | 53 | * @return ingress port |
54 | */ | 54 | */ |
55 | - public ConnectPoint getIngressPort() { | 55 | + public ConnectPoint ingressPoint() { |
56 | - return ingressPort; | 56 | + return ingressPoint; |
57 | } | 57 | } |
58 | 58 | ||
59 | /** | 59 | /** |
... | @@ -61,8 +61,8 @@ public class PointToPointIntent extends ConnectivityIntent { | ... | @@ -61,8 +61,8 @@ public class PointToPointIntent extends ConnectivityIntent { |
61 | * | 61 | * |
62 | * @return egress port | 62 | * @return egress port |
63 | */ | 63 | */ |
64 | - public ConnectPoint getEgressPort() { | 64 | + public ConnectPoint egressPoint() { |
65 | - return egressPort; | 65 | + return egressPoint; |
66 | } | 66 | } |
67 | 67 | ||
68 | @Override | 68 | @Override |
... | @@ -78,23 +78,23 @@ public class PointToPointIntent extends ConnectivityIntent { | ... | @@ -78,23 +78,23 @@ public class PointToPointIntent extends ConnectivityIntent { |
78 | } | 78 | } |
79 | 79 | ||
80 | PointToPointIntent that = (PointToPointIntent) o; | 80 | PointToPointIntent that = (PointToPointIntent) o; |
81 | - return Objects.equals(this.ingressPort, that.ingressPort) | 81 | + return Objects.equals(this.ingressPoint, that.ingressPoint) |
82 | - && Objects.equals(this.egressPort, that.egressPort); | 82 | + && Objects.equals(this.egressPoint, that.egressPoint); |
83 | } | 83 | } |
84 | 84 | ||
85 | @Override | 85 | @Override |
86 | public int hashCode() { | 86 | public int hashCode() { |
87 | - return Objects.hash(super.hashCode(), ingressPort, egressPort); | 87 | + return Objects.hash(super.hashCode(), ingressPoint, egressPoint); |
88 | } | 88 | } |
89 | 89 | ||
90 | @Override | 90 | @Override |
91 | public String toString() { | 91 | public String toString() { |
92 | return MoreObjects.toStringHelper(getClass()) | 92 | return MoreObjects.toStringHelper(getClass()) |
93 | - .add("id", getId()) | 93 | + .add("id", id()) |
94 | - .add("match", getTrafficSelector()) | 94 | + .add("match", selector()) |
95 | - .add("action", getTrafficTreatment()) | 95 | + .add("action", treatment()) |
96 | - .add("ingressPort", ingressPort) | 96 | + .add("ingressPoint", ingressPoint) |
97 | - .add("egressPort", egressPort) | 97 | + .add("egressPoints", egressPoint) |
98 | .toString(); | 98 | .toString(); |
99 | } | 99 | } |
100 | 100 | ... | ... |
... | @@ -17,34 +17,34 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -17,34 +17,34 @@ import static com.google.common.base.Preconditions.checkNotNull; |
17 | */ | 17 | */ |
18 | public class SinglePointToMultiPointIntent extends ConnectivityIntent { | 18 | public class SinglePointToMultiPointIntent extends ConnectivityIntent { |
19 | 19 | ||
20 | - private final ConnectPoint ingressPort; | 20 | + private final ConnectPoint ingressPoint; |
21 | - private final Set<ConnectPoint> egressPorts; | 21 | + private final Set<ConnectPoint> egressPoints; |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * Creates a new single-to-multi point connectivity intent. | 24 | * Creates a new single-to-multi point connectivity intent. |
25 | * | 25 | * |
26 | - * @param id intent identifier | 26 | + * @param id intent identifier |
27 | - * @param selector traffic selector | 27 | + * @param selector traffic selector |
28 | - * @param treatment treatment | 28 | + * @param treatment treatment |
29 | - * @param ingressPort port on which traffic will ingress | 29 | + * @param ingressPoint port on which traffic will ingress |
30 | - * @param egressPorts set of ports on which traffic will egress | 30 | + * @param egressPoints set of ports on which traffic will egress |
31 | - * @throws NullPointerException if {@code ingressPort} or | 31 | + * @throws NullPointerException if {@code ingressPoint} or |
32 | - * {@code egressPorts} is null | 32 | + * {@code egressPoints} is null |
33 | - * @throws IllegalArgumentException if the size of {@code egressPorts} is | 33 | + * @throws IllegalArgumentException if the size of {@code egressPoints} is |
34 | * not more than 1 | 34 | * not more than 1 |
35 | */ | 35 | */ |
36 | public SinglePointToMultiPointIntent(IntentId id, TrafficSelector selector, | 36 | public SinglePointToMultiPointIntent(IntentId id, TrafficSelector selector, |
37 | TrafficTreatment treatment, | 37 | TrafficTreatment treatment, |
38 | - ConnectPoint ingressPort, | 38 | + ConnectPoint ingressPoint, |
39 | - Set<ConnectPoint> egressPorts) { | 39 | + Set<ConnectPoint> egressPoints) { |
40 | super(id, selector, treatment); | 40 | super(id, selector, treatment); |
41 | 41 | ||
42 | - checkNotNull(egressPorts); | 42 | + checkNotNull(egressPoints); |
43 | - checkArgument(!egressPorts.isEmpty(), | 43 | + checkArgument(!egressPoints.isEmpty(), |
44 | "there should be at least one egress port"); | 44 | "there should be at least one egress port"); |
45 | 45 | ||
46 | - this.ingressPort = checkNotNull(ingressPort); | 46 | + this.ingressPoint = checkNotNull(ingressPoint); |
47 | - this.egressPorts = Sets.newHashSet(egressPorts); | 47 | + this.egressPoints = Sets.newHashSet(egressPoints); |
48 | } | 48 | } |
49 | 49 | ||
50 | /** | 50 | /** |
... | @@ -52,8 +52,8 @@ public class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -52,8 +52,8 @@ public class SinglePointToMultiPointIntent extends ConnectivityIntent { |
52 | */ | 52 | */ |
53 | protected SinglePointToMultiPointIntent() { | 53 | protected SinglePointToMultiPointIntent() { |
54 | super(); | 54 | super(); |
55 | - this.ingressPort = null; | 55 | + this.ingressPoint = null; |
56 | - this.egressPorts = null; | 56 | + this.egressPoints = null; |
57 | } | 57 | } |
58 | 58 | ||
59 | /** | 59 | /** |
... | @@ -61,8 +61,8 @@ public class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -61,8 +61,8 @@ public class SinglePointToMultiPointIntent extends ConnectivityIntent { |
61 | * | 61 | * |
62 | * @return ingress port | 62 | * @return ingress port |
63 | */ | 63 | */ |
64 | - public ConnectPoint getIngressPort() { | 64 | + public ConnectPoint ingressPoint() { |
65 | - return ingressPort; | 65 | + return ingressPoint; |
66 | } | 66 | } |
67 | 67 | ||
68 | /** | 68 | /** |
... | @@ -70,8 +70,8 @@ public class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -70,8 +70,8 @@ public class SinglePointToMultiPointIntent extends ConnectivityIntent { |
70 | * | 70 | * |
71 | * @return set of egress ports | 71 | * @return set of egress ports |
72 | */ | 72 | */ |
73 | - public Set<ConnectPoint> getEgressPorts() { | 73 | + public Set<ConnectPoint> egressPoints() { |
74 | - return egressPorts; | 74 | + return egressPoints; |
75 | } | 75 | } |
76 | 76 | ||
77 | @Override | 77 | @Override |
... | @@ -87,23 +87,23 @@ public class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -87,23 +87,23 @@ public class SinglePointToMultiPointIntent extends ConnectivityIntent { |
87 | } | 87 | } |
88 | 88 | ||
89 | SinglePointToMultiPointIntent that = (SinglePointToMultiPointIntent) o; | 89 | SinglePointToMultiPointIntent that = (SinglePointToMultiPointIntent) o; |
90 | - return Objects.equals(this.ingressPort, that.ingressPort) | 90 | + return Objects.equals(this.ingressPoint, that.ingressPoint) |
91 | - && Objects.equals(this.egressPorts, that.egressPorts); | 91 | + && Objects.equals(this.egressPoints, that.egressPoints); |
92 | } | 92 | } |
93 | 93 | ||
94 | @Override | 94 | @Override |
95 | public int hashCode() { | 95 | public int hashCode() { |
96 | - return Objects.hash(super.hashCode(), ingressPort, egressPorts); | 96 | + return Objects.hash(super.hashCode(), ingressPoint, egressPoints); |
97 | } | 97 | } |
98 | 98 | ||
99 | @Override | 99 | @Override |
100 | public String toString() { | 100 | public String toString() { |
101 | return MoreObjects.toStringHelper(getClass()) | 101 | return MoreObjects.toStringHelper(getClass()) |
102 | - .add("id", getId()) | 102 | + .add("id", id()) |
103 | - .add("match", getTrafficSelector()) | 103 | + .add("match", selector()) |
104 | - .add("action", getTrafficTreatment()) | 104 | + .add("action", treatment()) |
105 | - .add("ingressPort", ingressPort) | 105 | + .add("ingressPoint", ingressPoint) |
106 | - .add("egressPort", egressPorts) | 106 | + .add("egressPort", egressPoints) |
107 | .toString(); | 107 | .toString(); |
108 | } | 108 | } |
109 | 109 | ... | ... |
... | @@ -4,5 +4,53 @@ | ... | @@ -4,5 +4,53 @@ |
4 | * <em>what</em> rather than the <em>how</em>. This makes such instructions | 4 | * <em>what</em> rather than the <em>how</em>. This makes such instructions |
5 | * largely independent of topology and device specifics, thus allowing them to | 5 | * largely independent of topology and device specifics, thus allowing them to |
6 | * survive topology mutations. | 6 | * survive topology mutations. |
7 | + * <p/> | ||
8 | + * The controller core provides a suite of built-in intents and their compilers | ||
9 | + * and installers. However, the intent framework is extensible in that it allows | ||
10 | + * additional intents and their compilers or installers to be added | ||
11 | + * dynamically at run-time. This allows others to enhance the initial arsenal of | ||
12 | + * connectivity and policy-based intents available in base controller software. | ||
13 | + * <p/> | ||
14 | + * The following diagram depicts the state transition diagram for each top-level intent:<br> | ||
15 | + * <img src="doc-files/intent-states.png" alt="ONOS intent states"> | ||
16 | + * <p/> | ||
17 | + * The controller core accepts the intent specifications and translates them, via a | ||
18 | + * process referred to as intent compilation, to installable intents, which are | ||
19 | + * essentially actionable operations on the network environment. | ||
20 | + * These actions are carried out by intent installation process, which results | ||
21 | + * in some changes to the environment, e.g. tunnel links being provisioned, | ||
22 | + * flow rules being installed on the data-plane, optical lambdas being reserved. | ||
23 | + * <p/> | ||
24 | + * After an intent is submitted by an application, it will be sent immediately | ||
25 | + * (but asynchronously) into a compiling phase, then to installing phase and if | ||
26 | + * all goes according to plan into installed state. Once an application decides | ||
27 | + * it no longer wishes the intent to hold, it can withdraw it. This describes | ||
28 | + * the nominal flow. However, it may happen that some issue is encountered. | ||
29 | + * For example, an application may ask for an objective that is not currently | ||
30 | + * achievable, e.g. connectivity across to unconnected network segments. | ||
31 | + * If this is the case, the compiling phase may fail to produce a set of | ||
32 | + * installable intents and instead result in a failed compile. If this occurs, | ||
33 | + * only a change in the environment can trigger a transition back to the | ||
34 | + * compiling state. | ||
35 | + * <p/> | ||
36 | + * Similarly, an issue may be encountered during the installation phase in | ||
37 | + * which case the framework will attempt to recompile the intent to see if an | ||
38 | + * alternate approach is available. If so, the intent will be sent back to | ||
39 | + * installing phase. Otherwise, it will be parked in the failed state. Another | ||
40 | + * scenario that’s very likely to be encountered is where the intent is | ||
41 | + * successfully compiled and installed, but due to some topology event, such | ||
42 | + * as a downed or downgraded link, loss of throughput may occur or connectivity | ||
43 | + * may be lost altogether, thus impacting the viability of a previously | ||
44 | + * satisfied intent. If this occurs, the framework will attempt to recompile | ||
45 | + * the intent, and if an alternate approach is available, its installation | ||
46 | + * will be attempted. Otherwise, the original top-level intent will be parked | ||
47 | + * in the failed state. | ||
48 | + * <p/> | ||
49 | + * Please note that all *ing states, depicted in orange, are transitional and | ||
50 | + * are expected to last only a brief amount of time. The rest of the states | ||
51 | + * are parking states where the intent may spent some time; except for the | ||
52 | + * submitted state of course. There, the intent may pause, but only briefly, | ||
53 | + * while the system determines where to perform the compilation or while it | ||
54 | + * performs global recomputation/optimization across all prior intents. | ||
7 | */ | 55 | */ |
8 | package org.onlab.onos.net.intent; | 56 | package org.onlab.onos.net.intent; |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -40,8 +40,7 @@ public class FakeIntentManager implements TestableIntentService { | ... | @@ -40,8 +40,7 @@ public class FakeIntentManager implements TestableIntentService { |
40 | @Override | 40 | @Override |
41 | public void run() { | 41 | public void run() { |
42 | try { | 42 | try { |
43 | - List<InstallableIntent> installable = compileIntent(intent); | 43 | + executeCompilingPhase(intent); |
44 | - installIntents(intent, installable); | ||
45 | } catch (IntentException e) { | 44 | } catch (IntentException e) { |
46 | exceptions.add(e); | 45 | exceptions.add(e); |
47 | } | 46 | } |
... | @@ -55,8 +54,8 @@ public class FakeIntentManager implements TestableIntentService { | ... | @@ -55,8 +54,8 @@ public class FakeIntentManager implements TestableIntentService { |
55 | @Override | 54 | @Override |
56 | public void run() { | 55 | public void run() { |
57 | try { | 56 | try { |
58 | - List<InstallableIntent> installable = getInstallable(intent.getId()); | 57 | + List<InstallableIntent> installable = getInstallable(intent.id()); |
59 | - uninstallIntents(intent, installable); | 58 | + executeWithdrawingPhase(intent, installable); |
60 | } catch (IntentException e) { | 59 | } catch (IntentException e) { |
61 | exceptions.add(e); | 60 | exceptions.add(e); |
62 | } | 61 | } |
... | @@ -84,53 +83,60 @@ public class FakeIntentManager implements TestableIntentService { | ... | @@ -84,53 +83,60 @@ public class FakeIntentManager implements TestableIntentService { |
84 | return installer; | 83 | return installer; |
85 | } | 84 | } |
86 | 85 | ||
87 | - private <T extends Intent> List<InstallableIntent> compileIntent(T intent) { | 86 | + private <T extends Intent> void executeCompilingPhase(T intent) { |
87 | + setState(intent, IntentState.COMPILING); | ||
88 | try { | 88 | try { |
89 | // For the fake, we compile using a single level pass | 89 | // For the fake, we compile using a single level pass |
90 | List<InstallableIntent> installable = new ArrayList<>(); | 90 | List<InstallableIntent> installable = new ArrayList<>(); |
91 | for (Intent compiled : getCompiler(intent).compile(intent)) { | 91 | for (Intent compiled : getCompiler(intent).compile(intent)) { |
92 | installable.add((InstallableIntent) compiled); | 92 | installable.add((InstallableIntent) compiled); |
93 | } | 93 | } |
94 | - setState(intent, IntentState.COMPILED); | 94 | + executeInstallingPhase(intent, installable); |
95 | - return installable; | 95 | + |
96 | } catch (IntentException e) { | 96 | } catch (IntentException e) { |
97 | setState(intent, IntentState.FAILED); | 97 | setState(intent, IntentState.FAILED); |
98 | - throw e; | 98 | + dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent)); |
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | - private void installIntents(Intent intent, List<InstallableIntent> installable) { | 102 | + private void executeInstallingPhase(Intent intent, |
103 | + List<InstallableIntent> installable) { | ||
104 | + setState(intent, IntentState.INSTALLING); | ||
103 | try { | 105 | try { |
104 | for (InstallableIntent ii : installable) { | 106 | for (InstallableIntent ii : installable) { |
105 | registerSubclassInstallerIfNeeded(ii); | 107 | registerSubclassInstallerIfNeeded(ii); |
106 | getInstaller(ii).install(ii); | 108 | getInstaller(ii).install(ii); |
107 | } | 109 | } |
108 | setState(intent, IntentState.INSTALLED); | 110 | setState(intent, IntentState.INSTALLED); |
109 | - putInstallable(intent.getId(), installable); | 111 | + putInstallable(intent.id(), installable); |
112 | + dispatch(new IntentEvent(IntentEvent.Type.INSTALLED, intent)); | ||
113 | + | ||
110 | } catch (IntentException e) { | 114 | } catch (IntentException e) { |
111 | setState(intent, IntentState.FAILED); | 115 | setState(intent, IntentState.FAILED); |
112 | - throw e; | 116 | + dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent)); |
113 | } | 117 | } |
114 | } | 118 | } |
115 | 119 | ||
116 | - private void uninstallIntents(Intent intent, List<InstallableIntent> installable) { | 120 | + private void executeWithdrawingPhase(Intent intent, |
121 | + List<InstallableIntent> installable) { | ||
122 | + setState(intent, IntentState.WITHDRAWING); | ||
117 | try { | 123 | try { |
118 | for (InstallableIntent ii : installable) { | 124 | for (InstallableIntent ii : installable) { |
119 | getInstaller(ii).uninstall(ii); | 125 | getInstaller(ii).uninstall(ii); |
120 | } | 126 | } |
127 | + removeInstallable(intent.id()); | ||
121 | setState(intent, IntentState.WITHDRAWN); | 128 | setState(intent, IntentState.WITHDRAWN); |
122 | - removeInstallable(intent.getId()); | 129 | + dispatch(new IntentEvent(IntentEvent.Type.WITHDRAWN, intent)); |
123 | } catch (IntentException e) { | 130 | } catch (IntentException e) { |
131 | + // FIXME: Rework this to always go from WITHDRAWING to WITHDRAWN! | ||
124 | setState(intent, IntentState.FAILED); | 132 | setState(intent, IntentState.FAILED); |
125 | - throw e; | 133 | + dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent)); |
126 | } | 134 | } |
127 | } | 135 | } |
128 | 136 | ||
129 | // Sets the internal state for the given intent and dispatches an event | 137 | // Sets the internal state for the given intent and dispatches an event |
130 | private void setState(Intent intent, IntentState state) { | 138 | private void setState(Intent intent, IntentState state) { |
131 | - IntentState previous = intentStates.get(intent.getId()); | 139 | + intentStates.put(intent.id(), state); |
132 | - intentStates.put(intent.getId(), state); | ||
133 | - dispatch(new IntentEvent(intent, state, previous, System.currentTimeMillis())); | ||
134 | } | 140 | } |
135 | 141 | ||
136 | private void putInstallable(IntentId id, List<InstallableIntent> installable) { | 142 | private void putInstallable(IntentId id, List<InstallableIntent> installable) { |
... | @@ -152,15 +158,15 @@ public class FakeIntentManager implements TestableIntentService { | ... | @@ -152,15 +158,15 @@ public class FakeIntentManager implements TestableIntentService { |
152 | 158 | ||
153 | @Override | 159 | @Override |
154 | public void submit(Intent intent) { | 160 | public void submit(Intent intent) { |
155 | - intents.put(intent.getId(), intent); | 161 | + intents.put(intent.id(), intent); |
156 | setState(intent, IntentState.SUBMITTED); | 162 | setState(intent, IntentState.SUBMITTED); |
163 | + dispatch(new IntentEvent(IntentEvent.Type.SUBMITTED, intent)); | ||
157 | executeSubmit(intent); | 164 | executeSubmit(intent); |
158 | } | 165 | } |
159 | 166 | ||
160 | @Override | 167 | @Override |
161 | public void withdraw(Intent intent) { | 168 | public void withdraw(Intent intent) { |
162 | - intents.remove(intent.getId()); | 169 | + intents.remove(intent.id()); |
163 | - setState(intent, IntentState.WITHDRAWING); | ||
164 | executeWithdraw(intent); | 170 | executeWithdraw(intent); |
165 | } | 171 | } |
166 | 172 | ... | ... |
... | @@ -10,11 +10,9 @@ import java.util.Collections; | ... | @@ -10,11 +10,9 @@ import java.util.Collections; |
10 | import java.util.Iterator; | 10 | import java.util.Iterator; |
11 | import java.util.List; | 11 | import java.util.List; |
12 | 12 | ||
13 | -import static org.onlab.onos.net.intent.IntentState.*; | ||
14 | import static org.junit.Assert.*; | 13 | import static org.junit.Assert.*; |
14 | +import static org.onlab.onos.net.intent.IntentEvent.Type.*; | ||
15 | 15 | ||
16 | -// TODO: consider make it categorized as integration test when it become | ||
17 | -// slow test or fragile test | ||
18 | /** | 16 | /** |
19 | * Suite of tests for the intent service contract. | 17 | * Suite of tests for the intent service contract. |
20 | */ | 18 | */ |
... | @@ -64,13 +62,13 @@ public class IntentServiceTest { | ... | @@ -64,13 +62,13 @@ public class IntentServiceTest { |
64 | TestTools.assertAfter(GRACE_MS, new Runnable() { | 62 | TestTools.assertAfter(GRACE_MS, new Runnable() { |
65 | @Override | 63 | @Override |
66 | public void run() { | 64 | public void run() { |
67 | - assertEquals("incorrect intent state", INSTALLED, | 65 | + assertEquals("incorrect intent state", IntentState.INSTALLED, |
68 | - service.getIntentState(intent.getId())); | 66 | + service.getIntentState(intent.id())); |
69 | } | 67 | } |
70 | }); | 68 | }); |
71 | 69 | ||
72 | // Make sure that all expected events have been emitted | 70 | // Make sure that all expected events have been emitted |
73 | - validateEvents(intent, SUBMITTED, COMPILED, INSTALLED); | 71 | + validateEvents(intent, SUBMITTED, INSTALLED); |
74 | 72 | ||
75 | // Make sure there is just one intent (and is ours) | 73 | // Make sure there is just one intent (and is ours) |
76 | assertEquals("incorrect intent count", 1, service.getIntentCount()); | 74 | assertEquals("incorrect intent count", 1, service.getIntentCount()); |
... | @@ -85,19 +83,19 @@ public class IntentServiceTest { | ... | @@ -85,19 +83,19 @@ public class IntentServiceTest { |
85 | TestTools.assertAfter(GRACE_MS, new Runnable() { | 83 | TestTools.assertAfter(GRACE_MS, new Runnable() { |
86 | @Override | 84 | @Override |
87 | public void run() { | 85 | public void run() { |
88 | - assertEquals("incorrect intent state", WITHDRAWN, | 86 | + assertEquals("incorrect intent state", IntentState.WITHDRAWN, |
89 | - service.getIntentState(intent.getId())); | 87 | + service.getIntentState(intent.id())); |
90 | } | 88 | } |
91 | }); | 89 | }); |
92 | 90 | ||
93 | // Make sure that all expected events have been emitted | 91 | // Make sure that all expected events have been emitted |
94 | - validateEvents(intent, WITHDRAWING, WITHDRAWN); | 92 | + validateEvents(intent, WITHDRAWN); |
95 | 93 | ||
96 | // TODO: discuss what is the fate of intents after they have been withdrawn | 94 | // TODO: discuss what is the fate of intents after they have been withdrawn |
97 | // Make sure that the intent is no longer in the system | 95 | // Make sure that the intent is no longer in the system |
98 | // assertEquals("incorrect intent count", 0, service.getIntents().size()); | 96 | // assertEquals("incorrect intent count", 0, service.getIntents().size()); |
99 | -// assertNull("intent should not be found", service.getIntent(intent.getId())); | 97 | +// assertNull("intent should not be found", service.getIntent(intent.id())); |
100 | -// assertNull("intent state should not be found", service.getIntentState(intent.getId())); | 98 | +// assertNull("intent state should not be found", service.getIntentState(intent.id())); |
101 | } | 99 | } |
102 | 100 | ||
103 | @Test | 101 | @Test |
... | @@ -113,8 +111,8 @@ public class IntentServiceTest { | ... | @@ -113,8 +111,8 @@ public class IntentServiceTest { |
113 | TestTools.assertAfter(GRACE_MS, new Runnable() { | 111 | TestTools.assertAfter(GRACE_MS, new Runnable() { |
114 | @Override | 112 | @Override |
115 | public void run() { | 113 | public void run() { |
116 | - assertEquals("incorrect intent state", FAILED, | 114 | + assertEquals("incorrect intent state", IntentState.FAILED, |
117 | - service.getIntentState(intent.getId())); | 115 | + service.getIntentState(intent.id())); |
118 | } | 116 | } |
119 | }); | 117 | }); |
120 | 118 | ||
... | @@ -136,13 +134,13 @@ public class IntentServiceTest { | ... | @@ -136,13 +134,13 @@ public class IntentServiceTest { |
136 | TestTools.assertAfter(GRACE_MS, new Runnable() { | 134 | TestTools.assertAfter(GRACE_MS, new Runnable() { |
137 | @Override | 135 | @Override |
138 | public void run() { | 136 | public void run() { |
139 | - assertEquals("incorrect intent state", FAILED, | 137 | + assertEquals("incorrect intent state", IntentState.FAILED, |
140 | - service.getIntentState(intent.getId())); | 138 | + service.getIntentState(intent.id())); |
141 | } | 139 | } |
142 | }); | 140 | }); |
143 | 141 | ||
144 | // Make sure that all expected events have been emitted | 142 | // Make sure that all expected events have been emitted |
145 | - validateEvents(intent, SUBMITTED, COMPILED, FAILED); | 143 | + validateEvents(intent, SUBMITTED, FAILED); |
146 | } | 144 | } |
147 | 145 | ||
148 | /** | 146 | /** |
... | @@ -151,23 +149,23 @@ public class IntentServiceTest { | ... | @@ -151,23 +149,23 @@ public class IntentServiceTest { |
151 | * considered. | 149 | * considered. |
152 | * | 150 | * |
153 | * @param intent intent subject | 151 | * @param intent intent subject |
154 | - * @param states list of states for which events are expected | 152 | + * @param types list of event types for which events are expected |
155 | */ | 153 | */ |
156 | - protected void validateEvents(Intent intent, IntentState... states) { | 154 | + protected void validateEvents(Intent intent, IntentEvent.Type... types) { |
157 | Iterator<IntentEvent> events = listener.events.iterator(); | 155 | Iterator<IntentEvent> events = listener.events.iterator(); |
158 | - for (IntentState state : states) { | 156 | + for (IntentEvent.Type type : types) { |
159 | IntentEvent event = events.hasNext() ? events.next() : null; | 157 | IntentEvent event = events.hasNext() ? events.next() : null; |
160 | if (event == null) { | 158 | if (event == null) { |
161 | - fail("expected event not found: " + state); | 159 | + fail("expected event not found: " + type); |
162 | - } else if (intent.equals(event.getIntent())) { | 160 | + } else if (intent.equals(event.subject())) { |
163 | - assertEquals("incorrect state", state, event.getState()); | 161 | + assertEquals("incorrect state", type, event.type()); |
164 | } | 162 | } |
165 | } | 163 | } |
166 | 164 | ||
167 | // Remainder of events should not apply to this intent; make sure. | 165 | // Remainder of events should not apply to this intent; make sure. |
168 | while (events.hasNext()) { | 166 | while (events.hasNext()) { |
169 | assertFalse("unexpected event for intent", | 167 | assertFalse("unexpected event for intent", |
170 | - intent.equals(events.next().getIntent())); | 168 | + intent.equals(events.next().subject())); |
171 | } | 169 | } |
172 | } | 170 | } |
173 | 171 | ||
... | @@ -228,8 +226,8 @@ public class IntentServiceTest { | ... | @@ -228,8 +226,8 @@ public class IntentServiceTest { |
228 | TestTools.assertAfter(GRACE_MS, new Runnable() { | 226 | TestTools.assertAfter(GRACE_MS, new Runnable() { |
229 | @Override | 227 | @Override |
230 | public void run() { | 228 | public void run() { |
231 | - assertEquals("incorrect intent state", INSTALLED, | 229 | + assertEquals("incorrect intent state", IntentState.INSTALLED, |
232 | - service.getIntentState(intent.getId())); | 230 | + service.getIntentState(intent.id())); |
233 | } | 231 | } |
234 | }); | 232 | }); |
235 | 233 | ... | ... |
... | @@ -12,10 +12,10 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest { | ... | @@ -12,10 +12,10 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest { |
12 | @Test | 12 | @Test |
13 | public void basics() { | 13 | public void basics() { |
14 | MultiPointToSinglePointIntent intent = createOne(); | 14 | MultiPointToSinglePointIntent intent = createOne(); |
15 | - assertEquals("incorrect id", IID, intent.getId()); | 15 | + assertEquals("incorrect id", IID, intent.id()); |
16 | - assertEquals("incorrect match", MATCH, intent.getTrafficSelector()); | 16 | + assertEquals("incorrect match", MATCH, intent.selector()); |
17 | - assertEquals("incorrect ingress", PS1, intent.getIngressPorts()); | 17 | + assertEquals("incorrect ingress", PS1, intent.ingressPoints()); |
18 | - assertEquals("incorrect egress", P2, intent.getEgressPort()); | 18 | + assertEquals("incorrect egress", P2, intent.egressPoint()); |
19 | } | 19 | } |
20 | 20 | ||
21 | @Override | 21 | @Override | ... | ... |
... | @@ -16,12 +16,12 @@ public class PathIntentTest extends ConnectivityIntentTest { | ... | @@ -16,12 +16,12 @@ public class PathIntentTest extends ConnectivityIntentTest { |
16 | @Test | 16 | @Test |
17 | public void basics() { | 17 | public void basics() { |
18 | PathIntent intent = createOne(); | 18 | PathIntent intent = createOne(); |
19 | - assertEquals("incorrect id", IID, intent.getId()); | 19 | + assertEquals("incorrect id", IID, intent.id()); |
20 | - assertEquals("incorrect match", MATCH, intent.getTrafficSelector()); | 20 | + assertEquals("incorrect match", MATCH, intent.selector()); |
21 | - assertEquals("incorrect action", NOP, intent.getTrafficTreatment()); | 21 | + assertEquals("incorrect action", NOP, intent.treatment()); |
22 | - assertEquals("incorrect ingress", P1, intent.getIngressPort()); | 22 | + assertEquals("incorrect ingress", P1, intent.ingressPoint()); |
23 | - assertEquals("incorrect egress", P2, intent.getEgressPort()); | 23 | + assertEquals("incorrect egress", P2, intent.egressPoint()); |
24 | - assertEquals("incorrect path", PATH1, intent.getPath()); | 24 | + assertEquals("incorrect path", PATH1, intent.path()); |
25 | } | 25 | } |
26 | 26 | ||
27 | @Override | 27 | @Override | ... | ... |
... | @@ -12,10 +12,10 @@ public class PointToPointIntentTest extends ConnectivityIntentTest { | ... | @@ -12,10 +12,10 @@ public class PointToPointIntentTest extends ConnectivityIntentTest { |
12 | @Test | 12 | @Test |
13 | public void basics() { | 13 | public void basics() { |
14 | PointToPointIntent intent = createOne(); | 14 | PointToPointIntent intent = createOne(); |
15 | - assertEquals("incorrect id", IID, intent.getId()); | 15 | + assertEquals("incorrect id", IID, intent.id()); |
16 | - assertEquals("incorrect match", MATCH, intent.getTrafficSelector()); | 16 | + assertEquals("incorrect match", MATCH, intent.selector()); |
17 | - assertEquals("incorrect ingress", P1, intent.getIngressPort()); | 17 | + assertEquals("incorrect ingress", P1, intent.ingressPoint()); |
18 | - assertEquals("incorrect egress", P2, intent.getEgressPort()); | 18 | + assertEquals("incorrect egress", P2, intent.egressPoint()); |
19 | } | 19 | } |
20 | 20 | ||
21 | @Override | 21 | @Override | ... | ... |
... | @@ -12,10 +12,10 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest { | ... | @@ -12,10 +12,10 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest { |
12 | @Test | 12 | @Test |
13 | public void basics() { | 13 | public void basics() { |
14 | SinglePointToMultiPointIntent intent = createOne(); | 14 | SinglePointToMultiPointIntent intent = createOne(); |
15 | - assertEquals("incorrect id", IID, intent.getId()); | 15 | + assertEquals("incorrect id", IID, intent.id()); |
16 | - assertEquals("incorrect match", MATCH, intent.getTrafficSelector()); | 16 | + assertEquals("incorrect match", MATCH, intent.selector()); |
17 | - assertEquals("incorrect ingress", P1, intent.getIngressPort()); | 17 | + assertEquals("incorrect ingress", P1, intent.ingressPoint()); |
18 | - assertEquals("incorrect egress", PS2, intent.getEgressPorts()); | 18 | + assertEquals("incorrect egress", PS2, intent.egressPoints()); |
19 | } | 19 | } |
20 | 20 | ||
21 | @Override | 21 | @Override | ... | ... |
... | @@ -40,14 +40,14 @@ import com.google.common.collect.Lists; | ... | @@ -40,14 +40,14 @@ import com.google.common.collect.Lists; |
40 | @Component(immediate = true) | 40 | @Component(immediate = true) |
41 | @Service | 41 | @Service |
42 | public class FlowRuleManager | 42 | public class FlowRuleManager |
43 | -extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService> | 43 | + extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService> |
44 | -implements FlowRuleService, FlowRuleProviderRegistry { | 44 | + implements FlowRuleService, FlowRuleProviderRegistry { |
45 | 45 | ||
46 | public static final String FLOW_RULE_NULL = "FlowRule cannot be null"; | 46 | public static final String FLOW_RULE_NULL = "FlowRule cannot be null"; |
47 | private final Logger log = getLogger(getClass()); | 47 | private final Logger log = getLogger(getClass()); |
48 | 48 | ||
49 | private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener> | 49 | private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener> |
50 | - listenerRegistry = new AbstractListenerRegistry<>(); | 50 | + listenerRegistry = new AbstractListenerRegistry<>(); |
51 | 51 | ||
52 | private final FlowRuleStoreDelegate delegate = new InternalStoreDelegate(); | 52 | private final FlowRuleStoreDelegate delegate = new InternalStoreDelegate(); |
53 | 53 | ||
... | @@ -75,6 +75,11 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -75,6 +75,11 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
75 | } | 75 | } |
76 | 76 | ||
77 | @Override | 77 | @Override |
78 | + public int getFlowRuleCount() { | ||
79 | + return store.getFlowRuleCount(); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
78 | public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) { | 83 | public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) { |
79 | return store.getFlowEntries(deviceId); | 84 | return store.getFlowEntries(deviceId); |
80 | } | 85 | } |
... | @@ -98,15 +103,17 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -98,15 +103,17 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
98 | for (int i = 0; i < flowRules.length; i++) { | 103 | for (int i = 0; i < flowRules.length; i++) { |
99 | f = flowRules[i]; | 104 | f = flowRules[i]; |
100 | device = deviceService.getDevice(f.deviceId()); | 105 | device = deviceService.getDevice(f.deviceId()); |
101 | - frp = getProvider(device.providerId()); | ||
102 | store.deleteFlowRule(f); | 106 | store.deleteFlowRule(f); |
103 | - frp.removeFlowRule(f); | 107 | + if (device != null) { |
108 | + frp = getProvider(device.providerId()); | ||
109 | + frp.removeFlowRule(f); | ||
110 | + } | ||
104 | } | 111 | } |
105 | } | 112 | } |
106 | 113 | ||
107 | @Override | 114 | @Override |
108 | public void removeFlowRulesById(ApplicationId id) { | 115 | public void removeFlowRulesById(ApplicationId id) { |
109 | - Iterable<FlowRule> rules = getFlowRulesById(id); | 116 | + Iterable<FlowRule> rules = getFlowRulesById(id); |
110 | FlowRuleProvider frp; | 117 | FlowRuleProvider frp; |
111 | Device device; | 118 | Device device; |
112 | 119 | ||
... | @@ -140,8 +147,8 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -140,8 +147,8 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
140 | } | 147 | } |
141 | 148 | ||
142 | private class InternalFlowRuleProviderService | 149 | private class InternalFlowRuleProviderService |
143 | - extends AbstractProviderService<FlowRuleProvider> | 150 | + extends AbstractProviderService<FlowRuleProvider> |
144 | - implements FlowRuleProviderService { | 151 | + implements FlowRuleProviderService { |
145 | 152 | ||
146 | protected InternalFlowRuleProviderService(FlowRuleProvider provider) { | 153 | protected InternalFlowRuleProviderService(FlowRuleProvider provider) { |
147 | super(provider); | 154 | super(provider); |
... | @@ -160,16 +167,16 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -160,16 +167,16 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
160 | FlowRuleProvider frp = getProvider(device.providerId()); | 167 | FlowRuleProvider frp = getProvider(device.providerId()); |
161 | FlowRuleEvent event = null; | 168 | FlowRuleEvent event = null; |
162 | switch (stored.state()) { | 169 | switch (stored.state()) { |
163 | - case ADDED: | 170 | + case ADDED: |
164 | - case PENDING_ADD: | 171 | + case PENDING_ADD: |
165 | frp.applyFlowRule(stored); | 172 | frp.applyFlowRule(stored); |
166 | - break; | 173 | + break; |
167 | - case PENDING_REMOVE: | 174 | + case PENDING_REMOVE: |
168 | - case REMOVED: | 175 | + case REMOVED: |
169 | - event = store.removeFlowRule(stored); | 176 | + event = store.removeFlowRule(stored); |
170 | - break; | 177 | + break; |
171 | - default: | 178 | + default: |
172 | - break; | 179 | + break; |
173 | 180 | ||
174 | } | 181 | } |
175 | if (event != null) { | 182 | if (event != null) { |
... | @@ -186,17 +193,17 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -186,17 +193,17 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
186 | FlowRuleProvider frp = getProvider(device.providerId()); | 193 | FlowRuleProvider frp = getProvider(device.providerId()); |
187 | FlowRuleEvent event = null; | 194 | FlowRuleEvent event = null; |
188 | switch (flowRule.state()) { | 195 | switch (flowRule.state()) { |
189 | - case PENDING_REMOVE: | 196 | + case PENDING_REMOVE: |
190 | - case REMOVED: | 197 | + case REMOVED: |
191 | - event = store.removeFlowRule(flowRule); | 198 | + event = store.removeFlowRule(flowRule); |
192 | - frp.removeFlowRule(flowRule); | 199 | + frp.removeFlowRule(flowRule); |
193 | - break; | 200 | + break; |
194 | - case ADDED: | 201 | + case ADDED: |
195 | - case PENDING_ADD: | 202 | + case PENDING_ADD: |
196 | - frp.applyFlowRule(flowRule); | 203 | + frp.applyFlowRule(flowRule); |
197 | - break; | 204 | + break; |
198 | - default: | 205 | + default: |
199 | - log.debug("Flow {} has not been installed.", flowRule); | 206 | + log.debug("Flow {} has not been installed.", flowRule); |
200 | } | 207 | } |
201 | 208 | ||
202 | if (event != null) { | 209 | if (event != null) { | ... | ... |
... | @@ -71,11 +71,11 @@ public class HostToHostIntentCompiler | ... | @@ -71,11 +71,11 @@ public class HostToHostIntentCompiler |
71 | private Intent createPathIntent(Path path, Host src, Host dst, | 71 | private Intent createPathIntent(Path path, Host src, Host dst, |
72 | HostToHostIntent intent) { | 72 | HostToHostIntent intent) { |
73 | 73 | ||
74 | - TrafficSelector selector = builder(intent.getTrafficSelector()) | 74 | + TrafficSelector selector = builder(intent.selector()) |
75 | .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build(); | 75 | .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build(); |
76 | 76 | ||
77 | return new PathIntent(intentIdGenerator.getNewId(), | 77 | return new PathIntent(intentIdGenerator.getNewId(), |
78 | - selector, intent.getTrafficTreatment(), | 78 | + selector, intent.treatment(), |
79 | path.src(), path.dst(), path); | 79 | path.src(), path.dst(), path); |
80 | } | 80 | } |
81 | 81 | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -19,12 +19,15 @@ import org.onlab.onos.net.topology.TopologyService; | ... | @@ -19,12 +19,15 @@ import org.onlab.onos.net.topology.TopologyService; |
19 | import org.slf4j.Logger; | 19 | import org.slf4j.Logger; |
20 | 20 | ||
21 | import java.util.Collection; | 21 | import java.util.Collection; |
22 | +import java.util.HashSet; | ||
23 | +import java.util.Set; | ||
22 | import java.util.concurrent.ExecutorService; | 24 | import java.util.concurrent.ExecutorService; |
23 | 25 | ||
24 | import static com.google.common.base.Preconditions.checkArgument; | 26 | import static com.google.common.base.Preconditions.checkArgument; |
25 | import static com.google.common.base.Preconditions.checkNotNull; | 27 | import static com.google.common.base.Preconditions.checkNotNull; |
26 | import static com.google.common.collect.Multimaps.synchronizedSetMultimap; | 28 | import static com.google.common.collect.Multimaps.synchronizedSetMultimap; |
27 | import static java.util.concurrent.Executors.newSingleThreadExecutor; | 29 | import static java.util.concurrent.Executors.newSingleThreadExecutor; |
30 | +import static org.onlab.onos.net.link.LinkEvent.Type.LINK_REMOVED; | ||
28 | import static org.onlab.util.Tools.namedThreads; | 31 | import static org.onlab.util.Tools.namedThreads; |
29 | import static org.slf4j.LoggerFactory.getLogger; | 32 | import static org.slf4j.LoggerFactory.getLogger; |
30 | 33 | ||
... | @@ -34,7 +37,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -34,7 +37,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
34 | */ | 37 | */ |
35 | @Component | 38 | @Component |
36 | @Service | 39 | @Service |
37 | -public class FlowTracker implements FlowTrackerService { | 40 | +public class ObjectiveTracker implements ObjectiveTrackerService { |
38 | 41 | ||
39 | private final Logger log = getLogger(getClass()); | 42 | private final Logger log = getLogger(getClass()); |
40 | 43 | ||
... | @@ -110,19 +113,26 @@ public class FlowTracker implements FlowTrackerService { | ... | @@ -110,19 +113,26 @@ public class FlowTracker implements FlowTrackerService { |
110 | @Override | 113 | @Override |
111 | public void run() { | 114 | public void run() { |
112 | if (event.reasons() == null) { | 115 | if (event.reasons() == null) { |
113 | - delegate.bumpIntents(intentsByLink.values()); | 116 | + delegate.triggerCompile(new HashSet<IntentId>(), true); |
117 | + | ||
114 | } else { | 118 | } else { |
119 | + Set<IntentId> toBeRecompiled = new HashSet<>(); | ||
120 | + boolean recompileOnly = true; | ||
121 | + | ||
122 | + // Scan through the list of reasons and keep accruing all | ||
123 | + // intents that need to be recompiled. | ||
115 | for (Event reason : event.reasons()) { | 124 | for (Event reason : event.reasons()) { |
116 | if (reason instanceof LinkEvent) { | 125 | if (reason instanceof LinkEvent) { |
117 | LinkEvent linkEvent = (LinkEvent) reason; | 126 | LinkEvent linkEvent = (LinkEvent) reason; |
118 | - if (linkEvent.type() == LinkEvent.Type.LINK_ADDED || | 127 | + if (linkEvent.type() == LINK_REMOVED) { |
119 | - linkEvent.type() == LinkEvent.Type.LINK_UPDATED) { | 128 | + Set<IntentId> intentIds = intentsByLink.get(new LinkKey(linkEvent.subject())); |
120 | - delegate.bumpIntents(intentsByLink.get(new LinkKey(linkEvent.subject()))); | 129 | + toBeRecompiled.addAll(intentIds); |
121 | - } else if (linkEvent.type() == LinkEvent.Type.LINK_REMOVED) { | ||
122 | - delegate.failIntents(intentsByLink.get(new LinkKey(linkEvent.subject()))); | ||
123 | } | 130 | } |
131 | + recompileOnly = recompileOnly && linkEvent.type() == LINK_REMOVED; | ||
124 | } | 132 | } |
125 | } | 133 | } |
134 | + | ||
135 | + delegate.triggerCompile(toBeRecompiled, !recompileOnly); | ||
126 | } | 136 | } |
127 | } | 137 | } |
128 | } | 138 | } | ... | ... |
... | @@ -9,7 +9,7 @@ import java.util.Collection; | ... | @@ -9,7 +9,7 @@ import java.util.Collection; |
9 | * Auxiliary service for tracking intent path flows and for notifying the | 9 | * Auxiliary service for tracking intent path flows and for notifying the |
10 | * intent service of environment changes via topology change delegate. | 10 | * intent service of environment changes via topology change delegate. |
11 | */ | 11 | */ |
12 | -public interface FlowTrackerService { | 12 | +public interface ObjectiveTrackerService { |
13 | 13 | ||
14 | /** | 14 | /** |
15 | * Sets a topology change delegate. | 15 | * Sets a topology change delegate. | ... | ... |
1 | package org.onlab.onos.net.intent.impl; | 1 | package org.onlab.onos.net.intent.impl; |
2 | 2 | ||
3 | import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; | 3 | import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; |
4 | +import static org.slf4j.LoggerFactory.getLogger; | ||
4 | 5 | ||
5 | import java.util.Iterator; | 6 | import java.util.Iterator; |
6 | 7 | ||
... | @@ -21,6 +22,7 @@ import org.onlab.onos.net.flow.TrafficTreatment; | ... | @@ -21,6 +22,7 @@ import org.onlab.onos.net.flow.TrafficTreatment; |
21 | import org.onlab.onos.net.intent.IntentExtensionService; | 22 | import org.onlab.onos.net.intent.IntentExtensionService; |
22 | import org.onlab.onos.net.intent.IntentInstaller; | 23 | import org.onlab.onos.net.intent.IntentInstaller; |
23 | import org.onlab.onos.net.intent.PathIntent; | 24 | import org.onlab.onos.net.intent.PathIntent; |
25 | +import org.slf4j.Logger; | ||
24 | 26 | ||
25 | /** | 27 | /** |
26 | * Installer for {@link PathIntent path connectivity intents}. | 28 | * Installer for {@link PathIntent path connectivity intents}. |
... | @@ -28,6 +30,8 @@ import org.onlab.onos.net.intent.PathIntent; | ... | @@ -28,6 +30,8 @@ import org.onlab.onos.net.intent.PathIntent; |
28 | @Component(immediate = true) | 30 | @Component(immediate = true) |
29 | public class PathIntentInstaller implements IntentInstaller<PathIntent> { | 31 | public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
30 | 32 | ||
33 | + private final Logger log = getLogger(getClass()); | ||
34 | + | ||
31 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 35 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
32 | protected IntentExtensionService intentManager; | 36 | protected IntentExtensionService intentManager; |
33 | 37 | ||
... | @@ -49,8 +53,8 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -49,8 +53,8 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
49 | @Override | 53 | @Override |
50 | public void install(PathIntent intent) { | 54 | public void install(PathIntent intent) { |
51 | TrafficSelector.Builder builder = | 55 | TrafficSelector.Builder builder = |
52 | - DefaultTrafficSelector.builder(intent.getTrafficSelector()); | 56 | + DefaultTrafficSelector.builder(intent.selector()); |
53 | - Iterator<Link> links = intent.getPath().links().iterator(); | 57 | + Iterator<Link> links = intent.path().links().iterator(); |
54 | ConnectPoint prev = links.next().dst(); | 58 | ConnectPoint prev = links.next().dst(); |
55 | 59 | ||
56 | while (links.hasNext()) { | 60 | while (links.hasNext()) { |
... | @@ -70,8 +74,8 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -70,8 +74,8 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
70 | @Override | 74 | @Override |
71 | public void uninstall(PathIntent intent) { | 75 | public void uninstall(PathIntent intent) { |
72 | TrafficSelector.Builder builder = | 76 | TrafficSelector.Builder builder = |
73 | - DefaultTrafficSelector.builder(intent.getTrafficSelector()); | 77 | + DefaultTrafficSelector.builder(intent.selector()); |
74 | - Iterator<Link> links = intent.getPath().links().iterator(); | 78 | + Iterator<Link> links = intent.path().links().iterator(); |
75 | ConnectPoint prev = links.next().dst(); | 79 | ConnectPoint prev = links.next().dst(); |
76 | 80 | ||
77 | while (links.hasNext()) { | 81 | while (links.hasNext()) { |
... | @@ -82,6 +86,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -82,6 +86,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
82 | FlowRule rule = new DefaultFlowRule(link.src().deviceId(), | 86 | FlowRule rule = new DefaultFlowRule(link.src().deviceId(), |
83 | builder.build(), treatment, | 87 | builder.build(), treatment, |
84 | 123, appId, 600); | 88 | 123, appId, 600); |
89 | + | ||
85 | flowRuleService.removeFlowRules(rule); | 90 | flowRuleService.removeFlowRules(rule); |
86 | prev = link.dst(); | 91 | prev = link.dst(); |
87 | } | 92 | } | ... | ... |
... | @@ -9,18 +9,14 @@ public interface TopologyChangeDelegate { | ... | @@ -9,18 +9,14 @@ public interface TopologyChangeDelegate { |
9 | 9 | ||
10 | /** | 10 | /** |
11 | * Notifies that topology has changed in such a way that the specified | 11 | * Notifies that topology has changed in such a way that the specified |
12 | - * intents should be recompiled. | 12 | + * intents should be recompiled. If the {@code compileAllFailed} parameter |
13 | + * is true, then all intents in {@link org.onlab.onos.net.intent.IntentState#FAILED} | ||
14 | + * state should be compiled as well. | ||
13 | * | 15 | * |
14 | * @param intentIds intents that should be recompiled | 16 | * @param intentIds intents that should be recompiled |
17 | + * @param compileAllFailed true implies full compile of all failed intents | ||
18 | + * is required; false for selective recompile only | ||
15 | */ | 19 | */ |
16 | - void bumpIntents(Iterable<IntentId> intentIds); | 20 | + void triggerCompile(Iterable<IntentId> intentIds, boolean compileAllFailed); |
17 | - | ||
18 | - /** | ||
19 | - * Notifies that topology has changed in such a way that the specified | ||
20 | - * intents should be marked failed and then recompiled. | ||
21 | - * | ||
22 | - * @param intentIds intents that should be failed and recompiled | ||
23 | - */ | ||
24 | - void failIntents(Iterable<IntentId> intentIds); | ||
25 | 21 | ||
26 | } | 22 | } | ... | ... |
... | @@ -36,8 +36,6 @@ import org.onlab.onos.store.common.StoreManager; | ... | @@ -36,8 +36,6 @@ import org.onlab.onos.store.common.StoreManager; |
36 | import org.onlab.onos.store.common.StoreService; | 36 | import org.onlab.onos.store.common.StoreService; |
37 | import org.onlab.onos.store.common.TestStoreManager; | 37 | import org.onlab.onos.store.common.TestStoreManager; |
38 | import org.onlab.onos.store.device.impl.DistributedDeviceStore; | 38 | import org.onlab.onos.store.device.impl.DistributedDeviceStore; |
39 | -import org.onlab.onos.store.serializers.KryoSerializationManager; | ||
40 | -import org.onlab.onos.store.serializers.KryoSerializationService; | ||
41 | import org.onlab.packet.IpPrefix; | 39 | import org.onlab.packet.IpPrefix; |
42 | 40 | ||
43 | import java.util.ArrayList; | 41 | import java.util.ArrayList; |
... | @@ -95,7 +93,6 @@ public class DistributedDeviceManagerTest { | ... | @@ -95,7 +93,6 @@ public class DistributedDeviceManagerTest { |
95 | private DistributedDeviceStore dstore; | 93 | private DistributedDeviceStore dstore; |
96 | private TestMastershipManager masterManager; | 94 | private TestMastershipManager masterManager; |
97 | private EventDeliveryService eventService; | 95 | private EventDeliveryService eventService; |
98 | - private KryoSerializationManager serializationMgr; | ||
99 | 96 | ||
100 | @Before | 97 | @Before |
101 | public void setUp() { | 98 | public void setUp() { |
... | @@ -111,10 +108,7 @@ public class DistributedDeviceManagerTest { | ... | @@ -111,10 +108,7 @@ public class DistributedDeviceManagerTest { |
111 | storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config)); | 108 | storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config)); |
112 | storeManager.activate(); | 109 | storeManager.activate(); |
113 | 110 | ||
114 | - serializationMgr = new KryoSerializationManager(); | 111 | + dstore = new TestDistributedDeviceStore(storeManager); |
115 | - serializationMgr.activate(); | ||
116 | - | ||
117 | - dstore = new TestDistributedDeviceStore(storeManager, serializationMgr); | ||
118 | dstore.activate(); | 112 | dstore.activate(); |
119 | 113 | ||
120 | mgr.store = dstore; | 114 | mgr.store = dstore; |
... | @@ -140,7 +134,6 @@ public class DistributedDeviceManagerTest { | ... | @@ -140,7 +134,6 @@ public class DistributedDeviceManagerTest { |
140 | mgr.deactivate(); | 134 | mgr.deactivate(); |
141 | 135 | ||
142 | dstore.deactivate(); | 136 | dstore.deactivate(); |
143 | - serializationMgr.deactivate(); | ||
144 | storeManager.deactivate(); | 137 | storeManager.deactivate(); |
145 | } | 138 | } |
146 | 139 | ||
... | @@ -306,10 +299,8 @@ public class DistributedDeviceManagerTest { | ... | @@ -306,10 +299,8 @@ public class DistributedDeviceManagerTest { |
306 | 299 | ||
307 | private class TestDistributedDeviceStore extends DistributedDeviceStore { | 300 | private class TestDistributedDeviceStore extends DistributedDeviceStore { |
308 | 301 | ||
309 | - public TestDistributedDeviceStore(StoreService storeService, | 302 | + public TestDistributedDeviceStore(StoreService storeService) { |
310 | - KryoSerializationService kryoSerializationService) { | ||
311 | this.storeService = storeService; | 303 | this.storeService = storeService; |
312 | - this.kryoSerializationService = kryoSerializationService; | ||
313 | } | 304 | } |
314 | } | 305 | } |
315 | 306 | ... | ... |
1 | -package org.onlab.onos.store.cluster.messaging.impl; | 1 | +package org.onlab.onos.store.cluster.impl; |
2 | 2 | ||
3 | import org.onlab.onos.store.cluster.messaging.MessageSubject; | 3 | import org.onlab.onos.store.cluster.messaging.MessageSubject; |
4 | 4 | ||
5 | -public final class ClusterMessageSubjects { | 5 | +public final class ClusterManagementMessageSubjects { |
6 | // avoid instantiation | 6 | // avoid instantiation |
7 | - private ClusterMessageSubjects() {} | 7 | + private ClusterManagementMessageSubjects() {} |
8 | 8 | ||
9 | public static final MessageSubject CLUSTER_MEMBERSHIP_EVENT = new MessageSubject("CLUSTER_MEMBERSHIP_EVENT"); | 9 | public static final MessageSubject CLUSTER_MEMBERSHIP_EVENT = new MessageSubject("CLUSTER_MEMBERSHIP_EVENT"); |
10 | } | 10 | } | ... | ... |
... | @@ -11,14 +11,15 @@ public class ClusterMessage { | ... | @@ -11,14 +11,15 @@ public class ClusterMessage { |
11 | 11 | ||
12 | private final NodeId sender; | 12 | private final NodeId sender; |
13 | private final MessageSubject subject; | 13 | private final MessageSubject subject; |
14 | - private final Object payload; | 14 | + private final byte[] payload; |
15 | + // TODO: add field specifying Serializer for payload | ||
15 | 16 | ||
16 | /** | 17 | /** |
17 | * Creates a cluster message. | 18 | * Creates a cluster message. |
18 | * | 19 | * |
19 | * @param subject message subject | 20 | * @param subject message subject |
20 | */ | 21 | */ |
21 | - public ClusterMessage(NodeId sender, MessageSubject subject, Object payload) { | 22 | + public ClusterMessage(NodeId sender, MessageSubject subject, byte[] payload) { |
22 | this.sender = sender; | 23 | this.sender = sender; |
23 | this.subject = subject; | 24 | this.subject = subject; |
24 | this.payload = payload; | 25 | this.payload = payload; |
... | @@ -47,7 +48,7 @@ public class ClusterMessage { | ... | @@ -47,7 +48,7 @@ public class ClusterMessage { |
47 | * | 48 | * |
48 | * @return message payload. | 49 | * @return message payload. |
49 | */ | 50 | */ |
50 | - public Object payload() { | 51 | + public byte[] payload() { |
51 | return payload; | 52 | return payload; |
52 | } | 53 | } |
53 | } | 54 | } | ... | ... |
1 | package org.onlab.onos.store.cluster.messaging; | 1 | package org.onlab.onos.store.cluster.messaging; |
2 | 2 | ||
3 | /** | 3 | /** |
4 | - * Service for encoding & decoding intra-cluster messages. | 4 | + * Service for encoding & decoding intra-cluster message payload. |
5 | */ | 5 | */ |
6 | public interface SerializationService { | 6 | public interface SerializationService { |
7 | 7 | ||
... | @@ -11,7 +11,7 @@ public interface SerializationService { | ... | @@ -11,7 +11,7 @@ public interface SerializationService { |
11 | * @param buffer byte buffer with message(s) | 11 | * @param buffer byte buffer with message(s) |
12 | * @return parsed message | 12 | * @return parsed message |
13 | */ | 13 | */ |
14 | - Object decode(byte[] data); | 14 | + <T> T decode(byte[] data); |
15 | 15 | ||
16 | /** | 16 | /** |
17 | * Encodes the specified message into the given byte buffer. | 17 | * Encodes the specified message into the given byte buffer. | ... | ... |
... | @@ -12,17 +12,20 @@ import java.util.TimerTask; | ... | @@ -12,17 +12,20 @@ import java.util.TimerTask; |
12 | import org.apache.felix.scr.annotations.Activate; | 12 | import org.apache.felix.scr.annotations.Activate; |
13 | import org.apache.felix.scr.annotations.Component; | 13 | import org.apache.felix.scr.annotations.Component; |
14 | import org.apache.felix.scr.annotations.Deactivate; | 14 | import org.apache.felix.scr.annotations.Deactivate; |
15 | -import org.apache.felix.scr.annotations.Reference; | ||
16 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
17 | import org.apache.felix.scr.annotations.Service; | 15 | import org.apache.felix.scr.annotations.Service; |
18 | import org.onlab.onos.cluster.ControllerNode; | 16 | import org.onlab.onos.cluster.ControllerNode; |
19 | import org.onlab.onos.cluster.NodeId; | 17 | import org.onlab.onos.cluster.NodeId; |
18 | +import org.onlab.onos.store.cluster.impl.ClusterMembershipEvent; | ||
19 | +import org.onlab.onos.store.cluster.impl.ClusterMembershipEventType; | ||
20 | import org.onlab.onos.store.cluster.impl.ClusterNodesDelegate; | 20 | import org.onlab.onos.store.cluster.impl.ClusterNodesDelegate; |
21 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationAdminService; | 21 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationAdminService; |
22 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; | 22 | import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; |
23 | import org.onlab.onos.store.cluster.messaging.ClusterMessage; | 23 | import org.onlab.onos.store.cluster.messaging.ClusterMessage; |
24 | import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; | 24 | import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; |
25 | import org.onlab.onos.store.cluster.messaging.MessageSubject; | 25 | import org.onlab.onos.store.cluster.messaging.MessageSubject; |
26 | +import org.onlab.onos.store.serializers.KryoPoolUtil; | ||
27 | +import org.onlab.onos.store.serializers.KryoSerializer; | ||
28 | +import org.onlab.util.KryoPool; | ||
26 | import org.onlab.netty.Endpoint; | 29 | import org.onlab.netty.Endpoint; |
27 | import org.onlab.netty.Message; | 30 | import org.onlab.netty.Message; |
28 | import org.onlab.netty.MessageHandler; | 31 | import org.onlab.netty.MessageHandler; |
... | @@ -44,16 +47,35 @@ public class ClusterCommunicationManager | ... | @@ -44,16 +47,35 @@ public class ClusterCommunicationManager |
44 | private final Timer timer = new Timer("onos-controller-heatbeats"); | 47 | private final Timer timer = new Timer("onos-controller-heatbeats"); |
45 | public static final long HEART_BEAT_INTERVAL_MILLIS = 1000L; | 48 | public static final long HEART_BEAT_INTERVAL_MILLIS = 1000L; |
46 | 49 | ||
47 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 50 | + // TODO: This probably should not be a OSGi service. |
51 | + //@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
48 | private MessagingService messagingService; | 52 | private MessagingService messagingService; |
49 | 53 | ||
54 | + private static final KryoSerializer SERIALIZER = new KryoSerializer() { | ||
55 | + protected void setupKryoPool() { | ||
56 | + serializerPool = KryoPool.newBuilder() | ||
57 | + .register(KryoPoolUtil.API) | ||
58 | + .register(ClusterMessage.class) | ||
59 | + .register(ClusterMembershipEvent.class) | ||
60 | + .build() | ||
61 | + .populate(1); | ||
62 | + } | ||
63 | + | ||
64 | + }; | ||
65 | + | ||
50 | @Activate | 66 | @Activate |
51 | public void activate() { | 67 | public void activate() { |
68 | + // TODO: initialize messagingService | ||
69 | + // TODO: setPayloadSerializer, which is capable of | ||
70 | + // (1) serialize ClusterMessage - ClusterMessage.payload | ||
71 | + // (2) serialize ClusterMessage.payload using user specified serializer | ||
72 | +// messagingService.setPayloadSerializer(...); | ||
52 | log.info("Started"); | 73 | log.info("Started"); |
53 | } | 74 | } |
54 | 75 | ||
55 | @Deactivate | 76 | @Deactivate |
56 | public void deactivate() { | 77 | public void deactivate() { |
78 | + // TODO: cleanup messageingService if needed. | ||
57 | log.info("Stopped"); | 79 | log.info("Stopped"); |
58 | } | 80 | } |
59 | 81 | ||
... | @@ -85,7 +107,7 @@ public class ClusterCommunicationManager | ... | @@ -85,7 +107,7 @@ public class ClusterCommunicationManager |
85 | checkArgument(node != null, "Unknown nodeId: %s", toNodeId); | 107 | checkArgument(node != null, "Unknown nodeId: %s", toNodeId); |
86 | Endpoint nodeEp = new Endpoint(node.ip().toString(), node.tcpPort()); | 108 | Endpoint nodeEp = new Endpoint(node.ip().toString(), node.tcpPort()); |
87 | try { | 109 | try { |
88 | - messagingService.sendAsync(nodeEp, message.subject().value(), message); | 110 | + messagingService.sendAsync(nodeEp, message.subject().value(), SERIALIZER.encode(message)); |
89 | return true; | 111 | return true; |
90 | } catch (IOException e) { | 112 | } catch (IOException e) { |
91 | log.error("Failed to send cluster message to nodeId: " + toNodeId, e); | 113 | log.error("Failed to send cluster message to nodeId: " + toNodeId, e); |
... | @@ -119,7 +141,7 @@ public class ClusterCommunicationManager | ... | @@ -119,7 +141,7 @@ public class ClusterCommunicationManager |
119 | broadcast(new ClusterMessage( | 141 | broadcast(new ClusterMessage( |
120 | localNode.id(), | 142 | localNode.id(), |
121 | new MessageSubject("CLUSTER_MEMBERSHIP_EVENT"), | 143 | new MessageSubject("CLUSTER_MEMBERSHIP_EVENT"), |
122 | - new ClusterMembershipEvent(ClusterMembershipEventType.LEAVING_MEMBER, node))); | 144 | + SERIALIZER.encode(new ClusterMembershipEvent(ClusterMembershipEventType.LEAVING_MEMBER, node)))); |
123 | members.remove(node.id()); | 145 | members.remove(node.id()); |
124 | } | 146 | } |
125 | 147 | ||
... | @@ -131,7 +153,7 @@ public class ClusterCommunicationManager | ... | @@ -131,7 +153,7 @@ public class ClusterCommunicationManager |
131 | broadcast(new ClusterMessage( | 153 | broadcast(new ClusterMessage( |
132 | localNode.id(), | 154 | localNode.id(), |
133 | new MessageSubject("CLUSTER_MEMBERSHIP_EVENT"), | 155 | new MessageSubject("CLUSTER_MEMBERSHIP_EVENT"), |
134 | - new ClusterMembershipEvent(ClusterMembershipEventType.HEART_BEAT, localNode))); | 156 | + SERIALIZER.encode(new ClusterMembershipEvent(ClusterMembershipEventType.HEART_BEAT, localNode)))); |
135 | } | 157 | } |
136 | } | 158 | } |
137 | 159 | ||
... | @@ -140,7 +162,7 @@ public class ClusterCommunicationManager | ... | @@ -140,7 +162,7 @@ public class ClusterCommunicationManager |
140 | @Override | 162 | @Override |
141 | public void handle(ClusterMessage message) { | 163 | public void handle(ClusterMessage message) { |
142 | 164 | ||
143 | - ClusterMembershipEvent event = (ClusterMembershipEvent) message.payload(); | 165 | + ClusterMembershipEvent event = SERIALIZER.decode(message.payload()); |
144 | ControllerNode node = event.node(); | 166 | ControllerNode node = event.node(); |
145 | if (event.type() == ClusterMembershipEventType.HEART_BEAT) { | 167 | if (event.type() == ClusterMembershipEventType.HEART_BEAT) { |
146 | log.info("Node {} sent a hearbeat", node.id()); | 168 | log.info("Node {} sent a hearbeat", node.id()); |
... | @@ -165,7 +187,8 @@ public class ClusterCommunicationManager | ... | @@ -165,7 +187,8 @@ public class ClusterCommunicationManager |
165 | 187 | ||
166 | @Override | 188 | @Override |
167 | public void handle(Message message) { | 189 | public void handle(Message message) { |
168 | - handler.handle((ClusterMessage) message.payload()); | 190 | + ClusterMessage clusterMessage = SERIALIZER.decode(message.payload()); |
191 | + handler.handle(clusterMessage); | ||
169 | } | 192 | } |
170 | } | 193 | } |
171 | } | 194 | } | ... | ... |
1 | -package org.onlab.onos.store.cluster.impl; | 1 | +package org.onlab.onos.store.cluster.messaging.impl; |
2 | 2 | ||
3 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
4 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; |
... | @@ -52,7 +52,7 @@ public class MessageSerializer implements SerializationService { | ... | @@ -52,7 +52,7 @@ public class MessageSerializer implements SerializationService { |
52 | 52 | ||
53 | 53 | ||
54 | @Override | 54 | @Override |
55 | - public Object decode(byte[] data) { | 55 | + public <T> T decode(byte[] data) { |
56 | return serializerPool.deserialize(data); | 56 | return serializerPool.deserialize(data); |
57 | } | 57 | } |
58 | 58 | ... | ... |
... | @@ -8,7 +8,7 @@ import org.onlab.onos.cluster.NodeId; | ... | @@ -8,7 +8,7 @@ import org.onlab.onos.cluster.NodeId; |
8 | import org.onlab.onos.net.Device; | 8 | import org.onlab.onos.net.Device; |
9 | import org.onlab.onos.net.DeviceId; | 9 | import org.onlab.onos.net.DeviceId; |
10 | import org.onlab.onos.store.Timestamp; | 10 | import org.onlab.onos.store.Timestamp; |
11 | -import org.onlab.onos.store.cluster.messaging.AntiEntropyAdvertisement; | 11 | +import org.onlab.onos.store.common.impl.AntiEntropyAdvertisement; |
12 | 12 | ||
13 | // TODO DeviceID needs to be changed to something like (ProviderID, DeviceID) | 13 | // TODO DeviceID needs to be changed to something like (ProviderID, DeviceID) |
14 | // TODO: Handle Port as part of these messages, or separate messages for Ports? | 14 | // TODO: Handle Port as part of these messages, or separate messages for Ports? | ... | ... |
... | @@ -10,7 +10,7 @@ import org.onlab.onos.cluster.NodeId; | ... | @@ -10,7 +10,7 @@ import org.onlab.onos.cluster.NodeId; |
10 | import org.onlab.onos.net.Device; | 10 | import org.onlab.onos.net.Device; |
11 | import org.onlab.onos.net.DeviceId; | 11 | import org.onlab.onos.net.DeviceId; |
12 | import org.onlab.onos.store.Timestamp; | 12 | import org.onlab.onos.store.Timestamp; |
13 | -import org.onlab.onos.store.cluster.messaging.AntiEntropyReply; | 13 | +import org.onlab.onos.store.common.impl.AntiEntropyReply; |
14 | 14 | ||
15 | import com.google.common.collect.ImmutableMap; | 15 | import com.google.common.collect.ImmutableMap; |
16 | import com.google.common.collect.ImmutableSet; | 16 | import com.google.common.collect.ImmutableSet; | ... | ... |
... | @@ -4,6 +4,7 @@ import com.google.common.collect.FluentIterable; | ... | @@ -4,6 +4,7 @@ import com.google.common.collect.FluentIterable; |
4 | import com.google.common.collect.ImmutableList; | 4 | import com.google.common.collect.ImmutableList; |
5 | import com.google.common.collect.Maps; | 5 | import com.google.common.collect.Maps; |
6 | import com.google.common.collect.Sets; | 6 | import com.google.common.collect.Sets; |
7 | + | ||
7 | import org.apache.commons.lang3.concurrent.ConcurrentException; | 8 | import org.apache.commons.lang3.concurrent.ConcurrentException; |
8 | import org.apache.commons.lang3.concurrent.ConcurrentInitializer; | 9 | import org.apache.commons.lang3.concurrent.ConcurrentInitializer; |
9 | import org.apache.felix.scr.annotations.Activate; | 10 | import org.apache.felix.scr.annotations.Activate; |
... | @@ -12,6 +13,7 @@ import org.apache.felix.scr.annotations.Deactivate; | ... | @@ -12,6 +13,7 @@ import org.apache.felix.scr.annotations.Deactivate; |
12 | import org.apache.felix.scr.annotations.Reference; | 13 | import org.apache.felix.scr.annotations.Reference; |
13 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 14 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
14 | import org.apache.felix.scr.annotations.Service; | 15 | import org.apache.felix.scr.annotations.Service; |
16 | +import org.onlab.onos.cluster.ClusterService; | ||
15 | import org.onlab.onos.net.AnnotationsUtil; | 17 | import org.onlab.onos.net.AnnotationsUtil; |
16 | import org.onlab.onos.net.DefaultAnnotations; | 18 | import org.onlab.onos.net.DefaultAnnotations; |
17 | import org.onlab.onos.net.DefaultDevice; | 19 | import org.onlab.onos.net.DefaultDevice; |
... | @@ -33,10 +35,18 @@ import org.onlab.onos.net.provider.ProviderId; | ... | @@ -33,10 +35,18 @@ import org.onlab.onos.net.provider.ProviderId; |
33 | import org.onlab.onos.store.AbstractStore; | 35 | import org.onlab.onos.store.AbstractStore; |
34 | import org.onlab.onos.store.ClockService; | 36 | import org.onlab.onos.store.ClockService; |
35 | import org.onlab.onos.store.Timestamp; | 37 | import org.onlab.onos.store.Timestamp; |
38 | +import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; | ||
39 | +import org.onlab.onos.store.cluster.messaging.ClusterMessage; | ||
40 | +import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; | ||
41 | +import org.onlab.onos.store.common.impl.MastershipBasedTimestamp; | ||
36 | import org.onlab.onos.store.common.impl.Timestamped; | 42 | import org.onlab.onos.store.common.impl.Timestamped; |
43 | +import org.onlab.onos.store.serializers.KryoPoolUtil; | ||
44 | +import org.onlab.onos.store.serializers.KryoSerializer; | ||
45 | +import org.onlab.util.KryoPool; | ||
37 | import org.onlab.util.NewConcurrentHashMap; | 46 | import org.onlab.util.NewConcurrentHashMap; |
38 | import org.slf4j.Logger; | 47 | import org.slf4j.Logger; |
39 | 48 | ||
49 | +import java.io.IOException; | ||
40 | import java.util.ArrayList; | 50 | import java.util.ArrayList; |
41 | import java.util.Collections; | 51 | import java.util.Collections; |
42 | import java.util.HashSet; | 52 | import java.util.HashSet; |
... | @@ -96,8 +106,35 @@ public class GossipDeviceStore | ... | @@ -96,8 +106,35 @@ public class GossipDeviceStore |
96 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 106 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
97 | protected ClockService clockService; | 107 | protected ClockService clockService; |
98 | 108 | ||
109 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
110 | + protected ClusterCommunicationService clusterCommunicator; | ||
111 | + | ||
112 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
113 | + protected ClusterService clusterService; | ||
114 | + | ||
115 | + private static final KryoSerializer SERIALIZER = new KryoSerializer() { | ||
116 | + protected void setupKryoPool() { | ||
117 | + serializerPool = KryoPool.newBuilder() | ||
118 | + .register(KryoPoolUtil.API) | ||
119 | + .register(InternalDeviceEvent.class) | ||
120 | + .register(InternalPortEvent.class) | ||
121 | + .register(InternalPortStatusEvent.class) | ||
122 | + .register(Timestamped.class) | ||
123 | + .register(MastershipBasedTimestamp.class) | ||
124 | + .build() | ||
125 | + .populate(1); | ||
126 | + } | ||
127 | + | ||
128 | + }; | ||
129 | + | ||
99 | @Activate | 130 | @Activate |
100 | public void activate() { | 131 | public void activate() { |
132 | + clusterCommunicator.addSubscriber( | ||
133 | + GossipDeviceStoreMessageSubjects.DEVICE_UPDATE, new InternalDeviceEventListener()); | ||
134 | + clusterCommunicator.addSubscriber( | ||
135 | + GossipDeviceStoreMessageSubjects.PORT_UPDATE, new InternalPortEventListener()); | ||
136 | + clusterCommunicator.addSubscriber( | ||
137 | + GossipDeviceStoreMessageSubjects.PORT_STATUS_UPDATE, new InternalPortStatusEventListener()); | ||
101 | log.info("Started"); | 138 | log.info("Started"); |
102 | } | 139 | } |
103 | 140 | ||
... | @@ -133,8 +170,14 @@ public class GossipDeviceStore | ... | @@ -133,8 +170,14 @@ public class GossipDeviceStore |
133 | final Timestamped<DeviceDescription> deltaDesc = new Timestamped<>(deviceDescription, newTimestamp); | 170 | final Timestamped<DeviceDescription> deltaDesc = new Timestamped<>(deviceDescription, newTimestamp); |
134 | DeviceEvent event = createOrUpdateDeviceInternal(providerId, deviceId, deltaDesc); | 171 | DeviceEvent event = createOrUpdateDeviceInternal(providerId, deviceId, deltaDesc); |
135 | if (event != null) { | 172 | if (event != null) { |
136 | - // FIXME: broadcast deltaDesc, UP | 173 | + log.info("Notifying peers of a device update topology event for providerId: {} and deviceId: {}", |
137 | - log.debug("broadcast deltaDesc"); | 174 | + providerId, deviceId); |
175 | + try { | ||
176 | + notifyPeers(new InternalDeviceEvent(providerId, deviceId, deltaDesc)); | ||
177 | + } catch (IOException e) { | ||
178 | + log.error("Failed to notify peers of a device update topology event or providerId: " | ||
179 | + + providerId + " and deviceId: " + deviceId, e); | ||
180 | + } | ||
138 | } | 181 | } |
139 | return event; | 182 | return event; |
140 | } | 183 | } |
... | @@ -298,19 +341,21 @@ public class GossipDeviceStore | ... | @@ -298,19 +341,21 @@ public class GossipDeviceStore |
298 | List<PortDescription> portDescriptions) { | 341 | List<PortDescription> portDescriptions) { |
299 | Timestamp newTimestamp = clockService.getTimestamp(deviceId); | 342 | Timestamp newTimestamp = clockService.getTimestamp(deviceId); |
300 | 343 | ||
301 | - List<Timestamped<PortDescription>> deltaDescs = new ArrayList<>(portDescriptions.size()); | 344 | + Timestamped<List<PortDescription>> timestampedPortDescriptions = |
302 | - for (PortDescription e : portDescriptions) { | 345 | + new Timestamped<>(portDescriptions, newTimestamp); |
303 | - deltaDescs.add(new Timestamped<PortDescription>(e, newTimestamp)); | ||
304 | - } | ||
305 | 346 | ||
306 | - List<DeviceEvent> events = updatePortsInternal(providerId, deviceId, | 347 | + List<DeviceEvent> events = updatePortsInternal(providerId, deviceId, timestampedPortDescriptions); |
307 | - new Timestamped<>(portDescriptions, newTimestamp)); | ||
308 | if (!events.isEmpty()) { | 348 | if (!events.isEmpty()) { |
309 | - // FIXME: broadcast deltaDesc, UP | 349 | + log.info("Notifying peers of a port update topology event for providerId: {} and deviceId: {}", |
310 | - log.debug("broadcast deltaDesc"); | 350 | + providerId, deviceId); |
351 | + try { | ||
352 | + notifyPeers(new InternalPortEvent(providerId, deviceId, timestampedPortDescriptions)); | ||
353 | + } catch (IOException e) { | ||
354 | + log.error("Failed to notify peers of a port update topology event or providerId: " | ||
355 | + + providerId + " and deviceId: " + deviceId, e); | ||
356 | + } | ||
311 | } | 357 | } |
312 | return events; | 358 | return events; |
313 | - | ||
314 | } | 359 | } |
315 | 360 | ||
316 | private List<DeviceEvent> updatePortsInternal(ProviderId providerId, | 361 | private List<DeviceEvent> updatePortsInternal(ProviderId providerId, |
... | @@ -437,8 +482,14 @@ public class GossipDeviceStore | ... | @@ -437,8 +482,14 @@ public class GossipDeviceStore |
437 | final Timestamped<PortDescription> deltaDesc = new Timestamped<>(portDescription, newTimestamp); | 482 | final Timestamped<PortDescription> deltaDesc = new Timestamped<>(portDescription, newTimestamp); |
438 | DeviceEvent event = updatePortStatusInternal(providerId, deviceId, deltaDesc); | 483 | DeviceEvent event = updatePortStatusInternal(providerId, deviceId, deltaDesc); |
439 | if (event != null) { | 484 | if (event != null) { |
440 | - // FIXME: broadcast deltaDesc | 485 | + log.info("Notifying peers of a port status update topology event for providerId: {} and deviceId: {}", |
441 | - log.debug("broadcast deltaDesc"); | 486 | + providerId, deviceId); |
487 | + try { | ||
488 | + notifyPeers(new InternalPortStatusEvent(providerId, deviceId, deltaDesc)); | ||
489 | + } catch (IOException e) { | ||
490 | + log.error("Failed to notify peers of a port status update topology event or providerId: " | ||
491 | + + providerId + " and deviceId: " + deviceId, e); | ||
492 | + } | ||
442 | } | 493 | } |
443 | return event; | 494 | return event; |
444 | } | 495 | } |
... | @@ -749,4 +800,70 @@ public class GossipDeviceStore | ... | @@ -749,4 +800,70 @@ public class GossipDeviceStore |
749 | return portDescs.put(newOne.value().portNumber(), newOne); | 800 | return portDescs.put(newOne.value().portNumber(), newOne); |
750 | } | 801 | } |
751 | } | 802 | } |
803 | + | ||
804 | + private void notifyPeers(InternalDeviceEvent event) throws IOException { | ||
805 | + ClusterMessage message = new ClusterMessage( | ||
806 | + clusterService.getLocalNode().id(), | ||
807 | + GossipDeviceStoreMessageSubjects.DEVICE_UPDATE, | ||
808 | + SERIALIZER.encode(event)); | ||
809 | + clusterCommunicator.broadcast(message); | ||
810 | + } | ||
811 | + | ||
812 | + private void notifyPeers(InternalPortEvent event) throws IOException { | ||
813 | + ClusterMessage message = new ClusterMessage( | ||
814 | + clusterService.getLocalNode().id(), | ||
815 | + GossipDeviceStoreMessageSubjects.PORT_UPDATE, | ||
816 | + SERIALIZER.encode(event)); | ||
817 | + clusterCommunicator.broadcast(message); | ||
818 | + } | ||
819 | + | ||
820 | + private void notifyPeers(InternalPortStatusEvent event) throws IOException { | ||
821 | + ClusterMessage message = new ClusterMessage( | ||
822 | + clusterService.getLocalNode().id(), | ||
823 | + GossipDeviceStoreMessageSubjects.PORT_STATUS_UPDATE, | ||
824 | + SERIALIZER.encode(event)); | ||
825 | + clusterCommunicator.broadcast(message); | ||
826 | + } | ||
827 | + | ||
828 | + private class InternalDeviceEventListener implements ClusterMessageHandler { | ||
829 | + @Override | ||
830 | + public void handle(ClusterMessage message) { | ||
831 | + log.info("Received device update event from peer: {}", message.sender()); | ||
832 | + InternalDeviceEvent event = (InternalDeviceEvent) SERIALIZER.decode(message.payload()); | ||
833 | + ProviderId providerId = event.providerId(); | ||
834 | + DeviceId deviceId = event.deviceId(); | ||
835 | + Timestamped<DeviceDescription> deviceDescription = event.deviceDescription(); | ||
836 | + createOrUpdateDeviceInternal(providerId, deviceId, deviceDescription); | ||
837 | + } | ||
838 | + } | ||
839 | + | ||
840 | + private class InternalPortEventListener implements ClusterMessageHandler { | ||
841 | + @Override | ||
842 | + public void handle(ClusterMessage message) { | ||
843 | + | ||
844 | + log.info("Received port update event from peer: {}", message.sender()); | ||
845 | + InternalPortEvent event = (InternalPortEvent) SERIALIZER.decode(message.payload()); | ||
846 | + | ||
847 | + ProviderId providerId = event.providerId(); | ||
848 | + DeviceId deviceId = event.deviceId(); | ||
849 | + Timestamped<List<PortDescription>> portDescriptions = event.portDescriptions(); | ||
850 | + | ||
851 | + updatePortsInternal(providerId, deviceId, portDescriptions); | ||
852 | + } | ||
853 | + } | ||
854 | + | ||
855 | + private class InternalPortStatusEventListener implements ClusterMessageHandler { | ||
856 | + @Override | ||
857 | + public void handle(ClusterMessage message) { | ||
858 | + | ||
859 | + log.info("Received port status update event from peer: {}", message.sender()); | ||
860 | + InternalPortStatusEvent event = (InternalPortStatusEvent) SERIALIZER.decode(message.payload()); | ||
861 | + | ||
862 | + ProviderId providerId = event.providerId(); | ||
863 | + DeviceId deviceId = event.deviceId(); | ||
864 | + Timestamped<PortDescription> portDescription = event.portDescription(); | ||
865 | + | ||
866 | + updatePortStatusInternal(providerId, deviceId, portDescription); | ||
867 | + } | ||
868 | + } | ||
752 | } | 869 | } | ... | ... |
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStoreMessageSubjects.java
0 → 100644
1 | +package org.onlab.onos.store.device.impl; | ||
2 | + | ||
3 | +import org.onlab.onos.store.cluster.messaging.MessageSubject; | ||
4 | + | ||
5 | +/** | ||
6 | + * MessageSubjects used by GossipDeviceStore. | ||
7 | + */ | ||
8 | +public final class GossipDeviceStoreMessageSubjects { | ||
9 | + | ||
10 | + private GossipDeviceStoreMessageSubjects() {} | ||
11 | + | ||
12 | + public static final MessageSubject DEVICE_UPDATE = new MessageSubject("peer-device-update"); | ||
13 | + public static final MessageSubject PORT_UPDATE = new MessageSubject("peer-port-update"); | ||
14 | + public static final MessageSubject PORT_STATUS_UPDATE = new MessageSubject("peer-port-status-update"); | ||
15 | +} |
1 | +package org.onlab.onos.store.device.impl; | ||
2 | + | ||
3 | +import org.onlab.onos.net.DeviceId; | ||
4 | +import org.onlab.onos.net.device.DeviceDescription; | ||
5 | +import org.onlab.onos.net.provider.ProviderId; | ||
6 | +import org.onlab.onos.store.common.impl.Timestamped; | ||
7 | + | ||
8 | +/** | ||
9 | + * Information published by GossipDeviceStore to notify peers of a device | ||
10 | + * change event. | ||
11 | + */ | ||
12 | +public class InternalDeviceEvent { | ||
13 | + | ||
14 | + private final ProviderId providerId; | ||
15 | + private final DeviceId deviceId; | ||
16 | + private final Timestamped<DeviceDescription> deviceDescription; | ||
17 | + | ||
18 | + protected InternalDeviceEvent( | ||
19 | + ProviderId providerId, | ||
20 | + DeviceId deviceId, | ||
21 | + Timestamped<DeviceDescription> deviceDescription) { | ||
22 | + this.providerId = providerId; | ||
23 | + this.deviceId = deviceId; | ||
24 | + this.deviceDescription = deviceDescription; | ||
25 | + } | ||
26 | + | ||
27 | + public DeviceId deviceId() { | ||
28 | + return deviceId; | ||
29 | + } | ||
30 | + | ||
31 | + public ProviderId providerId() { | ||
32 | + return providerId; | ||
33 | + } | ||
34 | + | ||
35 | + public Timestamped<DeviceDescription> deviceDescription() { | ||
36 | + return deviceDescription; | ||
37 | + } | ||
38 | +} |
1 | +package org.onlab.onos.store.device.impl; | ||
2 | + | ||
3 | +import java.util.List; | ||
4 | + | ||
5 | +import org.onlab.onos.net.DeviceId; | ||
6 | +import org.onlab.onos.net.device.PortDescription; | ||
7 | +import org.onlab.onos.net.provider.ProviderId; | ||
8 | +import org.onlab.onos.store.common.impl.Timestamped; | ||
9 | + | ||
10 | +/** | ||
11 | + * Information published by GossipDeviceStore to notify peers of a port | ||
12 | + * change event. | ||
13 | + */ | ||
14 | +public class InternalPortEvent { | ||
15 | + | ||
16 | + private final ProviderId providerId; | ||
17 | + private final DeviceId deviceId; | ||
18 | + private final Timestamped<List<PortDescription>> portDescriptions; | ||
19 | + | ||
20 | + protected InternalPortEvent( | ||
21 | + ProviderId providerId, | ||
22 | + DeviceId deviceId, | ||
23 | + Timestamped<List<PortDescription>> portDescriptions) { | ||
24 | + this.providerId = providerId; | ||
25 | + this.deviceId = deviceId; | ||
26 | + this.portDescriptions = portDescriptions; | ||
27 | + } | ||
28 | + | ||
29 | + public DeviceId deviceId() { | ||
30 | + return deviceId; | ||
31 | + } | ||
32 | + | ||
33 | + public ProviderId providerId() { | ||
34 | + return providerId; | ||
35 | + } | ||
36 | + | ||
37 | + public Timestamped<List<PortDescription>> portDescriptions() { | ||
38 | + return portDescriptions; | ||
39 | + } | ||
40 | +} |
core/store/dist/src/main/java/org/onlab/onos/store/device/impl/InternalPortStatusEvent.java
0 → 100644
1 | +package org.onlab.onos.store.device.impl; | ||
2 | + | ||
3 | +import org.onlab.onos.net.DeviceId; | ||
4 | +import org.onlab.onos.net.device.PortDescription; | ||
5 | +import org.onlab.onos.net.provider.ProviderId; | ||
6 | +import org.onlab.onos.store.common.impl.Timestamped; | ||
7 | + | ||
8 | +/** | ||
9 | + * Information published by GossipDeviceStore to notify peers of a port | ||
10 | + * status change event. | ||
11 | + */ | ||
12 | +public class InternalPortStatusEvent { | ||
13 | + | ||
14 | + private final ProviderId providerId; | ||
15 | + private final DeviceId deviceId; | ||
16 | + private final Timestamped<PortDescription> portDescription; | ||
17 | + | ||
18 | + protected InternalPortStatusEvent( | ||
19 | + ProviderId providerId, | ||
20 | + DeviceId deviceId, | ||
21 | + Timestamped<PortDescription> portDescription) { | ||
22 | + this.providerId = providerId; | ||
23 | + this.deviceId = deviceId; | ||
24 | + this.portDescription = portDescription; | ||
25 | + } | ||
26 | + | ||
27 | + public DeviceId deviceId() { | ||
28 | + return deviceId; | ||
29 | + } | ||
30 | + | ||
31 | + public ProviderId providerId() { | ||
32 | + return providerId; | ||
33 | + } | ||
34 | + | ||
35 | + public Timestamped<PortDescription> portDescription() { | ||
36 | + return portDescription; | ||
37 | + } | ||
38 | +} |
... | @@ -58,6 +58,11 @@ public class DistributedFlowRuleStore | ... | @@ -58,6 +58,11 @@ public class DistributedFlowRuleStore |
58 | 58 | ||
59 | 59 | ||
60 | @Override | 60 | @Override |
61 | + public int getFlowRuleCount() { | ||
62 | + return flowEntries.size(); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
61 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { | 66 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { |
62 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { | 67 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { |
63 | if (f.equals(rule)) { | 68 | if (f.equals(rule)) { | ... | ... |
core/store/dist/src/main/java/org/onlab/onos/store/serializers/ClusterMessageSerializer.java
0 → 100644
1 | +package org.onlab.onos.store.serializers; | ||
2 | + | ||
3 | +import org.onlab.onos.cluster.NodeId; | ||
4 | +import org.onlab.onos.store.cluster.messaging.ClusterMessage; | ||
5 | +import org.onlab.onos.store.cluster.messaging.MessageSubject; | ||
6 | + | ||
7 | +import com.esotericsoftware.kryo.Kryo; | ||
8 | +import com.esotericsoftware.kryo.Serializer; | ||
9 | +import com.esotericsoftware.kryo.io.Input; | ||
10 | +import com.esotericsoftware.kryo.io.Output; | ||
11 | + | ||
12 | +public final class ClusterMessageSerializer extends Serializer<ClusterMessage> { | ||
13 | + | ||
14 | + public ClusterMessageSerializer() { | ||
15 | + // does not accept null | ||
16 | + super(false); | ||
17 | + } | ||
18 | + | ||
19 | + @Override | ||
20 | + public void write(Kryo kryo, Output output, ClusterMessage message) { | ||
21 | + kryo.writeClassAndObject(output, message.sender()); | ||
22 | + kryo.writeClassAndObject(output, message.subject()); | ||
23 | + output.writeInt(message.payload().length); | ||
24 | + output.writeBytes(message.payload()); | ||
25 | + } | ||
26 | + | ||
27 | + @Override | ||
28 | + public ClusterMessage read(Kryo kryo, Input input, | ||
29 | + Class<ClusterMessage> type) { | ||
30 | + NodeId sender = (NodeId) kryo.readClassAndObject(input); | ||
31 | + MessageSubject subject = (MessageSubject) kryo.readClassAndObject(input); | ||
32 | + int payloadSize = input.readInt(); | ||
33 | + byte[] payload = input.readBytes(payloadSize); | ||
34 | + return new ClusterMessage(sender, subject, payload); | ||
35 | + } | ||
36 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
core/store/dist/src/test/java/org/onlab/onos/store/cluster/impl/ClusterCommunicationManagerTest.java
... | @@ -7,6 +7,7 @@ import org.junit.Test; | ... | @@ -7,6 +7,7 @@ import org.junit.Test; |
7 | import org.onlab.onos.cluster.DefaultControllerNode; | 7 | import org.onlab.onos.cluster.DefaultControllerNode; |
8 | import org.onlab.onos.cluster.NodeId; | 8 | import org.onlab.onos.cluster.NodeId; |
9 | import org.onlab.onos.store.cluster.messaging.impl.ClusterCommunicationManager; | 9 | import org.onlab.onos.store.cluster.messaging.impl.ClusterCommunicationManager; |
10 | +import org.onlab.onos.store.cluster.messaging.impl.MessageSerializer; | ||
10 | import org.onlab.netty.NettyMessagingService; | 11 | import org.onlab.netty.NettyMessagingService; |
11 | import org.onlab.packet.IpPrefix; | 12 | import org.onlab.packet.IpPrefix; |
12 | 13 | ... | ... |
... | @@ -5,6 +5,7 @@ import static org.onlab.onos.net.Device.Type.SWITCH; | ... | @@ -5,6 +5,7 @@ import static org.onlab.onos.net.Device.Type.SWITCH; |
5 | import static org.onlab.onos.net.DeviceId.deviceId; | 5 | import static org.onlab.onos.net.DeviceId.deviceId; |
6 | import static org.onlab.onos.net.device.DeviceEvent.Type.*; | 6 | import static org.onlab.onos.net.device.DeviceEvent.Type.*; |
7 | 7 | ||
8 | +import java.io.IOException; | ||
8 | import java.util.Arrays; | 9 | import java.util.Arrays; |
9 | import java.util.HashMap; | 10 | import java.util.HashMap; |
10 | import java.util.List; | 11 | import java.util.List; |
... | @@ -19,6 +20,11 @@ import org.junit.Before; | ... | @@ -19,6 +20,11 @@ import org.junit.Before; |
19 | import org.junit.BeforeClass; | 20 | import org.junit.BeforeClass; |
20 | import org.junit.Ignore; | 21 | import org.junit.Ignore; |
21 | import org.junit.Test; | 22 | import org.junit.Test; |
23 | +import org.onlab.onos.cluster.ClusterEventListener; | ||
24 | +import org.onlab.onos.cluster.ClusterService; | ||
25 | +import org.onlab.onos.cluster.ControllerNode; | ||
26 | +import org.onlab.onos.cluster.ControllerNode.State; | ||
27 | +import org.onlab.onos.cluster.DefaultControllerNode; | ||
22 | import org.onlab.onos.cluster.MastershipTerm; | 28 | import org.onlab.onos.cluster.MastershipTerm; |
23 | import org.onlab.onos.cluster.NodeId; | 29 | import org.onlab.onos.cluster.NodeId; |
24 | import org.onlab.onos.net.Annotations; | 30 | import org.onlab.onos.net.Annotations; |
... | @@ -37,6 +43,11 @@ import org.onlab.onos.net.device.DeviceStoreDelegate; | ... | @@ -37,6 +43,11 @@ import org.onlab.onos.net.device.DeviceStoreDelegate; |
37 | import org.onlab.onos.net.device.PortDescription; | 43 | import org.onlab.onos.net.device.PortDescription; |
38 | import org.onlab.onos.net.provider.ProviderId; | 44 | import org.onlab.onos.net.provider.ProviderId; |
39 | import org.onlab.onos.store.ClockService; | 45 | import org.onlab.onos.store.ClockService; |
46 | +import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; | ||
47 | +import org.onlab.onos.store.cluster.messaging.ClusterMessage; | ||
48 | +import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; | ||
49 | +import org.onlab.onos.store.cluster.messaging.MessageSubject; | ||
50 | +import org.onlab.packet.IpPrefix; | ||
40 | 51 | ||
41 | import com.google.common.collect.Iterables; | 52 | import com.google.common.collect.Iterables; |
42 | import com.google.common.collect.Sets; | 53 | import com.google.common.collect.Sets; |
... | @@ -105,7 +116,10 @@ public class GossipDeviceStoreTest { | ... | @@ -105,7 +116,10 @@ public class GossipDeviceStoreTest { |
105 | deviceClockManager.setMastershipTerm(DID1, MastershipTerm.of(MYSELF, 1)); | 116 | deviceClockManager.setMastershipTerm(DID1, MastershipTerm.of(MYSELF, 1)); |
106 | deviceClockManager.setMastershipTerm(DID2, MastershipTerm.of(MYSELF, 2)); | 117 | deviceClockManager.setMastershipTerm(DID2, MastershipTerm.of(MYSELF, 2)); |
107 | 118 | ||
108 | - gossipDeviceStore = new TestGossipDeviceStore(clockService); | 119 | + ClusterCommunicationService clusterCommunicator = new TestClusterCommunicationService(); |
120 | + ClusterService clusterService = new TestClusterService(); | ||
121 | + | ||
122 | + gossipDeviceStore = new TestGossipDeviceStore(clockService, clusterService, clusterCommunicator); | ||
109 | gossipDeviceStore.activate(); | 123 | gossipDeviceStore.activate(); |
110 | deviceStore = gossipDeviceStore; | 124 | deviceStore = gossipDeviceStore; |
111 | } | 125 | } |
... | @@ -541,8 +555,65 @@ public class GossipDeviceStoreTest { | ... | @@ -541,8 +555,65 @@ public class GossipDeviceStoreTest { |
541 | 555 | ||
542 | private static final class TestGossipDeviceStore extends GossipDeviceStore { | 556 | private static final class TestGossipDeviceStore extends GossipDeviceStore { |
543 | 557 | ||
544 | - public TestGossipDeviceStore(ClockService clockService) { | 558 | + public TestGossipDeviceStore( |
559 | + ClockService clockService, | ||
560 | + ClusterService clusterService, | ||
561 | + ClusterCommunicationService clusterCommunicator) { | ||
545 | this.clockService = clockService; | 562 | this.clockService = clockService; |
563 | + this.clusterService = clusterService; | ||
564 | + this.clusterCommunicator = clusterCommunicator; | ||
565 | + } | ||
566 | + } | ||
567 | + | ||
568 | + private static final class TestClusterCommunicationService implements ClusterCommunicationService { | ||
569 | + @Override | ||
570 | + public boolean broadcast(ClusterMessage message) throws IOException { return true; } | ||
571 | + @Override | ||
572 | + public boolean unicast(ClusterMessage message, NodeId nodeId) throws IOException { return true; } | ||
573 | + @Override | ||
574 | + public boolean multicast(ClusterMessage message, Set<NodeId> nodeIds) throws IOException { return true; } | ||
575 | + @Override | ||
576 | + public void addSubscriber(MessageSubject subject, ClusterMessageHandler subscriber) {} | ||
577 | + } | ||
578 | + | ||
579 | + private static final class TestClusterService implements ClusterService { | ||
580 | + | ||
581 | + private static final ControllerNode ONOS1 = | ||
582 | + new DefaultControllerNode(new NodeId("N1"), IpPrefix.valueOf("127.0.0.1")); | ||
583 | + private final Map<NodeId, ControllerNode> nodes = new HashMap<>(); | ||
584 | + private final Map<NodeId, ControllerNode.State> nodeStates = new HashMap<>(); | ||
585 | + | ||
586 | + public TestClusterService() { | ||
587 | + nodes.put(new NodeId("N1"), ONOS1); | ||
588 | + nodeStates.put(new NodeId("N1"), ControllerNode.State.ACTIVE); | ||
589 | + } | ||
590 | + | ||
591 | + @Override | ||
592 | + public ControllerNode getLocalNode() { | ||
593 | + return ONOS1; | ||
594 | + } | ||
595 | + | ||
596 | + @Override | ||
597 | + public Set<ControllerNode> getNodes() { | ||
598 | + return Sets.newHashSet(nodes.values()); | ||
599 | + } | ||
600 | + | ||
601 | + @Override | ||
602 | + public ControllerNode getNode(NodeId nodeId) { | ||
603 | + return nodes.get(nodeId); | ||
604 | + } | ||
605 | + | ||
606 | + @Override | ||
607 | + public State getState(NodeId nodeId) { | ||
608 | + return nodeStates.get(nodeId); | ||
609 | + } | ||
610 | + | ||
611 | + @Override | ||
612 | + public void addListener(ClusterEventListener listener) { | ||
613 | + } | ||
614 | + | ||
615 | + @Override | ||
616 | + public void removeListener(ClusterEventListener listener) { | ||
546 | } | 617 | } |
547 | } | 618 | } |
548 | } | 619 | } | ... | ... |
... | @@ -57,7 +57,7 @@ public class DistributedClusterStore | ... | @@ -57,7 +57,7 @@ public class DistributedClusterStore |
57 | 57 | ||
58 | rawNodes = theInstance.getMap("nodes"); | 58 | rawNodes = theInstance.getMap("nodes"); |
59 | OptionalCacheLoader<NodeId, DefaultControllerNode> nodeLoader | 59 | OptionalCacheLoader<NodeId, DefaultControllerNode> nodeLoader |
60 | - = new OptionalCacheLoader<>(kryoSerializationService, rawNodes); | 60 | + = new OptionalCacheLoader<>(serializer, rawNodes); |
61 | nodes = new AbsentInvalidatingLoadingCache<>(newBuilder().build(nodeLoader)); | 61 | nodes = new AbsentInvalidatingLoadingCache<>(newBuilder().build(nodeLoader)); |
62 | rawNodes.addEntryListener(new RemoteCacheEventHandler<>(nodes), true); | 62 | rawNodes.addEntryListener(new RemoteCacheEventHandler<>(nodes), true); |
63 | 63 | ... | ... |
... | @@ -52,7 +52,7 @@ implements MastershipStore { | ... | @@ -52,7 +52,7 @@ implements MastershipStore { |
52 | 52 | ||
53 | rawMasters = theInstance.getMap("masters"); | 53 | rawMasters = theInstance.getMap("masters"); |
54 | OptionalCacheLoader<DeviceId, NodeId> nodeLoader | 54 | OptionalCacheLoader<DeviceId, NodeId> nodeLoader |
55 | - = new OptionalCacheLoader<>(kryoSerializationService, rawMasters); | 55 | + = new OptionalCacheLoader<>(serializer, rawMasters); |
56 | masters = new AbsentInvalidatingLoadingCache<>(newBuilder().build(nodeLoader)); | 56 | masters = new AbsentInvalidatingLoadingCache<>(newBuilder().build(nodeLoader)); |
57 | rawMasters.addEntryListener(new RemoteMasterShipEventHandler(masters), true); | 57 | rawMasters.addEntryListener(new RemoteMasterShipEventHandler(masters), true); |
58 | 58 | ... | ... |
... | @@ -15,7 +15,8 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -15,7 +15,8 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
15 | import org.onlab.onos.event.Event; | 15 | import org.onlab.onos.event.Event; |
16 | import org.onlab.onos.store.AbstractStore; | 16 | import org.onlab.onos.store.AbstractStore; |
17 | import org.onlab.onos.store.StoreDelegate; | 17 | import org.onlab.onos.store.StoreDelegate; |
18 | -import org.onlab.onos.store.serializers.KryoSerializationService; | 18 | +import org.onlab.onos.store.serializers.KryoSerializer; |
19 | +import org.onlab.onos.store.serializers.Serializer; | ||
19 | import org.slf4j.Logger; | 20 | import org.slf4j.Logger; |
20 | 21 | ||
21 | import static com.google.common.base.Preconditions.checkNotNull; | 22 | import static com.google.common.base.Preconditions.checkNotNull; |
... | @@ -24,7 +25,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -24,7 +25,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
24 | /** | 25 | /** |
25 | * Abstraction of a distributed store based on Hazelcast. | 26 | * Abstraction of a distributed store based on Hazelcast. |
26 | */ | 27 | */ |
27 | -@Component(componentAbstract = true) | 28 | +@Component |
28 | public abstract class AbstractHazelcastStore<E extends Event, D extends StoreDelegate<E>> | 29 | public abstract class AbstractHazelcastStore<E extends Event, D extends StoreDelegate<E>> |
29 | extends AbstractStore<E, D> { | 30 | extends AbstractStore<E, D> { |
30 | 31 | ||
... | @@ -33,13 +34,13 @@ public abstract class AbstractHazelcastStore<E extends Event, D extends StoreDel | ... | @@ -33,13 +34,13 @@ public abstract class AbstractHazelcastStore<E extends Event, D extends StoreDel |
33 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 34 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
34 | protected StoreService storeService; | 35 | protected StoreService storeService; |
35 | 36 | ||
36 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 37 | + protected Serializer serializer; |
37 | - protected KryoSerializationService kryoSerializationService; | ||
38 | 38 | ||
39 | protected HazelcastInstance theInstance; | 39 | protected HazelcastInstance theInstance; |
40 | 40 | ||
41 | @Activate | 41 | @Activate |
42 | public void activate() { | 42 | public void activate() { |
43 | + serializer = new KryoSerializer(); | ||
43 | theInstance = storeService.getHazelcastInstance(); | 44 | theInstance = storeService.getHazelcastInstance(); |
44 | } | 45 | } |
45 | 46 | ||
... | @@ -50,7 +51,7 @@ public abstract class AbstractHazelcastStore<E extends Event, D extends StoreDel | ... | @@ -50,7 +51,7 @@ public abstract class AbstractHazelcastStore<E extends Event, D extends StoreDel |
50 | * @return serialized object | 51 | * @return serialized object |
51 | */ | 52 | */ |
52 | protected byte[] serialize(Object obj) { | 53 | protected byte[] serialize(Object obj) { |
53 | - return kryoSerializationService.serialize(obj); | 54 | + return serializer.encode(obj); |
54 | } | 55 | } |
55 | 56 | ||
56 | /** | 57 | /** |
... | @@ -61,7 +62,7 @@ public abstract class AbstractHazelcastStore<E extends Event, D extends StoreDel | ... | @@ -61,7 +62,7 @@ public abstract class AbstractHazelcastStore<E extends Event, D extends StoreDel |
61 | * @return deserialized object | 62 | * @return deserialized object |
62 | */ | 63 | */ |
63 | protected <T> T deserialize(byte[] bytes) { | 64 | protected <T> T deserialize(byte[] bytes) { |
64 | - return kryoSerializationService.deserialize(bytes); | 65 | + return serializer.decode(bytes); |
65 | } | 66 | } |
66 | 67 | ||
67 | 68 | ... | ... |
... | @@ -2,7 +2,7 @@ package org.onlab.onos.store.common; | ... | @@ -2,7 +2,7 @@ package org.onlab.onos.store.common; |
2 | 2 | ||
3 | import static com.google.common.base.Preconditions.checkNotNull; | 3 | import static com.google.common.base.Preconditions.checkNotNull; |
4 | 4 | ||
5 | -import org.onlab.onos.store.serializers.KryoSerializationService; | 5 | +import org.onlab.onos.store.serializers.Serializer; |
6 | 6 | ||
7 | import com.google.common.base.Optional; | 7 | import com.google.common.base.Optional; |
8 | import com.google.common.cache.CacheLoader; | 8 | import com.google.common.cache.CacheLoader; |
... | @@ -18,28 +18,28 @@ import com.hazelcast.core.IMap; | ... | @@ -18,28 +18,28 @@ import com.hazelcast.core.IMap; |
18 | public final class OptionalCacheLoader<K, V> extends | 18 | public final class OptionalCacheLoader<K, V> extends |
19 | CacheLoader<K, Optional<V>> { | 19 | CacheLoader<K, Optional<V>> { |
20 | 20 | ||
21 | - private final KryoSerializationService kryoSerializationService; | 21 | + private final Serializer serializer; |
22 | private IMap<byte[], byte[]> rawMap; | 22 | private IMap<byte[], byte[]> rawMap; |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * Constructor. | 25 | * Constructor. |
26 | * | 26 | * |
27 | - * @param kryoSerializationService to use for serialization | 27 | + * @param serializer to use for serialization |
28 | * @param rawMap underlying IMap | 28 | * @param rawMap underlying IMap |
29 | */ | 29 | */ |
30 | - public OptionalCacheLoader(KryoSerializationService kryoSerializationService, IMap<byte[], byte[]> rawMap) { | 30 | + public OptionalCacheLoader(Serializer serializer, IMap<byte[], byte[]> rawMap) { |
31 | - this.kryoSerializationService = checkNotNull(kryoSerializationService); | 31 | + this.serializer = checkNotNull(serializer); |
32 | this.rawMap = checkNotNull(rawMap); | 32 | this.rawMap = checkNotNull(rawMap); |
33 | } | 33 | } |
34 | 34 | ||
35 | @Override | 35 | @Override |
36 | public Optional<V> load(K key) throws Exception { | 36 | public Optional<V> load(K key) throws Exception { |
37 | - byte[] keyBytes = kryoSerializationService.serialize(key); | 37 | + byte[] keyBytes = serializer.encode(key); |
38 | byte[] valBytes = rawMap.get(keyBytes); | 38 | byte[] valBytes = rawMap.get(keyBytes); |
39 | if (valBytes == null) { | 39 | if (valBytes == null) { |
40 | return Optional.absent(); | 40 | return Optional.absent(); |
41 | } | 41 | } |
42 | - V dev = kryoSerializationService.deserialize(valBytes); | 42 | + V dev = serializer.decode(valBytes); |
43 | return Optional.of(dev); | 43 | return Optional.of(dev); |
44 | } | 44 | } |
45 | } | 45 | } | ... | ... |
... | @@ -88,7 +88,7 @@ public class DistributedDeviceStore | ... | @@ -88,7 +88,7 @@ public class DistributedDeviceStore |
88 | // TODO decide on Map name scheme to avoid collision | 88 | // TODO decide on Map name scheme to avoid collision |
89 | rawDevices = theInstance.getMap("devices"); | 89 | rawDevices = theInstance.getMap("devices"); |
90 | final OptionalCacheLoader<DeviceId, DefaultDevice> deviceLoader | 90 | final OptionalCacheLoader<DeviceId, DefaultDevice> deviceLoader |
91 | - = new OptionalCacheLoader<>(kryoSerializationService, rawDevices); | 91 | + = new OptionalCacheLoader<>(serializer, rawDevices); |
92 | devices = new AbsentInvalidatingLoadingCache<>(newBuilder().build(deviceLoader)); | 92 | devices = new AbsentInvalidatingLoadingCache<>(newBuilder().build(deviceLoader)); |
93 | // refresh/populate cache based on notification from other instance | 93 | // refresh/populate cache based on notification from other instance |
94 | devicesListener = rawDevices.addEntryListener(new RemoteDeviceEventHandler(devices), includeValue); | 94 | devicesListener = rawDevices.addEntryListener(new RemoteDeviceEventHandler(devices), includeValue); |
... | @@ -98,7 +98,7 @@ public class DistributedDeviceStore | ... | @@ -98,7 +98,7 @@ public class DistributedDeviceStore |
98 | 98 | ||
99 | rawDevicePorts = theInstance.getMap("devicePorts"); | 99 | rawDevicePorts = theInstance.getMap("devicePorts"); |
100 | final OptionalCacheLoader<DeviceId, Map<PortNumber, Port>> devicePortLoader | 100 | final OptionalCacheLoader<DeviceId, Map<PortNumber, Port>> devicePortLoader |
101 | - = new OptionalCacheLoader<>(kryoSerializationService, rawDevicePorts); | 101 | + = new OptionalCacheLoader<>(serializer, rawDevicePorts); |
102 | devicePorts = new AbsentInvalidatingLoadingCache<>(newBuilder().build(devicePortLoader)); | 102 | devicePorts = new AbsentInvalidatingLoadingCache<>(newBuilder().build(devicePortLoader)); |
103 | // refresh/populate cache based on notification from other instance | 103 | // refresh/populate cache based on notification from other instance |
104 | portsListener = rawDevicePorts.addEntryListener(new RemotePortEventHandler(devicePorts), includeValue); | 104 | portsListener = rawDevicePorts.addEntryListener(new RemotePortEventHandler(devicePorts), includeValue); | ... | ... |
... | @@ -58,6 +58,11 @@ public class DistributedFlowRuleStore | ... | @@ -58,6 +58,11 @@ public class DistributedFlowRuleStore |
58 | 58 | ||
59 | 59 | ||
60 | @Override | 60 | @Override |
61 | + public int getFlowRuleCount() { | ||
62 | + return flowEntries.size(); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
61 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { | 66 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { |
62 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { | 67 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { |
63 | if (f.equals(rule)) { | 68 | if (f.equals(rule)) { | ... | ... |
... | @@ -71,7 +71,7 @@ public class DistributedLinkStore | ... | @@ -71,7 +71,7 @@ public class DistributedLinkStore |
71 | // TODO decide on Map name scheme to avoid collision | 71 | // TODO decide on Map name scheme to avoid collision |
72 | rawLinks = theInstance.getMap("links"); | 72 | rawLinks = theInstance.getMap("links"); |
73 | final OptionalCacheLoader<LinkKey, DefaultLink> linkLoader | 73 | final OptionalCacheLoader<LinkKey, DefaultLink> linkLoader |
74 | - = new OptionalCacheLoader<>(kryoSerializationService, rawLinks); | 74 | + = new OptionalCacheLoader<>(serializer, rawLinks); |
75 | links = new AbsentInvalidatingLoadingCache<>(newBuilder().build(linkLoader)); | 75 | links = new AbsentInvalidatingLoadingCache<>(newBuilder().build(linkLoader)); |
76 | // refresh/populate cache based on notification from other instance | 76 | // refresh/populate cache based on notification from other instance |
77 | linksListener = rawLinks.addEntryListener(new RemoteLinkEventHandler(links), includeValue); | 77 | linksListener = rawLinks.addEntryListener(new RemoteLinkEventHandler(links), includeValue); | ... | ... |
... | @@ -36,9 +36,6 @@ import org.onlab.onos.net.provider.ProviderId; | ... | @@ -36,9 +36,6 @@ import org.onlab.onos.net.provider.ProviderId; |
36 | import org.onlab.onos.store.common.StoreManager; | 36 | import org.onlab.onos.store.common.StoreManager; |
37 | import org.onlab.onos.store.common.StoreService; | 37 | import org.onlab.onos.store.common.StoreService; |
38 | import org.onlab.onos.store.common.TestStoreManager; | 38 | import org.onlab.onos.store.common.TestStoreManager; |
39 | -import org.onlab.onos.store.serializers.KryoSerializationManager; | ||
40 | -import org.onlab.onos.store.serializers.KryoSerializationService; | ||
41 | - | ||
42 | import com.google.common.collect.Iterables; | 39 | import com.google.common.collect.Iterables; |
43 | import com.google.common.collect.Sets; | 40 | import com.google.common.collect.Sets; |
44 | import com.hazelcast.config.Config; | 41 | import com.hazelcast.config.Config; |
... | @@ -63,7 +60,6 @@ public class DistributedDeviceStoreTest { | ... | @@ -63,7 +60,6 @@ public class DistributedDeviceStoreTest { |
63 | private static final PortNumber P3 = PortNumber.portNumber(3); | 60 | private static final PortNumber P3 = PortNumber.portNumber(3); |
64 | 61 | ||
65 | private DistributedDeviceStore deviceStore; | 62 | private DistributedDeviceStore deviceStore; |
66 | - private KryoSerializationManager serializationMgr; | ||
67 | 63 | ||
68 | private StoreManager storeManager; | 64 | private StoreManager storeManager; |
69 | 65 | ||
... | @@ -85,10 +81,7 @@ public class DistributedDeviceStoreTest { | ... | @@ -85,10 +81,7 @@ public class DistributedDeviceStoreTest { |
85 | storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config)); | 81 | storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config)); |
86 | storeManager.activate(); | 82 | storeManager.activate(); |
87 | 83 | ||
88 | - serializationMgr = new KryoSerializationManager(); | 84 | + deviceStore = new TestDistributedDeviceStore(storeManager); |
89 | - serializationMgr.activate(); | ||
90 | - | ||
91 | - deviceStore = new TestDistributedDeviceStore(storeManager, serializationMgr); | ||
92 | deviceStore.activate(); | 85 | deviceStore.activate(); |
93 | } | 86 | } |
94 | 87 | ||
... | @@ -96,8 +89,6 @@ public class DistributedDeviceStoreTest { | ... | @@ -96,8 +89,6 @@ public class DistributedDeviceStoreTest { |
96 | public void tearDown() throws Exception { | 89 | public void tearDown() throws Exception { |
97 | deviceStore.deactivate(); | 90 | deviceStore.deactivate(); |
98 | 91 | ||
99 | - serializationMgr.deactivate(); | ||
100 | - | ||
101 | storeManager.deactivate(); | 92 | storeManager.deactivate(); |
102 | } | 93 | } |
103 | 94 | ||
... | @@ -392,10 +383,8 @@ public class DistributedDeviceStoreTest { | ... | @@ -392,10 +383,8 @@ public class DistributedDeviceStoreTest { |
392 | } | 383 | } |
393 | 384 | ||
394 | private class TestDistributedDeviceStore extends DistributedDeviceStore { | 385 | private class TestDistributedDeviceStore extends DistributedDeviceStore { |
395 | - public TestDistributedDeviceStore(StoreService storeService, | 386 | + public TestDistributedDeviceStore(StoreService storeService) { |
396 | - KryoSerializationService kryoSerializationService) { | ||
397 | this.storeService = storeService; | 387 | this.storeService = storeService; |
398 | - this.kryoSerializationService = kryoSerializationService; | ||
399 | } | 388 | } |
400 | } | 389 | } |
401 | } | 390 | } | ... | ... |
... | @@ -30,9 +30,6 @@ import org.onlab.onos.net.provider.ProviderId; | ... | @@ -30,9 +30,6 @@ import org.onlab.onos.net.provider.ProviderId; |
30 | import org.onlab.onos.store.common.StoreManager; | 30 | import org.onlab.onos.store.common.StoreManager; |
31 | import org.onlab.onos.store.common.StoreService; | 31 | import org.onlab.onos.store.common.StoreService; |
32 | import org.onlab.onos.store.common.TestStoreManager; | 32 | import org.onlab.onos.store.common.TestStoreManager; |
33 | -import org.onlab.onos.store.serializers.KryoSerializationManager; | ||
34 | -import org.onlab.onos.store.serializers.KryoSerializationService; | ||
35 | - | ||
36 | import com.google.common.collect.Iterables; | 33 | import com.google.common.collect.Iterables; |
37 | import com.hazelcast.config.Config; | 34 | import com.hazelcast.config.Config; |
38 | import com.hazelcast.core.Hazelcast; | 35 | import com.hazelcast.core.Hazelcast; |
... | @@ -51,7 +48,6 @@ public class DistributedLinkStoreTest { | ... | @@ -51,7 +48,6 @@ public class DistributedLinkStoreTest { |
51 | private static final PortNumber P3 = PortNumber.portNumber(3); | 48 | private static final PortNumber P3 = PortNumber.portNumber(3); |
52 | 49 | ||
53 | private StoreManager storeManager; | 50 | private StoreManager storeManager; |
54 | - private KryoSerializationManager serializationMgr; | ||
55 | 51 | ||
56 | private DistributedLinkStore linkStore; | 52 | private DistributedLinkStore linkStore; |
57 | 53 | ||
... | @@ -71,17 +67,13 @@ public class DistributedLinkStoreTest { | ... | @@ -71,17 +67,13 @@ public class DistributedLinkStoreTest { |
71 | storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config)); | 67 | storeManager = new TestStoreManager(Hazelcast.newHazelcastInstance(config)); |
72 | storeManager.activate(); | 68 | storeManager.activate(); |
73 | 69 | ||
74 | - serializationMgr = new KryoSerializationManager(); | 70 | + linkStore = new TestDistributedLinkStore(storeManager); |
75 | - serializationMgr.activate(); | ||
76 | - | ||
77 | - linkStore = new TestDistributedLinkStore(storeManager, serializationMgr); | ||
78 | linkStore.activate(); | 71 | linkStore.activate(); |
79 | } | 72 | } |
80 | 73 | ||
81 | @After | 74 | @After |
82 | public void tearDown() throws Exception { | 75 | public void tearDown() throws Exception { |
83 | linkStore.deactivate(); | 76 | linkStore.deactivate(); |
84 | - serializationMgr.deactivate(); | ||
85 | storeManager.deactivate(); | 77 | storeManager.deactivate(); |
86 | } | 78 | } |
87 | 79 | ||
... | @@ -361,10 +353,8 @@ public class DistributedLinkStoreTest { | ... | @@ -361,10 +353,8 @@ public class DistributedLinkStoreTest { |
361 | 353 | ||
362 | 354 | ||
363 | class TestDistributedLinkStore extends DistributedLinkStore { | 355 | class TestDistributedLinkStore extends DistributedLinkStore { |
364 | - TestDistributedLinkStore(StoreService storeService, | 356 | + TestDistributedLinkStore(StoreService storeService) { |
365 | - KryoSerializationService kryoSerializationService) { | ||
366 | this.storeService = storeService; | 357 | this.storeService = storeService; |
367 | - this.kryoSerializationService = kryoSerializationService; | ||
368 | } | 358 | } |
369 | } | 359 | } |
370 | } | 360 | } | ... | ... |
... | @@ -2,6 +2,7 @@ package org.onlab.onos.store.serializers; | ... | @@ -2,6 +2,7 @@ package org.onlab.onos.store.serializers; |
2 | 2 | ||
3 | import java.net.URI; | 3 | import java.net.URI; |
4 | import java.util.ArrayList; | 4 | import java.util.ArrayList; |
5 | +import java.util.Arrays; | ||
5 | import java.util.HashMap; | 6 | import java.util.HashMap; |
6 | 7 | ||
7 | import org.onlab.onos.cluster.ControllerNode; | 8 | import org.onlab.onos.cluster.ControllerNode; |
... | @@ -21,6 +22,8 @@ import org.onlab.onos.net.LinkKey; | ... | @@ -21,6 +22,8 @@ import org.onlab.onos.net.LinkKey; |
21 | import org.onlab.onos.net.MastershipRole; | 22 | import org.onlab.onos.net.MastershipRole; |
22 | import org.onlab.onos.net.Port; | 23 | import org.onlab.onos.net.Port; |
23 | import org.onlab.onos.net.PortNumber; | 24 | import org.onlab.onos.net.PortNumber; |
25 | +import org.onlab.onos.net.device.DefaultDeviceDescription; | ||
26 | +import org.onlab.onos.net.device.DefaultPortDescription; | ||
24 | import org.onlab.onos.net.provider.ProviderId; | 27 | import org.onlab.onos.net.provider.ProviderId; |
25 | import org.onlab.packet.IpAddress; | 28 | import org.onlab.packet.IpAddress; |
26 | import org.onlab.packet.IpPrefix; | 29 | import org.onlab.packet.IpPrefix; |
... | @@ -47,6 +50,7 @@ public final class KryoPoolUtil { | ... | @@ -47,6 +50,7 @@ public final class KryoPoolUtil { |
47 | .register( | 50 | .register( |
48 | // | 51 | // |
49 | ArrayList.class, | 52 | ArrayList.class, |
53 | + Arrays.asList().getClass(), | ||
50 | HashMap.class, | 54 | HashMap.class, |
51 | // | 55 | // |
52 | ControllerNode.State.class, | 56 | ControllerNode.State.class, |
... | @@ -54,8 +58,10 @@ public final class KryoPoolUtil { | ... | @@ -54,8 +58,10 @@ public final class KryoPoolUtil { |
54 | DefaultAnnotations.class, | 58 | DefaultAnnotations.class, |
55 | DefaultControllerNode.class, | 59 | DefaultControllerNode.class, |
56 | DefaultDevice.class, | 60 | DefaultDevice.class, |
61 | + DefaultDeviceDescription.class, | ||
57 | MastershipRole.class, | 62 | MastershipRole.class, |
58 | Port.class, | 63 | Port.class, |
64 | + DefaultPortDescription.class, | ||
59 | Element.class, | 65 | Element.class, |
60 | Link.Type.class | 66 | Link.Type.class |
61 | ) | 67 | ) | ... | ... |
1 | package org.onlab.onos.store.serializers; | 1 | package org.onlab.onos.store.serializers; |
2 | 2 | ||
3 | -import org.apache.felix.scr.annotations.Activate; | ||
4 | -import org.apache.felix.scr.annotations.Component; | ||
5 | -import org.apache.felix.scr.annotations.Deactivate; | ||
6 | -import org.apache.felix.scr.annotations.Service; | ||
7 | import org.onlab.util.KryoPool; | 3 | import org.onlab.util.KryoPool; |
8 | import org.slf4j.Logger; | 4 | import org.slf4j.Logger; |
9 | import org.slf4j.LoggerFactory; | 5 | import org.slf4j.LoggerFactory; |
... | @@ -11,25 +7,16 @@ import org.slf4j.LoggerFactory; | ... | @@ -11,25 +7,16 @@ import org.slf4j.LoggerFactory; |
11 | import java.nio.ByteBuffer; | 7 | import java.nio.ByteBuffer; |
12 | 8 | ||
13 | /** | 9 | /** |
14 | - * Serialization service using Kryo. | 10 | + * Serializer implementation using Kryo. |
15 | */ | 11 | */ |
16 | -@Component(immediate = true) | 12 | +public class KryoSerializer implements Serializer { |
17 | -@Service | ||
18 | -public class KryoSerializationManager implements KryoSerializationService { | ||
19 | 13 | ||
20 | private final Logger log = LoggerFactory.getLogger(getClass()); | 14 | private final Logger log = LoggerFactory.getLogger(getClass()); |
21 | - private KryoPool serializerPool; | 15 | + protected KryoPool serializerPool; |
22 | 16 | ||
23 | 17 | ||
24 | - @Activate | 18 | + public KryoSerializer() { |
25 | - public void activate() { | ||
26 | setupKryoPool(); | 19 | setupKryoPool(); |
27 | - log.info("Started"); | ||
28 | - } | ||
29 | - | ||
30 | - @Deactivate | ||
31 | - public void deactivate() { | ||
32 | - log.info("Stopped"); | ||
33 | } | 20 | } |
34 | 21 | ||
35 | /** | 22 | /** |
... | @@ -43,12 +30,12 @@ public class KryoSerializationManager implements KryoSerializationService { | ... | @@ -43,12 +30,12 @@ public class KryoSerializationManager implements KryoSerializationService { |
43 | } | 30 | } |
44 | 31 | ||
45 | @Override | 32 | @Override |
46 | - public byte[] serialize(final Object obj) { | 33 | + public byte[] encode(final Object obj) { |
47 | return serializerPool.serialize(obj); | 34 | return serializerPool.serialize(obj); |
48 | } | 35 | } |
49 | 36 | ||
50 | @Override | 37 | @Override |
51 | - public <T> T deserialize(final byte[] bytes) { | 38 | + public <T> T decode(final byte[] bytes) { |
52 | if (bytes == null) { | 39 | if (bytes == null) { |
53 | return null; | 40 | return null; |
54 | } | 41 | } |
... | @@ -56,12 +43,12 @@ public class KryoSerializationManager implements KryoSerializationService { | ... | @@ -56,12 +43,12 @@ public class KryoSerializationManager implements KryoSerializationService { |
56 | } | 43 | } |
57 | 44 | ||
58 | @Override | 45 | @Override |
59 | - public void serialize(Object obj, ByteBuffer buffer) { | 46 | + public void encode(Object obj, ByteBuffer buffer) { |
60 | serializerPool.serialize(obj, buffer); | 47 | serializerPool.serialize(obj, buffer); |
61 | } | 48 | } |
62 | 49 | ||
63 | @Override | 50 | @Override |
64 | - public <T> T deserialize(ByteBuffer buffer) { | 51 | + public <T> T decode(ByteBuffer buffer) { |
65 | return serializerPool.deserialize(buffer); | 52 | return serializerPool.deserialize(buffer); |
66 | } | 53 | } |
67 | 54 | ... | ... |
... | @@ -6,41 +6,37 @@ import java.nio.ByteBuffer; | ... | @@ -6,41 +6,37 @@ import java.nio.ByteBuffer; |
6 | /** | 6 | /** |
7 | * Service to serialize Objects into byte array. | 7 | * Service to serialize Objects into byte array. |
8 | */ | 8 | */ |
9 | -public interface KryoSerializationService { | 9 | +public interface Serializer { |
10 | 10 | ||
11 | /** | 11 | /** |
12 | - * Serializes the specified object into bytes using one of the | 12 | + * Serializes the specified object into bytes. |
13 | - * pre-registered serializers. | ||
14 | * | 13 | * |
15 | * @param obj object to be serialized | 14 | * @param obj object to be serialized |
16 | * @return serialized bytes | 15 | * @return serialized bytes |
17 | */ | 16 | */ |
18 | - public byte[] serialize(final Object obj); | 17 | + public byte[] encode(final Object obj); |
19 | 18 | ||
20 | /** | 19 | /** |
21 | - * Serializes the specified object into bytes using one of the | 20 | + * Serializes the specified object into bytes. |
22 | - * pre-registered serializers. | ||
23 | * | 21 | * |
24 | * @param obj object to be serialized | 22 | * @param obj object to be serialized |
25 | * @param buffer to write serialized bytes | 23 | * @param buffer to write serialized bytes |
26 | */ | 24 | */ |
27 | - public void serialize(final Object obj, ByteBuffer buffer); | 25 | + public void encode(final Object obj, ByteBuffer buffer); |
28 | 26 | ||
29 | /** | 27 | /** |
30 | - * Deserializes the specified bytes into an object using one of the | 28 | + * Deserializes the specified bytes into an object. |
31 | - * pre-registered serializers. | ||
32 | * | 29 | * |
33 | * @param bytes bytes to be deserialized | 30 | * @param bytes bytes to be deserialized |
34 | * @return deserialized object | 31 | * @return deserialized object |
35 | */ | 32 | */ |
36 | - public <T> T deserialize(final byte[] bytes); | 33 | + public <T> T decode(final byte[] bytes); |
37 | 34 | ||
38 | /** | 35 | /** |
39 | - * Deserializes the specified bytes into an object using one of the | 36 | + * Deserializes the specified bytes into an object. |
40 | - * pre-registered serializers. | ||
41 | * | 37 | * |
42 | * @param buffer bytes to be deserialized | 38 | * @param buffer bytes to be deserialized |
43 | * @return deserialized object | 39 | * @return deserialized object |
44 | */ | 40 | */ |
45 | - public <T> T deserialize(final ByteBuffer buffer); | 41 | + public <T> T decode(final ByteBuffer buffer); |
46 | } | 42 | } | ... | ... |
... | @@ -57,6 +57,11 @@ public class SimpleFlowRuleStore | ... | @@ -57,6 +57,11 @@ public class SimpleFlowRuleStore |
57 | 57 | ||
58 | 58 | ||
59 | @Override | 59 | @Override |
60 | + public int getFlowRuleCount() { | ||
61 | + return flowEntries.size(); | ||
62 | + } | ||
63 | + | ||
64 | + @Override | ||
60 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { | 65 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { |
61 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { | 66 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { |
62 | if (f.equals(rule)) { | 67 | if (f.equals(rule)) { |
... | @@ -98,6 +103,7 @@ public class SimpleFlowRuleStore | ... | @@ -98,6 +103,7 @@ public class SimpleFlowRuleStore |
98 | public synchronized void deleteFlowRule(FlowRule rule) { | 103 | public synchronized void deleteFlowRule(FlowRule rule) { |
99 | FlowEntry entry = getFlowEntry(rule); | 104 | FlowEntry entry = getFlowEntry(rule); |
100 | if (entry == null) { | 105 | if (entry == null) { |
106 | + //log.warn("Cannot find rule {}", rule); | ||
101 | return; | 107 | return; |
102 | } | 108 | } |
103 | entry.setState(FlowEntryState.PENDING_REMOVE); | 109 | entry.setState(FlowEntryState.PENDING_REMOVE); |
... | @@ -120,7 +126,7 @@ public class SimpleFlowRuleStore | ... | @@ -120,7 +126,7 @@ public class SimpleFlowRuleStore |
120 | return new FlowRuleEvent(Type.RULE_UPDATED, rule); | 126 | return new FlowRuleEvent(Type.RULE_UPDATED, rule); |
121 | } | 127 | } |
122 | 128 | ||
123 | - flowEntries.put(did, rule); | 129 | + //flowEntries.put(did, rule); |
124 | return null; | 130 | return null; |
125 | } | 131 | } |
126 | 132 | ... | ... |
1 | package org.onlab.onos.store.trivial.impl; | 1 | package org.onlab.onos.store.trivial.impl; |
2 | 2 | ||
3 | -import static org.onlab.onos.net.intent.IntentState.COMPILED; | 3 | +import com.google.common.collect.ImmutableSet; |
4 | -import static org.slf4j.LoggerFactory.getLogger; | ||
5 | - | ||
6 | -import java.util.HashMap; | ||
7 | -import java.util.List; | ||
8 | -import java.util.Map; | ||
9 | - | ||
10 | import org.apache.felix.scr.annotations.Activate; | 4 | import org.apache.felix.scr.annotations.Activate; |
11 | import org.apache.felix.scr.annotations.Component; | 5 | import org.apache.felix.scr.annotations.Component; |
12 | import org.apache.felix.scr.annotations.Deactivate; | 6 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -21,13 +15,18 @@ import org.onlab.onos.net.intent.IntentStoreDelegate; | ... | @@ -21,13 +15,18 @@ import org.onlab.onos.net.intent.IntentStoreDelegate; |
21 | import org.onlab.onos.store.AbstractStore; | 15 | import org.onlab.onos.store.AbstractStore; |
22 | import org.slf4j.Logger; | 16 | import org.slf4j.Logger; |
23 | 17 | ||
24 | -import com.google.common.collect.ImmutableSet; | 18 | +import java.util.HashMap; |
19 | +import java.util.List; | ||
20 | +import java.util.Map; | ||
21 | + | ||
22 | +import static org.onlab.onos.net.intent.IntentState.*; | ||
23 | +import static org.slf4j.LoggerFactory.getLogger; | ||
25 | 24 | ||
26 | @Component(immediate = true) | 25 | @Component(immediate = true) |
27 | @Service | 26 | @Service |
28 | public class SimpleIntentStore | 27 | public class SimpleIntentStore |
29 | - extends AbstractStore<IntentEvent, IntentStoreDelegate> | 28 | + extends AbstractStore<IntentEvent, IntentStoreDelegate> |
30 | - implements IntentStore { | 29 | + implements IntentStore { |
31 | 30 | ||
32 | private final Logger log = getLogger(getClass()); | 31 | private final Logger log = getLogger(getClass()); |
33 | private final Map<IntentId, Intent> intents = new HashMap<>(); | 32 | private final Map<IntentId, Intent> intents = new HashMap<>(); |
... | @@ -46,7 +45,7 @@ public class SimpleIntentStore | ... | @@ -46,7 +45,7 @@ public class SimpleIntentStore |
46 | 45 | ||
47 | @Override | 46 | @Override |
48 | public IntentEvent createIntent(Intent intent) { | 47 | public IntentEvent createIntent(Intent intent) { |
49 | - intents.put(intent.getId(), intent); | 48 | + intents.put(intent.id(), intent); |
50 | return this.setState(intent, IntentState.SUBMITTED); | 49 | return this.setState(intent, IntentState.SUBMITTED); |
51 | } | 50 | } |
52 | 51 | ||
... | @@ -54,7 +53,7 @@ public class SimpleIntentStore | ... | @@ -54,7 +53,7 @@ public class SimpleIntentStore |
54 | public IntentEvent removeIntent(IntentId intentId) { | 53 | public IntentEvent removeIntent(IntentId intentId) { |
55 | Intent intent = intents.remove(intentId); | 54 | Intent intent = intents.remove(intentId); |
56 | installable.remove(intentId); | 55 | installable.remove(intentId); |
57 | - IntentEvent event = this.setState(intent, IntentState.WITHDRAWN); | 56 | + IntentEvent event = this.setState(intent, WITHDRAWN); |
58 | states.remove(intentId); | 57 | states.remove(intentId); |
59 | return event; | 58 | return event; |
60 | } | 59 | } |
... | @@ -79,19 +78,21 @@ public class SimpleIntentStore | ... | @@ -79,19 +78,21 @@ public class SimpleIntentStore |
79 | return states.get(id); | 78 | return states.get(id); |
80 | } | 79 | } |
81 | 80 | ||
82 | - // TODO return dispatch event here... replace with state transition methods | ||
83 | @Override | 81 | @Override |
84 | - public IntentEvent setState(Intent intent, IntentState newState) { | 82 | + public IntentEvent setState(Intent intent, IntentState state) { |
85 | - IntentId id = intent.getId(); | 83 | + IntentId id = intent.id(); |
86 | - IntentState oldState = states.get(id); | 84 | + states.put(id, state); |
87 | - states.put(id, newState); | 85 | + IntentEvent.Type type = (state == SUBMITTED ? IntentEvent.Type.SUBMITTED : |
88 | - return new IntentEvent(intent, newState, oldState, System.currentTimeMillis()); | 86 | + (state == INSTALLED ? IntentEvent.Type.INSTALLED : |
87 | + (state == FAILED ? IntentEvent.Type.FAILED : | ||
88 | + state == WITHDRAWN ? IntentEvent.Type.WITHDRAWN : | ||
89 | + null))); | ||
90 | + return type == null ? null : new IntentEvent(type, intent); | ||
89 | } | 91 | } |
90 | 92 | ||
91 | @Override | 93 | @Override |
92 | - public IntentEvent addInstallableIntents(IntentId intentId, List<InstallableIntent> result) { | 94 | + public void addInstallableIntents(IntentId intentId, List<InstallableIntent> result) { |
93 | installable.put(intentId, result); | 95 | installable.put(intentId, result); |
94 | - return this.setState(intents.get(intentId), COMPILED); | ||
95 | } | 96 | } |
96 | 97 | ||
97 | @Override | 98 | @Override | ... | ... |
... | @@ -53,6 +53,8 @@ | ... | @@ -53,6 +53,8 @@ |
53 | <feature>onos-api</feature> | 53 | <feature>onos-api</feature> |
54 | <bundle>mvn:org.onlab.onos/onos-core-net/1.0.0-SNAPSHOT</bundle> | 54 | <bundle>mvn:org.onlab.onos/onos-core-net/1.0.0-SNAPSHOT</bundle> |
55 | <bundle>mvn:org.onlab.onos/onos-core-dist/1.0.0-SNAPSHOT</bundle> | 55 | <bundle>mvn:org.onlab.onos/onos-core-dist/1.0.0-SNAPSHOT</bundle> |
56 | + <bundle>mvn:org.onlab.onos/onos-core-serializers/1.0.0-SNAPSHOT</bundle> | ||
57 | + <bundle>mvn:org.onlab.onos/onlab-netty/1.0.0-SNAPSHOT</bundle> | ||
56 | </feature> | 58 | </feature> |
57 | 59 | ||
58 | <feature name="onos-core-hazelcast" version="1.0.0" | 60 | <feature name="onos-core-hazelcast" version="1.0.0" | ... | ... |
... | @@ -33,6 +33,7 @@ alias obs='onos-build-selective' | ... | @@ -33,6 +33,7 @@ alias obs='onos-build-selective' |
33 | alias op='onos-package' | 33 | alias op='onos-package' |
34 | alias ot='onos-test' | 34 | alias ot='onos-test' |
35 | alias ol='onos-log' | 35 | alias ol='onos-log' |
36 | +alias pub='onos-push-update-bundle' | ||
36 | 37 | ||
37 | # Short-hand for tailing the ONOS (karaf) log | 38 | # Short-hand for tailing the ONOS (karaf) log |
38 | alias tl='$ONOS_ROOT/tools/dev/bin/onos-local-log' | 39 | alias tl='$ONOS_ROOT/tools/dev/bin/onos-local-log' |
... | @@ -89,5 +90,5 @@ function spy { | ... | @@ -89,5 +90,5 @@ function spy { |
89 | } | 90 | } |
90 | 91 | ||
91 | function nuke { | 92 | function nuke { |
92 | - spy | cut -c7-11 | xargs kill | 93 | + spy "$@" | cut -c7-11 | xargs kill |
93 | } | 94 | } | ... | ... |
... | @@ -32,6 +32,10 @@ ssh $remote " | ... | @@ -32,6 +32,10 @@ ssh $remote " |
32 | 32 | ||
33 | # Remove any previous ON.Lab bits from ~/.m2 repo | 33 | # Remove any previous ON.Lab bits from ~/.m2 repo |
34 | rm -fr ~/.m2/repository/org/onlab | 34 | rm -fr ~/.m2/repository/org/onlab |
35 | + | ||
36 | + # Drop log level for the console | ||
37 | + echo "log4j.logger.org.apache.sshd = WARN" >> $ONOS_INSTALL_DIR/$KARAF_DIST/etc/org.ops4j.pax.logging.cfg | ||
38 | + | ||
35 | " | 39 | " |
36 | 40 | ||
37 | # Configure the ONOS installation | 41 | # Configure the ONOS installation | ... | ... |
... | @@ -15,7 +15,7 @@ name=${2:-onos-1} | ... | @@ -15,7 +15,7 @@ name=${2:-onos-1} |
15 | 15 | ||
16 | ssh $remote " | 16 | ssh $remote " |
17 | sudo perl -pi.bak -e \"s/127.0.1.1.*/127.0.1.1 $name/g\" /etc/hosts | 17 | sudo perl -pi.bak -e \"s/127.0.1.1.*/127.0.1.1 $name/g\" /etc/hosts |
18 | - sudo perl -pi.bak -e \"local \$/ = ''; s/.*/$name/g\" /etc/hostname | 18 | + sudo bash -c \"echo $name >/etc/hostname\" |
19 | sudo hostname $name | 19 | sudo hostname $name |
20 | " 2>/dev/null | 20 | " 2>/dev/null |
21 | 21 | ... | ... |
... | @@ -9,5 +9,9 @@ | ... | @@ -9,5 +9,9 @@ |
9 | remote=$ONOS_USER@${1:-$OCI} | 9 | remote=$ONOS_USER@${1:-$OCI} |
10 | 10 | ||
11 | scp -q ~/.ssh/id_rsa.pub $remote:/tmp | 11 | scp -q ~/.ssh/id_rsa.pub $remote:/tmp |
12 | -ssh $remote "cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys" | 12 | +ssh $remote " |
13 | + cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys | ||
14 | + sort -u ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.bak | ||
15 | + mv ~/.ssh/authorized_keys.bak ~/.ssh/authorized_keys | ||
16 | +" | ||
13 | ssh -n -o PasswordAuthentication=no $remote true | 17 | ssh -n -o PasswordAuthentication=no $remote true | ... | ... |
tools/test/bin/onos-push-update-bundle
0 → 100755
1 | +#!/bin/bash | ||
2 | +#------------------------------------------------------------------------------- | ||
3 | +# Pushes the specified bundle to the remote ONOS cell machines and updates it. | ||
4 | +#------------------------------------------------------------------------------- | ||
5 | + | ||
6 | +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 | ||
7 | +. $ONOS_ROOT/tools/build/envDefaults | ||
8 | + | ||
9 | +cd ~/.m2/repository | ||
10 | +jar=$(find org/onlab -type f -name '*.jar' | grep $1 | grep -v -e -tests | head -n 1) | ||
11 | + | ||
12 | +[ -z "$jar" ] && echo "No bundle $1 found for" && exit 1 | ||
13 | + | ||
14 | +bundle=$(echo $(basename $jar .jar) | sed 's/-[0-9].*//g') | ||
15 | + | ||
16 | +nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) | ||
17 | +for node in $nodes; do | ||
18 | + scp -q $jar $ONOS_USER@$node:$ONOS_INSTALL_DIR/$KARAF_DIST/system/$jar | ||
19 | + ssh $ONOS_USER@$node "ls -l $ONOS_INSTALL_DIR/$KARAF_DIST/system/$jar" | ||
20 | + ssh $ONOS_USER@$node "$ONOS_INSTALL_DIR/bin/onos \"bundle:update -f $bundle\"" 2>/dev/null | ||
21 | +done |
tools/test/topos/tower.py
0 → 100644
1 | +#!/usr/bin/env python | ||
2 | +from mininet.cli import CLI | ||
3 | +from mininet.net import Mininet | ||
4 | +from mininet.node import RemoteController, OVSKernelSwitch | ||
5 | + | ||
6 | +MAC = 12 | ||
7 | +DPID = 16 | ||
8 | + | ||
9 | +def string_to_hex(s, length): | ||
10 | + """ Convert a string like 00:00 in to hex 0x0000 format""" | ||
11 | + tmp = '{0:#x}'.format(int(s.replace(':', '').lstrip('0'),length)) | ||
12 | + return tmp | ||
13 | + | ||
14 | +def hex_to_string(h, length): | ||
15 | + """Convert a hex number from 0x0000 to 00:00 format""" | ||
16 | + tmp = h.lstrip('0x').zfill(length) | ||
17 | + tmp = ':'.join(a+b for a,b in zip(tmp[::2], tmp[1::2])) | ||
18 | + return tmp | ||
19 | + | ||
20 | +class Tower(object): | ||
21 | + """ Create a tower topology from semi-scratch in Mininet """ | ||
22 | + | ||
23 | + def __init__(self, cname='flare', cip='15.255.126.183', k=4, h=6, | ||
24 | + proto=None): | ||
25 | + """Create tower topology for mininet | ||
26 | + cname: controller name | ||
27 | + cip: controller ip | ||
28 | + k: number of leaf switches | ||
29 | + h: number of hosts perl leaf switch | ||
30 | + """ | ||
31 | + | ||
32 | + # We are creating the controller with local-loopback on purpose to avoid | ||
33 | + # having the switches connect immediately. Instead, we'll set controller | ||
34 | + # explicitly for each switch after configuring it as we want. | ||
35 | + self.flare = RemoteController(cname, '127.0.0.1', 6633) | ||
36 | + self.net = Mininet(controller=self.flare, switch = OVSKernelSwitch, | ||
37 | + build=False) | ||
38 | + | ||
39 | + self.cip = cip | ||
40 | + self.spines = [] | ||
41 | + self.leaves = [] | ||
42 | + self.hosts = [] | ||
43 | + self.proto = proto | ||
44 | + | ||
45 | + # Create the two spine switches | ||
46 | + self.spines.append(self.net.addSwitch('s1')) | ||
47 | + self.spines.append(self.net.addSwitch('s2')) | ||
48 | + | ||
49 | + # Create two links between the spine switches | ||
50 | + self.net.addLink(self.spines[0], self.spines[1]) | ||
51 | + self.net.addLink(self.spines[1], self.spines[0]) | ||
52 | + | ||
53 | + # Now create the leaf switches, their hosts and connect them together | ||
54 | + i = 1 | ||
55 | + c = 0 | ||
56 | + while i <= k: | ||
57 | + self.leaves.append(self.net.addSwitch('s1%d' % i)) | ||
58 | + for spine in self.spines: | ||
59 | + self.net.addLink(self.leaves[i-1], spine) | ||
60 | + | ||
61 | + j = 1 | ||
62 | + while j <= h: | ||
63 | + self.hosts.append(self.net.addHost('h%d%d' % (i, j))) | ||
64 | + self.net.addLink(self.hosts[c], self.leaves[i-1]) | ||
65 | + j+=1 | ||
66 | + c+=1 | ||
67 | + | ||
68 | + i+=1 | ||
69 | + | ||
70 | + def run(self): | ||
71 | + """ Runs the created network topology and launches mininet cli""" | ||
72 | + self.run_silent() | ||
73 | + CLI(self.net) | ||
74 | + self.net.stop() | ||
75 | + | ||
76 | + def run_silent(self): | ||
77 | + """ Runs silently - for unit testing """ | ||
78 | + self.net.build() | ||
79 | + | ||
80 | + # Start the switches, configure them with desired protocols and only | ||
81 | + # then set the controller | ||
82 | + for sw in self.spines: | ||
83 | + sw.start([self.flare]) | ||
84 | + if self.proto: | ||
85 | + sw.cmd('ovs-vsctl set bridge %(sw)s protocols=%(proto)s' % \ | ||
86 | + { 'sw': sw.name, 'proto': self.proto}) | ||
87 | + sw.cmdPrint('ovs-vsctl set-controller %(sw)s tcp:%(ctl)s:6633' % \ | ||
88 | + {'sw': sw.name, 'ctl': self.cip}) | ||
89 | + | ||
90 | + for sw in self.leaves: | ||
91 | + sw.start([self.flare]) | ||
92 | + sw.cmdPrint('ovs-vsctl set-controller %(sw)s tcp:%(ctl)s:6633' % \ | ||
93 | + {'sw': sw.name, 'ctl': self.cip}) | ||
94 | + | ||
95 | + def pingAll(self): | ||
96 | + """ PingAll to create flows - for unit testing """ | ||
97 | + self.net.pingAll() | ||
98 | + | ||
99 | + def stop(self): | ||
100 | + "Stops the topology. You should call this after run_silent" | ||
101 | + self.net.stop() |
... | @@ -28,8 +28,9 @@ public final class Timer { | ... | @@ -28,8 +28,9 @@ public final class Timer { |
28 | 28 | ||
29 | private static synchronized void initTimer() { | 29 | private static synchronized void initTimer() { |
30 | if (Timer.timer == null) { | 30 | if (Timer.timer == null) { |
31 | - Timer.timer = new HashedWheelTimer(); | 31 | + HashedWheelTimer hwTimer = new HashedWheelTimer(); |
32 | - Timer.timer.start(); | 32 | + hwTimer.start(); |
33 | + Timer.timer = hwTimer; | ||
33 | } | 34 | } |
34 | } | 35 | } |
35 | 36 | ... | ... |
... | @@ -8,16 +8,15 @@ import java.util.concurrent.TimeoutException; | ... | @@ -8,16 +8,15 @@ import java.util.concurrent.TimeoutException; |
8 | * This class provides a base implementation of Response, with methods to retrieve the | 8 | * This class provides a base implementation of Response, with methods to retrieve the |
9 | * result and query to see if the result is ready. The result can only be retrieved when | 9 | * result and query to see if the result is ready. The result can only be retrieved when |
10 | * it is ready and the get methods will block if the result is not ready yet. | 10 | * it is ready and the get methods will block if the result is not ready yet. |
11 | - * @param <T> type of response. | ||
12 | */ | 11 | */ |
13 | -public class AsyncResponse<T> implements Response<T> { | 12 | +public class AsyncResponse implements Response { |
14 | 13 | ||
15 | - private T value; | 14 | + private byte[] value; |
16 | private boolean done = false; | 15 | private boolean done = false; |
17 | private final long start = System.nanoTime(); | 16 | private final long start = System.nanoTime(); |
18 | 17 | ||
19 | @Override | 18 | @Override |
20 | - public T get(long timeout, TimeUnit timeUnit) throws TimeoutException { | 19 | + public byte[] get(long timeout, TimeUnit timeUnit) throws TimeoutException { |
21 | timeout = timeUnit.toNanos(timeout); | 20 | timeout = timeUnit.toNanos(timeout); |
22 | boolean interrupted = false; | 21 | boolean interrupted = false; |
23 | try { | 22 | try { |
... | @@ -43,7 +42,7 @@ public class AsyncResponse<T> implements Response<T> { | ... | @@ -43,7 +42,7 @@ public class AsyncResponse<T> implements Response<T> { |
43 | } | 42 | } |
44 | 43 | ||
45 | @Override | 44 | @Override |
46 | - public T get() throws InterruptedException { | 45 | + public byte[] get() throws InterruptedException { |
47 | throw new UnsupportedOperationException(); | 46 | throw new UnsupportedOperationException(); |
48 | } | 47 | } |
49 | 48 | ||
... | @@ -57,11 +56,10 @@ public class AsyncResponse<T> implements Response<T> { | ... | @@ -57,11 +56,10 @@ public class AsyncResponse<T> implements Response<T> { |
57 | * available. | 56 | * available. |
58 | * @param data response data. | 57 | * @param data response data. |
59 | */ | 58 | */ |
60 | - @SuppressWarnings("unchecked") | 59 | + public synchronized void setResponse(byte[] data) { |
61 | - public synchronized void setResponse(Object data) { | ||
62 | if (!done) { | 60 | if (!done) { |
63 | done = true; | 61 | done = true; |
64 | - value = (T) data; | 62 | + value = data; |
65 | this.notifyAll(); | 63 | this.notifyAll(); |
66 | } | 64 | } |
67 | } | 65 | } | ... | ... |
... | @@ -5,6 +5,7 @@ import java.io.IOException; | ... | @@ -5,6 +5,7 @@ import java.io.IOException; |
5 | import org.slf4j.Logger; | 5 | import org.slf4j.Logger; |
6 | import org.slf4j.LoggerFactory; | 6 | import org.slf4j.LoggerFactory; |
7 | 7 | ||
8 | +//FIXME: Should be move out to test or app | ||
8 | /** | 9 | /** |
9 | * Message handler that echos the message back to the sender. | 10 | * Message handler that echos the message back to the sender. |
10 | */ | 11 | */ | ... | ... |
1 | package org.onlab.netty; | 1 | package org.onlab.netty; |
2 | 2 | ||
3 | +import java.util.Objects; | ||
4 | + | ||
5 | +import com.google.common.base.MoreObjects; | ||
6 | + | ||
3 | /** | 7 | /** |
4 | * Representation of a TCP/UDP communication end point. | 8 | * Representation of a TCP/UDP communication end point. |
5 | */ | 9 | */ |
... | @@ -32,16 +36,15 @@ public class Endpoint { | ... | @@ -32,16 +36,15 @@ public class Endpoint { |
32 | 36 | ||
33 | @Override | 37 | @Override |
34 | public String toString() { | 38 | public String toString() { |
35 | - return "Endpoint [port=" + port + ", host=" + host + "]"; | 39 | + return MoreObjects.toStringHelper(getClass()) |
40 | + .add("port", port) | ||
41 | + .add("host", host) | ||
42 | + .toString(); | ||
36 | } | 43 | } |
37 | 44 | ||
38 | @Override | 45 | @Override |
39 | public int hashCode() { | 46 | public int hashCode() { |
40 | - final int prime = 31; | 47 | + return Objects.hash(host, port); |
41 | - int result = 1; | ||
42 | - result = prime * result + ((host == null) ? 0 : host.hashCode()); | ||
43 | - result = prime * result + port; | ||
44 | - return result; | ||
45 | } | 48 | } |
46 | 49 | ||
47 | @Override | 50 | @Override |
... | @@ -55,17 +58,8 @@ public class Endpoint { | ... | @@ -55,17 +58,8 @@ public class Endpoint { |
55 | if (getClass() != obj.getClass()) { | 58 | if (getClass() != obj.getClass()) { |
56 | return false; | 59 | return false; |
57 | } | 60 | } |
58 | - Endpoint other = (Endpoint) obj; | 61 | + Endpoint that = (Endpoint) obj; |
59 | - if (host == null) { | 62 | + return Objects.equals(this.port, that.port) && |
60 | - if (other.host != null) { | 63 | + Objects.equals(this.host, that.host); |
61 | - return false; | ||
62 | - } | ||
63 | - } else if (!host.equals(other.host)) { | ||
64 | - return false; | ||
65 | - } | ||
66 | - if (port != other.port) { | ||
67 | - return false; | ||
68 | - } | ||
69 | - return true; | ||
70 | } | 64 | } |
71 | } | 65 | } | ... | ... |
... | @@ -8,12 +8,13 @@ import java.io.IOException; | ... | @@ -8,12 +8,13 @@ import java.io.IOException; |
8 | */ | 8 | */ |
9 | public final class InternalMessage implements Message { | 9 | public final class InternalMessage implements Message { |
10 | 10 | ||
11 | + public static final String REPLY_MESSAGE_TYPE = "NETTY_MESSAGIG_REQUEST_REPLY"; | ||
12 | + | ||
11 | private long id; | 13 | private long id; |
12 | private Endpoint sender; | 14 | private Endpoint sender; |
13 | private String type; | 15 | private String type; |
14 | - private Object payload; | 16 | + private byte[] payload; |
15 | private transient NettyMessagingService messagingService; | 17 | private transient NettyMessagingService messagingService; |
16 | - public static final String REPLY_MESSAGE_TYPE = "NETTY_MESSAGIG_REQUEST_REPLY"; | ||
17 | 18 | ||
18 | // Must be created using the Builder. | 19 | // Must be created using the Builder. |
19 | private InternalMessage() {} | 20 | private InternalMessage() {} |
... | @@ -31,7 +32,7 @@ public final class InternalMessage implements Message { | ... | @@ -31,7 +32,7 @@ public final class InternalMessage implements Message { |
31 | } | 32 | } |
32 | 33 | ||
33 | @Override | 34 | @Override |
34 | - public Object payload() { | 35 | + public byte[] payload() { |
35 | return payload; | 36 | return payload; |
36 | } | 37 | } |
37 | 38 | ||
... | @@ -40,7 +41,7 @@ public final class InternalMessage implements Message { | ... | @@ -40,7 +41,7 @@ public final class InternalMessage implements Message { |
40 | } | 41 | } |
41 | 42 | ||
42 | @Override | 43 | @Override |
43 | - public void respond(Object data) throws IOException { | 44 | + public void respond(byte[] data) throws IOException { |
44 | Builder builder = new Builder(messagingService); | 45 | Builder builder = new Builder(messagingService); |
45 | InternalMessage message = builder.withId(this.id) | 46 | InternalMessage message = builder.withId(this.id) |
46 | // FIXME: Sender should be messagingService.localEp. | 47 | // FIXME: Sender should be messagingService.localEp. |
... | @@ -55,7 +56,7 @@ public final class InternalMessage implements Message { | ... | @@ -55,7 +56,7 @@ public final class InternalMessage implements Message { |
55 | /** | 56 | /** |
56 | * Builder for InternalMessages. | 57 | * Builder for InternalMessages. |
57 | */ | 58 | */ |
58 | - public static class Builder { | 59 | + public static final class Builder { |
59 | private InternalMessage message; | 60 | private InternalMessage message; |
60 | 61 | ||
61 | public Builder(NettyMessagingService messagingService) { | 62 | public Builder(NettyMessagingService messagingService) { |
... | @@ -77,7 +78,7 @@ public final class InternalMessage implements Message { | ... | @@ -77,7 +78,7 @@ public final class InternalMessage implements Message { |
77 | message.sender = sender; | 78 | message.sender = sender; |
78 | return this; | 79 | return this; |
79 | } | 80 | } |
80 | - public Builder withPayload(Object payload) { | 81 | + public Builder withPayload(byte[] payload) { |
81 | message.payload = payload; | 82 | message.payload = payload; |
82 | return this; | 83 | return this; |
83 | } | 84 | } | ... | ... |
... | @@ -6,10 +6,11 @@ import java.nio.ByteBuffer; | ... | @@ -6,10 +6,11 @@ import java.nio.ByteBuffer; |
6 | import java.util.ArrayList; | 6 | import java.util.ArrayList; |
7 | import java.util.HashMap; | 7 | import java.util.HashMap; |
8 | 8 | ||
9 | +//FIXME: Should be move out to test or app | ||
9 | /** | 10 | /** |
10 | * Kryo Serializer. | 11 | * Kryo Serializer. |
11 | */ | 12 | */ |
12 | -public class KryoSerializer implements Serializer { | 13 | +public class KryoSerializer { |
13 | 14 | ||
14 | private KryoPool serializerPool; | 15 | private KryoPool serializerPool; |
15 | 16 | ||
... | @@ -27,29 +28,26 @@ public class KryoSerializer implements Serializer { | ... | @@ -27,29 +28,26 @@ public class KryoSerializer implements Serializer { |
27 | HashMap.class, | 28 | HashMap.class, |
28 | ArrayList.class, | 29 | ArrayList.class, |
29 | InternalMessage.class, | 30 | InternalMessage.class, |
30 | - Endpoint.class | 31 | + Endpoint.class, |
32 | + byte[].class | ||
31 | ) | 33 | ) |
32 | .build() | 34 | .build() |
33 | .populate(1); | 35 | .populate(1); |
34 | } | 36 | } |
35 | 37 | ||
36 | 38 | ||
37 | - @Override | ||
38 | public <T> T decode(byte[] data) { | 39 | public <T> T decode(byte[] data) { |
39 | return serializerPool.deserialize(data); | 40 | return serializerPool.deserialize(data); |
40 | } | 41 | } |
41 | 42 | ||
42 | - @Override | ||
43 | public byte[] encode(Object payload) { | 43 | public byte[] encode(Object payload) { |
44 | return serializerPool.serialize(payload); | 44 | return serializerPool.serialize(payload); |
45 | } | 45 | } |
46 | 46 | ||
47 | - @Override | ||
48 | public <T> T decode(ByteBuffer buffer) { | 47 | public <T> T decode(ByteBuffer buffer) { |
49 | return serializerPool.deserialize(buffer); | 48 | return serializerPool.deserialize(buffer); |
50 | } | 49 | } |
51 | 50 | ||
52 | - @Override | ||
53 | public void encode(Object obj, ByteBuffer buffer) { | 51 | public void encode(Object obj, ByteBuffer buffer) { |
54 | serializerPool.serialize(obj, buffer); | 52 | serializerPool.serialize(obj, buffer); |
55 | } | 53 | } | ... | ... |
... | @@ -12,6 +12,6 @@ public class LoggingHandler implements MessageHandler { | ... | @@ -12,6 +12,6 @@ public class LoggingHandler implements MessageHandler { |
12 | 12 | ||
13 | @Override | 13 | @Override |
14 | public void handle(Message message) { | 14 | public void handle(Message message) { |
15 | - log.info("Received message. Payload: " + message.payload()); | 15 | + log.info("Received message. Payload has {} bytes", message.payload().length); |
16 | } | 16 | } |
17 | } | 17 | } | ... | ... |
... | @@ -12,12 +12,12 @@ public interface Message { | ... | @@ -12,12 +12,12 @@ public interface Message { |
12 | * Returns the payload of this message. | 12 | * Returns the payload of this message. |
13 | * @return message payload. | 13 | * @return message payload. |
14 | */ | 14 | */ |
15 | - public Object payload(); | 15 | + public byte[] payload(); |
16 | 16 | ||
17 | /** | 17 | /** |
18 | - * Sends a reply back to the sender of this messge. | 18 | + * Sends a reply back to the sender of this message. |
19 | * @param data payload of the response. | 19 | * @param data payload of the response. |
20 | * @throws IOException if there is a communication error. | 20 | * @throws IOException if there is a communication error. |
21 | */ | 21 | */ |
22 | - public void respond(Object data) throws IOException; | 22 | + public void respond(byte[] data) throws IOException; |
23 | } | 23 | } | ... | ... |
... | @@ -14,14 +14,14 @@ import java.util.List; | ... | @@ -14,14 +14,14 @@ import java.util.List; |
14 | public class MessageDecoder extends ReplayingDecoder<DecoderState> { | 14 | public class MessageDecoder extends ReplayingDecoder<DecoderState> { |
15 | 15 | ||
16 | private final NettyMessagingService messagingService; | 16 | private final NettyMessagingService messagingService; |
17 | - private final Serializer serializer; | 17 | + |
18 | + private static final KryoSerializer SERIALIZER = new KryoSerializer(); | ||
18 | 19 | ||
19 | private int contentLength; | 20 | private int contentLength; |
20 | 21 | ||
21 | - public MessageDecoder(NettyMessagingService messagingService, Serializer serializer) { | 22 | + public MessageDecoder(NettyMessagingService messagingService) { |
22 | super(DecoderState.READ_HEADER_VERSION); | 23 | super(DecoderState.READ_HEADER_VERSION); |
23 | this.messagingService = messagingService; | 24 | this.messagingService = messagingService; |
24 | - this.serializer = serializer; | ||
25 | } | 25 | } |
26 | 26 | ||
27 | @Override | 27 | @Override |
... | @@ -48,7 +48,7 @@ public class MessageDecoder extends ReplayingDecoder<DecoderState> { | ... | @@ -48,7 +48,7 @@ public class MessageDecoder extends ReplayingDecoder<DecoderState> { |
48 | checkState(serializerVersion == MessageEncoder.SERIALIZER_VERSION, "Unexpected serializer version"); | 48 | checkState(serializerVersion == MessageEncoder.SERIALIZER_VERSION, "Unexpected serializer version"); |
49 | checkpoint(DecoderState.READ_CONTENT); | 49 | checkpoint(DecoderState.READ_CONTENT); |
50 | case READ_CONTENT: | 50 | case READ_CONTENT: |
51 | - InternalMessage message = serializer.decode(buffer.readBytes(contentLength).nioBuffer()); | 51 | + InternalMessage message = SERIALIZER.decode(buffer.readBytes(contentLength).nioBuffer()); |
52 | message.setMessagingService(messagingService); | 52 | message.setMessagingService(messagingService); |
53 | out.add(message); | 53 | out.add(message); |
54 | checkpoint(DecoderState.READ_HEADER_VERSION); | 54 | checkpoint(DecoderState.READ_HEADER_VERSION); | ... | ... |
... | @@ -17,11 +17,7 @@ public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { | ... | @@ -17,11 +17,7 @@ public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { |
17 | public static final int SERIALIZER_VERSION = 1; | 17 | public static final int SERIALIZER_VERSION = 1; |
18 | 18 | ||
19 | 19 | ||
20 | - private final Serializer serializer; | 20 | + private static final KryoSerializer SERIALIZER = new KryoSerializer(); |
21 | - | ||
22 | - public MessageEncoder(Serializer serializer) { | ||
23 | - this.serializer = serializer; | ||
24 | - } | ||
25 | 21 | ||
26 | @Override | 22 | @Override |
27 | protected void encode( | 23 | protected void encode( |
... | @@ -35,12 +31,17 @@ public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { | ... | @@ -35,12 +31,17 @@ public class MessageEncoder extends MessageToByteEncoder<InternalMessage> { |
35 | // write preamble | 31 | // write preamble |
36 | out.writeBytes(PREAMBLE); | 32 | out.writeBytes(PREAMBLE); |
37 | 33 | ||
38 | - byte[] payload = serializer.encode(message); | 34 | + try { |
35 | + SERIALIZER.encode(message); | ||
36 | + } catch (Exception e) { | ||
37 | + e.printStackTrace(); | ||
38 | + } | ||
39 | + byte[] payload = SERIALIZER.encode(message); | ||
39 | 40 | ||
40 | // write payload length | 41 | // write payload length |
41 | out.writeInt(payload.length); | 42 | out.writeInt(payload.length); |
42 | 43 | ||
43 | - // write serializer version | 44 | + // write payloadSerializer version |
44 | out.writeInt(SERIALIZER_VERSION); | 45 | out.writeInt(SERIALIZER_VERSION); |
45 | 46 | ||
46 | // write payload. | 47 | // write payload. | ... | ... |
... | @@ -11,10 +11,10 @@ public interface MessagingService { | ... | @@ -11,10 +11,10 @@ public interface MessagingService { |
11 | * The message is specified using the type and payload. | 11 | * The message is specified using the type and payload. |
12 | * @param ep end point to send the message to. | 12 | * @param ep end point to send the message to. |
13 | * @param type type of message. | 13 | * @param type type of message. |
14 | - * @param payload message payload. | 14 | + * @param payload message payload bytes. |
15 | * @throws IOException | 15 | * @throws IOException |
16 | */ | 16 | */ |
17 | - public void sendAsync(Endpoint ep, String type, Object payload) throws IOException; | 17 | + public void sendAsync(Endpoint ep, String type, byte[] payload) throws IOException; |
18 | 18 | ||
19 | /** | 19 | /** |
20 | * Sends a message synchronously and waits for a response. | 20 | * Sends a message synchronously and waits for a response. |
... | @@ -24,7 +24,7 @@ public interface MessagingService { | ... | @@ -24,7 +24,7 @@ public interface MessagingService { |
24 | * @return a response future | 24 | * @return a response future |
25 | * @throws IOException | 25 | * @throws IOException |
26 | */ | 26 | */ |
27 | - public <T> Response<T> sendAndReceive(Endpoint ep, String type, Object payload) throws IOException; | 27 | + public Response sendAndReceive(Endpoint ep, String type, byte[] payload) throws IOException; |
28 | 28 | ||
29 | /** | 29 | /** |
30 | * Registers a new message handler for message type. | 30 | * Registers a new message handler for message type. |
... | @@ -38,4 +38,4 @@ public interface MessagingService { | ... | @@ -38,4 +38,4 @@ public interface MessagingService { |
38 | * @param type message type | 38 | * @param type message type |
39 | */ | 39 | */ |
40 | public void unregisterHandler(String type); | 40 | public void unregisterHandler(String type); |
41 | -} | 41 | +} |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -43,7 +43,7 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -43,7 +43,7 @@ public class NettyMessagingService implements MessagingService { |
43 | private final EventLoopGroup bossGroup = new NioEventLoopGroup(); | 43 | private final EventLoopGroup bossGroup = new NioEventLoopGroup(); |
44 | private final EventLoopGroup workerGroup = new NioEventLoopGroup(); | 44 | private final EventLoopGroup workerGroup = new NioEventLoopGroup(); |
45 | private final ConcurrentMap<String, MessageHandler> handlers = new ConcurrentHashMap<>(); | 45 | private final ConcurrentMap<String, MessageHandler> handlers = new ConcurrentHashMap<>(); |
46 | - private final Cache<Long, AsyncResponse<?>> responseFutures = CacheBuilder.newBuilder() | 46 | + private final Cache<Long, AsyncResponse> responseFutures = CacheBuilder.newBuilder() |
47 | .maximumSize(100000) | 47 | .maximumSize(100000) |
48 | .weakValues() | 48 | .weakValues() |
49 | // TODO: Once the entry expires, notify blocking threads (if any). | 49 | // TODO: Once the entry expires, notify blocking threads (if any). |
... | @@ -52,8 +52,6 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -52,8 +52,6 @@ public class NettyMessagingService implements MessagingService { |
52 | private final GenericKeyedObjectPool<Endpoint, Channel> channels | 52 | private final GenericKeyedObjectPool<Endpoint, Channel> channels |
53 | = new GenericKeyedObjectPool<Endpoint, Channel>(new OnosCommunicationChannelFactory()); | 53 | = new GenericKeyedObjectPool<Endpoint, Channel>(new OnosCommunicationChannelFactory()); |
54 | 54 | ||
55 | - protected Serializer serializer; | ||
56 | - | ||
57 | public NettyMessagingService() { | 55 | public NettyMessagingService() { |
58 | // TODO: Default port should be configurable. | 56 | // TODO: Default port should be configurable. |
59 | this(8080); | 57 | this(8080); |
... | @@ -83,7 +81,7 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -83,7 +81,7 @@ public class NettyMessagingService implements MessagingService { |
83 | } | 81 | } |
84 | 82 | ||
85 | @Override | 83 | @Override |
86 | - public void sendAsync(Endpoint ep, String type, Object payload) throws IOException { | 84 | + public void sendAsync(Endpoint ep, String type, byte[] payload) throws IOException { |
87 | InternalMessage message = new InternalMessage.Builder(this) | 85 | InternalMessage message = new InternalMessage.Builder(this) |
88 | .withId(RandomUtils.nextLong()) | 86 | .withId(RandomUtils.nextLong()) |
89 | .withSender(localEp) | 87 | .withSender(localEp) |
... | @@ -108,9 +106,9 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -108,9 +106,9 @@ public class NettyMessagingService implements MessagingService { |
108 | } | 106 | } |
109 | 107 | ||
110 | @Override | 108 | @Override |
111 | - public <T> Response<T> sendAndReceive(Endpoint ep, String type, Object payload) | 109 | + public Response sendAndReceive(Endpoint ep, String type, byte[] payload) |
112 | throws IOException { | 110 | throws IOException { |
113 | - AsyncResponse<T> futureResponse = new AsyncResponse<T>(); | 111 | + AsyncResponse futureResponse = new AsyncResponse(); |
114 | Long messageId = RandomUtils.nextLong(); | 112 | Long messageId = RandomUtils.nextLong(); |
115 | responseFutures.put(messageId, futureResponse); | 113 | responseFutures.put(messageId, futureResponse); |
116 | InternalMessage message = new InternalMessage.Builder(this) | 114 | InternalMessage message = new InternalMessage.Builder(this) |
... | @@ -133,10 +131,6 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -133,10 +131,6 @@ public class NettyMessagingService implements MessagingService { |
133 | handlers.remove(type); | 131 | handlers.remove(type); |
134 | } | 132 | } |
135 | 133 | ||
136 | - public void setSerializer(Serializer serializer) { | ||
137 | - this.serializer = serializer; | ||
138 | - } | ||
139 | - | ||
140 | private MessageHandler getMessageHandler(String type) { | 134 | private MessageHandler getMessageHandler(String type) { |
141 | return handlers.get(type); | 135 | return handlers.get(type); |
142 | } | 136 | } |
... | @@ -201,13 +195,13 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -201,13 +195,13 @@ public class NettyMessagingService implements MessagingService { |
201 | private class OnosCommunicationChannelInitializer extends ChannelInitializer<SocketChannel> { | 195 | private class OnosCommunicationChannelInitializer extends ChannelInitializer<SocketChannel> { |
202 | 196 | ||
203 | private final ChannelHandler dispatcher = new InboundMessageDispatcher(); | 197 | private final ChannelHandler dispatcher = new InboundMessageDispatcher(); |
204 | - private final ChannelHandler encoder = new MessageEncoder(serializer); | 198 | + private final ChannelHandler encoder = new MessageEncoder(); |
205 | 199 | ||
206 | @Override | 200 | @Override |
207 | protected void initChannel(SocketChannel channel) throws Exception { | 201 | protected void initChannel(SocketChannel channel) throws Exception { |
208 | channel.pipeline() | 202 | channel.pipeline() |
209 | .addLast("encoder", encoder) | 203 | .addLast("encoder", encoder) |
210 | - .addLast("decoder", new MessageDecoder(NettyMessagingService.this, serializer)) | 204 | + .addLast("decoder", new MessageDecoder(NettyMessagingService.this)) |
211 | .addLast("handler", dispatcher); | 205 | .addLast("handler", dispatcher); |
212 | } | 206 | } |
213 | } | 207 | } |
... | @@ -236,12 +230,13 @@ public class NettyMessagingService implements MessagingService { | ... | @@ -236,12 +230,13 @@ public class NettyMessagingService implements MessagingService { |
236 | String type = message.type(); | 230 | String type = message.type(); |
237 | if (type.equals(InternalMessage.REPLY_MESSAGE_TYPE)) { | 231 | if (type.equals(InternalMessage.REPLY_MESSAGE_TYPE)) { |
238 | try { | 232 | try { |
239 | - AsyncResponse<?> futureResponse = | 233 | + AsyncResponse futureResponse = |
240 | NettyMessagingService.this.responseFutures.getIfPresent(message.id()); | 234 | NettyMessagingService.this.responseFutures.getIfPresent(message.id()); |
241 | if (futureResponse != null) { | 235 | if (futureResponse != null) { |
242 | futureResponse.setResponse(message.payload()); | 236 | futureResponse.setResponse(message.payload()); |
237 | + } else { | ||
238 | + log.warn("Received a reply. But was unable to locate the request handle"); | ||
243 | } | 239 | } |
244 | - log.warn("Received a reply. But was unable to locate the request handle"); | ||
245 | } finally { | 240 | } finally { |
246 | NettyMessagingService.this.responseFutures.invalidate(message.id()); | 241 | NettyMessagingService.this.responseFutures.invalidate(message.id()); |
247 | } | 242 | } | ... | ... |
... | @@ -7,26 +7,24 @@ import java.util.concurrent.TimeoutException; | ... | @@ -7,26 +7,24 @@ import java.util.concurrent.TimeoutException; |
7 | * Response object returned when making synchronous requests. | 7 | * Response object returned when making synchronous requests. |
8 | * Can you used to check is a response is ready and/or wait for a response | 8 | * Can you used to check is a response is ready and/or wait for a response |
9 | * to become available. | 9 | * to become available. |
10 | - * | ||
11 | - * @param <T> type of response. | ||
12 | */ | 10 | */ |
13 | -public interface Response<T> { | 11 | +public interface Response { |
14 | 12 | ||
15 | /** | 13 | /** |
16 | * Gets the response waiting for a designated timeout period. | 14 | * Gets the response waiting for a designated timeout period. |
17 | * @param timeout timeout period (since request was sent out) | 15 | * @param timeout timeout period (since request was sent out) |
18 | * @param tu unit of time. | 16 | * @param tu unit of time. |
19 | - * @return response | 17 | + * @return response payload |
20 | * @throws TimeoutException if the timeout expires before the response arrives. | 18 | * @throws TimeoutException if the timeout expires before the response arrives. |
21 | */ | 19 | */ |
22 | - public T get(long timeout, TimeUnit tu) throws TimeoutException; | 20 | + public byte[] get(long timeout, TimeUnit tu) throws TimeoutException; |
23 | 21 | ||
24 | /** | 22 | /** |
25 | * Gets the response waiting for indefinite timeout period. | 23 | * Gets the response waiting for indefinite timeout period. |
26 | - * @return response | 24 | + * @return response payload |
27 | * @throws InterruptedException if the thread is interrupted before the response arrives. | 25 | * @throws InterruptedException if the thread is interrupted before the response arrives. |
28 | */ | 26 | */ |
29 | - public T get() throws InterruptedException; | 27 | + public byte[] get() throws InterruptedException; |
30 | 28 | ||
31 | /** | 29 | /** |
32 | * Checks if the response is ready without blocking. | 30 | * Checks if the response is ready without blocking. | ... | ... |
1 | -package org.onlab.netty; | ||
2 | - | ||
3 | -import java.nio.ByteBuffer; | ||
4 | - | ||
5 | -/** | ||
6 | - * Interface for encoding/decoding message payloads. | ||
7 | - */ | ||
8 | -public interface Serializer { | ||
9 | - | ||
10 | - /** | ||
11 | - * Decodes the specified byte array to a POJO. | ||
12 | - * | ||
13 | - * @param data byte array. | ||
14 | - * @return POJO | ||
15 | - */ | ||
16 | - public <T> T decode(byte[] data); | ||
17 | - | ||
18 | - /** | ||
19 | - * Encodes the specified POJO into a byte array. | ||
20 | - * | ||
21 | - * @param data POJO to be encoded | ||
22 | - * @return byte array. | ||
23 | - */ | ||
24 | - public byte[] encode(Object data); | ||
25 | - | ||
26 | - /** | ||
27 | - * Encodes the specified POJO into a byte buffer. | ||
28 | - * | ||
29 | - * @param data POJO to be encoded | ||
30 | - * @param buffer to write serialized bytes | ||
31 | - */ | ||
32 | - public void encode(final Object data, ByteBuffer buffer); | ||
33 | - | ||
34 | - /** | ||
35 | - * Decodes the specified byte buffer to a POJO. | ||
36 | - * | ||
37 | - * @param buffer bytes to be decoded | ||
38 | - * @return POJO | ||
39 | - */ | ||
40 | - public <T> T decode(final ByteBuffer buffer); | ||
41 | -} |
... | @@ -8,6 +8,7 @@ import org.onlab.metrics.MetricsManager; | ... | @@ -8,6 +8,7 @@ import org.onlab.metrics.MetricsManager; |
8 | 8 | ||
9 | import com.codahale.metrics.Timer; | 9 | import com.codahale.metrics.Timer; |
10 | 10 | ||
11 | +// FIXME: Should be move out to test or app | ||
11 | public final class SimpleClient { | 12 | public final class SimpleClient { |
12 | private SimpleClient() { | 13 | private SimpleClient() { |
13 | } | 14 | } |
... | @@ -23,7 +24,7 @@ public final class SimpleClient { | ... | @@ -23,7 +24,7 @@ public final class SimpleClient { |
23 | final int warmup = 100; | 24 | final int warmup = 100; |
24 | for (int i = 0; i < warmup; i++) { | 25 | for (int i = 0; i < warmup; i++) { |
25 | Timer.Context context = sendAsyncTimer.time(); | 26 | Timer.Context context = sendAsyncTimer.time(); |
26 | - messaging.sendAsync(new Endpoint("localhost", 8080), "simple", "Hello World"); | 27 | + messaging.sendAsync(new Endpoint("localhost", 8080), "simple", "Hello World".getBytes()); |
27 | context.stop(); | 28 | context.stop(); |
28 | } | 29 | } |
29 | metrics.registerMetric(component, feature, "AsyncTimer", sendAsyncTimer); | 30 | metrics.registerMetric(component, feature, "AsyncTimer", sendAsyncTimer); |
... | @@ -32,10 +33,10 @@ public final class SimpleClient { | ... | @@ -32,10 +33,10 @@ public final class SimpleClient { |
32 | final int iterations = 1000000; | 33 | final int iterations = 1000000; |
33 | for (int i = 0; i < iterations; i++) { | 34 | for (int i = 0; i < iterations; i++) { |
34 | Timer.Context context = sendAndReceiveTimer.time(); | 35 | Timer.Context context = sendAndReceiveTimer.time(); |
35 | - Response<String> response = messaging | 36 | + Response response = messaging |
36 | .sendAndReceive(new Endpoint("localhost", 8080), "echo", | 37 | .sendAndReceive(new Endpoint("localhost", 8080), "echo", |
37 | - "Hello World"); | 38 | + "Hello World".getBytes()); |
38 | - System.out.println("Got back:" + response.get(2, TimeUnit.SECONDS)); | 39 | + System.out.println("Got back:" + new String(response.get(2, TimeUnit.SECONDS))); |
39 | context.stop(); | 40 | context.stop(); |
40 | } | 41 | } |
41 | metrics.registerMetric(component, feature, "AsyncTimer", sendAndReceiveTimer); | 42 | metrics.registerMetric(component, feature, "AsyncTimer", sendAndReceiveTimer); |
... | @@ -44,8 +45,6 @@ public final class SimpleClient { | ... | @@ -44,8 +45,6 @@ public final class SimpleClient { |
44 | public static class TestNettyMessagingService extends NettyMessagingService { | 45 | public static class TestNettyMessagingService extends NettyMessagingService { |
45 | public TestNettyMessagingService(int port) throws Exception { | 46 | public TestNettyMessagingService(int port) throws Exception { |
46 | super(port); | 47 | super(port); |
47 | - Serializer serializer = new KryoSerializer(); | ||
48 | - this.serializer = serializer; | ||
49 | } | 48 | } |
50 | } | 49 | } |
51 | } | 50 | } | ... | ... |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment