pankaj

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 }
......
...@@ -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();
......
...@@ -11,5 +11,5 @@ public interface Intent extends BatchOperationTarget { ...@@ -11,5 +11,5 @@ public interface Intent extends BatchOperationTarget {
11 * 11 *
12 * @return intent identifier 12 * @return intent identifier
13 */ 13 */
14 - IntentId getId(); 14 + IntentId id();
15 } 15 }
......
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
......
...@@ -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 }
......
1 -package org.onlab.onos.store.cluster.messaging.impl; 1 +package org.onlab.onos.store.cluster.impl;
2 2
3 import org.onlab.onos.cluster.ControllerNode; 3 import org.onlab.onos.cluster.ControllerNode;
4 4
......
1 -package org.onlab.onos.store.cluster.messaging.impl; 1 +package org.onlab.onos.store.cluster.impl;
2 2
3 public enum ClusterMembershipEventType { 3 public enum ClusterMembershipEventType {
4 NEW_MEMBER, 4 NEW_MEMBER,
......
...@@ -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 &amp; decoding intra-cluster messages. 4 + * Service for encoding &amp; 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
......
1 -package org.onlab.onos.store.cluster.messaging; 1 +package org.onlab.onos.store.common.impl;
2 2
3 import java.util.Map; 3 import java.util.Map;
4 4
......
1 -package org.onlab.onos.store.cluster.messaging; 1 +package org.onlab.onos.store.common.impl;
2 2
3 import java.util.Map; 3 import java.util.Map;
4 import java.util.Set; 4 import java.util.Set;
......
...@@ -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 }
......
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 +}
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)) {
......
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
...@@ -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
......
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
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.