Madan Jampani

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

Showing 56 changed files with 880 additions and 230 deletions
...@@ -14,6 +14,6 @@ public class NettyLoggingHandler implements MessageHandler { ...@@ -14,6 +14,6 @@ public class NettyLoggingHandler implements MessageHandler {
14 14
15 @Override 15 @Override
16 public void handle(Message message) { 16 public void handle(Message message) {
17 - log.info("Received message. Payload has {} bytes", message.payload().length); 17 + //log.info("Received message. Payload has {} bytes", message.payload().length);
18 } 18 }
19 } 19 }
......
...@@ -10,12 +10,17 @@ import org.onlab.metrics.MetricsManager; ...@@ -10,12 +10,17 @@ import org.onlab.metrics.MetricsManager;
10 import org.onlab.netty.Endpoint; 10 import org.onlab.netty.Endpoint;
11 import org.onlab.netty.NettyMessagingService; 11 import org.onlab.netty.NettyMessagingService;
12 import org.onlab.netty.Response; 12 import org.onlab.netty.Response;
13 +import org.slf4j.Logger;
14 +import org.slf4j.LoggerFactory;
13 15
14 import com.codahale.metrics.Timer; 16 import com.codahale.metrics.Timer;
15 17
16 // FIXME: Should be move out to test or app 18 // FIXME: Should be move out to test or app
17 public final class SimpleNettyClient { 19 public final class SimpleNettyClient {
18 - private SimpleNettyClient() { 20 +
21 +private static Logger log = LoggerFactory.getLogger(SimpleNettyClient.class);
22 +
23 + private SimpleNettyClient() {
19 } 24 }
20 25
21 public static void main(String[] args) 26 public static void main(String[] args)
...@@ -29,30 +34,33 @@ public final class SimpleNettyClient { ...@@ -29,30 +34,33 @@ public final class SimpleNettyClient {
29 34
30 System.exit(0); 35 System.exit(0);
31 } 36 }
32 - public static void startStandalone(String... args) throws Exception { 37 + public static void startStandalone(String[] args) throws Exception {
33 String host = args.length > 0 ? args[0] : "localhost"; 38 String host = args.length > 0 ? args[0] : "localhost";
34 int port = args.length > 1 ? Integer.parseInt(args[1]) : 8081; 39 int port = args.length > 1 ? Integer.parseInt(args[1]) : 8081;
35 int warmup = args.length > 2 ? Integer.parseInt(args[2]) : 1000; 40 int warmup = args.length > 2 ? Integer.parseInt(args[2]) : 1000;
36 int iterations = args.length > 3 ? Integer.parseInt(args[3]) : 50 * 100000; 41 int iterations = args.length > 3 ? Integer.parseInt(args[3]) : 50 * 100000;
37 NettyMessagingService messaging = new TestNettyMessagingService(9081); 42 NettyMessagingService messaging = new TestNettyMessagingService(9081);
38 MetricsManager metrics = new MetricsManager(); 43 MetricsManager metrics = new MetricsManager();
44 + Endpoint endpoint = new Endpoint(host, port);
39 messaging.activate(); 45 messaging.activate();
40 metrics.activate(); 46 metrics.activate();
41 MetricsFeature feature = new MetricsFeature("latency"); 47 MetricsFeature feature = new MetricsFeature("latency");
42 MetricsComponent component = metrics.registerComponent("NettyMessaging"); 48 MetricsComponent component = metrics.registerComponent("NettyMessaging");
49 + log.info("connecting " + host + ":" + port + " warmup:" + warmup + " iterations:" + iterations);
43 50
44 for (int i = 0; i < warmup; i++) { 51 for (int i = 0; i < warmup; i++) {
45 - messaging.sendAsync(new Endpoint(host, port), "simple", "Hello World".getBytes()); 52 + messaging.sendAsync(endpoint, "simple", "Hello World".getBytes());
46 Response response = messaging 53 Response response = messaging
47 - .sendAndReceive(new Endpoint(host, port), "echo", 54 + .sendAndReceive(endpoint, "echo",
48 "Hello World".getBytes()); 55 "Hello World".getBytes());
49 } 56 }
50 57
58 + log.info("measuring async sender");
51 Timer sendAsyncTimer = metrics.createTimer(component, feature, "AsyncSender"); 59 Timer sendAsyncTimer = metrics.createTimer(component, feature, "AsyncSender");
52 60
53 for (int i = 0; i < iterations; i++) { 61 for (int i = 0; i < iterations; i++) {
54 Timer.Context context = sendAsyncTimer.time(); 62 Timer.Context context = sendAsyncTimer.time();
55 - messaging.sendAsync(new Endpoint(host, port), "simple", "Hello World".getBytes()); 63 + messaging.sendAsync(endpoint, "simple", "Hello World".getBytes());
56 context.stop(); 64 context.stop();
57 } 65 }
58 66
...@@ -60,11 +68,12 @@ public final class SimpleNettyClient { ...@@ -60,11 +68,12 @@ public final class SimpleNettyClient {
60 for (int i = 0; i < iterations; i++) { 68 for (int i = 0; i < iterations; i++) {
61 Timer.Context context = sendAndReceiveTimer.time(); 69 Timer.Context context = sendAndReceiveTimer.time();
62 Response response = messaging 70 Response response = messaging
63 - .sendAndReceive(new Endpoint(host, port), "echo", 71 + .sendAndReceive(endpoint, "echo",
64 "Hello World".getBytes()); 72 "Hello World".getBytes());
65 // System.out.println("Got back:" + new String(response.get(2, TimeUnit.SECONDS))); 73 // System.out.println("Got back:" + new String(response.get(2, TimeUnit.SECONDS)));
66 context.stop(); 74 context.stop();
67 } 75 }
76 + metrics.deactivate();
68 } 77 }
69 78
70 public static class TestNettyMessagingService extends NettyMessagingService { 79 public static class TestNettyMessagingService extends NettyMessagingService {
......
...@@ -16,27 +16,26 @@ public class SimpleNettyClientCommand extends AbstractShellCommand { ...@@ -16,27 +16,26 @@ public class SimpleNettyClientCommand extends AbstractShellCommand {
16 //FIXME: replace these arguments with proper ones needed for the test. 16 //FIXME: replace these arguments with proper ones needed for the test.
17 @Argument(index = 0, name = "hostname", description = "Server Hostname", 17 @Argument(index = 0, name = "hostname", description = "Server Hostname",
18 required = false, multiValued = false) 18 required = false, multiValued = false)
19 - String host = "localhost"; 19 + String hostname = "localhost";
20 20
21 - @Argument(index = 3, name = "port", description = "Port", 21 + @Argument(index = 1, name = "port", description = "Port",
22 required = false, multiValued = false) 22 required = false, multiValued = false)
23 String port = "8081"; 23 String port = "8081";
24 24
25 - @Argument(index = 1, name = "warmupCount", description = "Warm-up count", 25 + @Argument(index = 2, name = "warmupCount", description = "Warm-up count",
26 required = false, multiValued = false) 26 required = false, multiValued = false)
27 - String warmup = "1000"; 27 + String warmupCount = "1000";
28 28
29 - @Argument(index = 2, name = "messageCount", description = "Message count", 29 + @Argument(index = 3, name = "messageCount", description = "Message count",
30 required = false, multiValued = false) 30 required = false, multiValued = false)
31 - String messageCount = "5000000"; 31 + String messageCount = "100000";
32 32
33 @Override 33 @Override
34 protected void execute() { 34 protected void execute() {
35 try { 35 try {
36 - startStandalone(new String[]{host, port, warmup, messageCount}); 36 + startStandalone(new String[]{hostname, port, warmupCount, messageCount});
37 } catch (Exception e) { 37 } catch (Exception e) {
38 error("Unable to start client %s", e); 38 error("Unable to start client %s", e);
39 } 39 }
40 } 40 }
41 -
42 } 41 }
......
...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Reference; 10 import org.apache.felix.scr.annotations.Reference;
11 import org.apache.felix.scr.annotations.ReferenceCardinality; 11 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 import org.onlab.onos.ApplicationId; 12 import org.onlab.onos.ApplicationId;
13 +import org.onlab.onos.CoreService;
13 import org.onlab.onos.net.Host; 14 import org.onlab.onos.net.Host;
14 import org.onlab.onos.net.HostId; 15 import org.onlab.onos.net.HostId;
15 import org.onlab.onos.net.Path; 16 import org.onlab.onos.net.Path;
...@@ -53,13 +54,16 @@ public class ReactiveForwarding { ...@@ -53,13 +54,16 @@ public class ReactiveForwarding {
53 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 protected FlowRuleService flowRuleService; 55 protected FlowRuleService flowRuleService;
55 56
57 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 + protected CoreService coreService;
59 +
56 private ReactivePacketProcessor processor = new ReactivePacketProcessor(); 60 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
57 61
58 private ApplicationId appId; 62 private ApplicationId appId;
59 63
60 @Activate 64 @Activate
61 public void activate() { 65 public void activate() {
62 - appId = ApplicationId.getAppId(); 66 + appId = coreService.registerApplication("org.onlab.onos.fwd");
63 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); 67 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
64 log.info("Started with Application ID {}", appId.id()); 68 log.info("Started with Application ID {}", appId.id());
65 } 69 }
......
...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -10,6 +10,7 @@ import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Reference; 10 import org.apache.felix.scr.annotations.Reference;
11 import org.apache.felix.scr.annotations.ReferenceCardinality; 11 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 import org.onlab.onos.ApplicationId; 12 import org.onlab.onos.ApplicationId;
13 +import org.onlab.onos.CoreService;
13 import org.onlab.onos.net.Device; 14 import org.onlab.onos.net.Device;
14 import org.onlab.onos.net.Host; 15 import org.onlab.onos.net.Host;
15 import org.onlab.onos.net.device.DeviceService; 16 import org.onlab.onos.net.device.DeviceService;
...@@ -44,11 +45,14 @@ public class HostMobility { ...@@ -44,11 +45,14 @@ public class HostMobility {
44 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 45 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 protected DeviceService deviceService; 46 protected DeviceService deviceService;
46 47
48 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 + protected CoreService coreService;
50 +
47 private ApplicationId appId; 51 private ApplicationId appId;
48 52
49 @Activate 53 @Activate
50 public void activate() { 54 public void activate() {
51 - appId = ApplicationId.getAppId(); 55 + appId = coreService.registerApplication("org.onlab.onos.mobility");
52 hostService.addListener(new InternalHostListener()); 56 hostService.addListener(new InternalHostListener());
53 log.info("Started with Application ID {}", appId.id()); 57 log.info("Started with Application ID {}", appId.id());
54 } 58 }
......
...@@ -8,6 +8,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -8,6 +8,7 @@ import org.apache.felix.scr.annotations.Deactivate;
8 import org.apache.felix.scr.annotations.Reference; 8 import org.apache.felix.scr.annotations.Reference;
9 import org.apache.felix.scr.annotations.ReferenceCardinality; 9 import org.apache.felix.scr.annotations.ReferenceCardinality;
10 import org.onlab.onos.ApplicationId; 10 import org.onlab.onos.ApplicationId;
11 +import org.onlab.onos.CoreService;
11 import org.onlab.onos.net.packet.PacketContext; 12 import org.onlab.onos.net.packet.PacketContext;
12 import org.onlab.onos.net.packet.PacketProcessor; 13 import org.onlab.onos.net.packet.PacketProcessor;
13 import org.onlab.onos.net.packet.PacketService; 14 import org.onlab.onos.net.packet.PacketService;
...@@ -31,11 +32,14 @@ public class ProxyArp { ...@@ -31,11 +32,14 @@ public class ProxyArp {
31 32
32 private ProxyArpProcessor processor = new ProxyArpProcessor(); 33 private ProxyArpProcessor processor = new ProxyArpProcessor();
33 34
35 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
36 + protected CoreService coreService;
37 +
34 private ApplicationId appId; 38 private ApplicationId appId;
35 39
36 @Activate 40 @Activate
37 public void activate() { 41 public void activate() {
38 - appId = ApplicationId.getAppId(); 42 + appId = coreService.registerApplication("org.onlab.onos.proxyarp");
39 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1); 43 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1);
40 log.info("Started with Application ID {}", appId.id()); 44 log.info("Started with Application ID {}", appId.id());
41 } 45 }
......
...@@ -27,7 +27,7 @@ public class AddHostToHostIntentCommand extends AbstractShellCommand { ...@@ -27,7 +27,7 @@ public class AddHostToHostIntentCommand extends AbstractShellCommand {
27 required = true, multiValued = false) 27 required = true, multiValued = false)
28 String two = null; 28 String two = null;
29 29
30 - private static long id = 1; 30 + private static long id = 0x7870001;
31 31
32 @Override 32 @Override
33 protected void execute() { 33 protected void execute() {
......
...@@ -14,6 +14,7 @@ import org.onlab.onos.net.intent.Intent; ...@@ -14,6 +14,7 @@ import org.onlab.onos.net.intent.Intent;
14 import org.onlab.onos.net.intent.IntentId; 14 import org.onlab.onos.net.intent.IntentId;
15 import org.onlab.onos.net.intent.IntentService; 15 import org.onlab.onos.net.intent.IntentService;
16 import org.onlab.onos.net.intent.PointToPointIntent; 16 import org.onlab.onos.net.intent.PointToPointIntent;
17 +import org.onlab.packet.Ethernet;
17 18
18 /** 19 /**
19 * Installs point-to-point connectivity intents. 20 * Installs point-to-point connectivity intents.
...@@ -32,7 +33,7 @@ public class AddPointToPointIntentCommand extends AbstractShellCommand { ...@@ -32,7 +33,7 @@ public class AddPointToPointIntentCommand extends AbstractShellCommand {
32 required = true, multiValued = false) 33 required = true, multiValued = false)
33 String egressDeviceString = null; 34 String egressDeviceString = null;
34 35
35 - private static long id = 1; 36 + private static long id = 0x7470001;
36 37
37 @Override 38 @Override
38 protected void execute() { 39 protected void execute() {
...@@ -48,7 +49,9 @@ public class AddPointToPointIntentCommand extends AbstractShellCommand { ...@@ -48,7 +49,9 @@ public class AddPointToPointIntentCommand extends AbstractShellCommand {
48 PortNumber.portNumber(getPortNumber(egressDeviceString)); 49 PortNumber.portNumber(getPortNumber(egressDeviceString));
49 ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber); 50 ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber);
50 51
51 - TrafficSelector selector = DefaultTrafficSelector.builder().build(); 52 + TrafficSelector selector = DefaultTrafficSelector.builder()
53 + .matchEthType(Ethernet.TYPE_IPV4)
54 + .build();
52 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); 55 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
53 56
54 Intent intent = 57 Intent intent =
......
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 com.google.common.collect.Maps;
4 -import static org.onlab.onos.cli.net.DevicesListCommand.getSortedDevices;
5 -
6 -import java.util.Collections;
7 -import java.util.List;
8 -import java.util.Map;
9 -
10 import org.apache.karaf.shell.commands.Argument; 4 import org.apache.karaf.shell.commands.Argument;
11 import org.apache.karaf.shell.commands.Command; 5 import org.apache.karaf.shell.commands.Command;
6 +import org.onlab.onos.CoreService;
12 import org.onlab.onos.cli.AbstractShellCommand; 7 import org.onlab.onos.cli.AbstractShellCommand;
13 import org.onlab.onos.cli.Comparators; 8 import org.onlab.onos.cli.Comparators;
14 import org.onlab.onos.net.Device; 9 import org.onlab.onos.net.Device;
...@@ -18,37 +13,43 @@ import org.onlab.onos.net.flow.FlowEntry; ...@@ -18,37 +13,43 @@ import org.onlab.onos.net.flow.FlowEntry;
18 import org.onlab.onos.net.flow.FlowEntry.FlowEntryState; 13 import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
19 import org.onlab.onos.net.flow.FlowRuleService; 14 import org.onlab.onos.net.flow.FlowRuleService;
20 15
21 -import com.google.common.collect.Maps; 16 +import java.util.Collections;
17 +import java.util.List;
18 +import java.util.Map;
19 +
20 +import static com.google.common.collect.Lists.newArrayList;
21 +import static org.onlab.onos.cli.net.DevicesListCommand.getSortedDevices;
22 22
23 /** 23 /**
24 * Lists all currently-known hosts. 24 * Lists all currently-known hosts.
25 */ 25 */
26 @Command(scope = "onos", name = "flows", 26 @Command(scope = "onos", name = "flows",
27 -description = "Lists all currently-known flows.") 27 + description = "Lists all currently-known flows.")
28 public class FlowsListCommand extends AbstractShellCommand { 28 public class FlowsListCommand extends AbstractShellCommand {
29 29
30 public static final String ANY = "any"; 30 public static final String ANY = "any";
31 31
32 private static final String FMT = 32 private static final String FMT =
33 - " id=%s, state=%s, bytes=%s, packets=%s, duration=%s, priority=%s"; 33 + " id=%s, state=%s, bytes=%s, packets=%s, duration=%s, priority=%s, appId=%s";
34 private static final String TFMT = " treatment=%s"; 34 private static final String TFMT = " treatment=%s";
35 private static final String SFMT = " selector=%s"; 35 private static final String SFMT = " selector=%s";
36 36
37 @Argument(index = 1, name = "uri", description = "Device ID", 37 @Argument(index = 1, name = "uri", description = "Device ID",
38 - required = false, multiValued = false) 38 + required = false, multiValued = false)
39 String uri = null; 39 String uri = null;
40 40
41 @Argument(index = 0, name = "state", description = "Flow Rule state", 41 @Argument(index = 0, name = "state", description = "Flow Rule state",
42 - required = false, multiValued = false) 42 + required = false, multiValued = false)
43 String state = null; 43 String state = null;
44 44
45 @Override 45 @Override
46 protected void execute() { 46 protected void execute() {
47 + CoreService coreService = get(CoreService.class);
47 DeviceService deviceService = get(DeviceService.class); 48 DeviceService deviceService = get(DeviceService.class);
48 FlowRuleService service = get(FlowRuleService.class); 49 FlowRuleService service = get(FlowRuleService.class);
49 Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service); 50 Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service);
50 for (Device d : getSortedDevices(deviceService)) { 51 for (Device d : getSortedDevices(deviceService)) {
51 - printFlows(d, flows.get(d)); 52 + printFlows(d, flows.get(d), coreService);
52 } 53 }
53 } 54 }
54 55
...@@ -67,7 +68,7 @@ public class FlowsListCommand extends AbstractShellCommand { ...@@ -67,7 +68,7 @@ public class FlowsListCommand extends AbstractShellCommand {
67 s = FlowEntryState.valueOf(state.toUpperCase()); 68 s = FlowEntryState.valueOf(state.toUpperCase());
68 } 69 }
69 Iterable<Device> devices = uri == null ? deviceService.getDevices() : 70 Iterable<Device> devices = uri == null ? deviceService.getDevices() :
70 - Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri))); 71 + Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
71 for (Device d : devices) { 72 for (Device d : devices) {
72 if (s == null) { 73 if (s == null) {
73 rules = newArrayList(service.getFlowEntries(d.id())); 74 rules = newArrayList(service.getFlowEntries(d.id()));
...@@ -87,16 +88,19 @@ public class FlowsListCommand extends AbstractShellCommand { ...@@ -87,16 +88,19 @@ public class FlowsListCommand extends AbstractShellCommand {
87 88
88 /** 89 /**
89 * Prints flows. 90 * Prints flows.
90 - * @param d the device 91 + *
92 + * @param d the device
91 * @param flows the set of flows for that device. 93 * @param flows the set of flows for that device.
92 */ 94 */
93 - protected void printFlows(Device d, List<FlowEntry> flows) { 95 + protected void printFlows(Device d, List<FlowEntry> flows,
96 + CoreService coreService) {
94 boolean empty = flows == null || flows.isEmpty(); 97 boolean empty = flows == null || flows.isEmpty();
95 print("deviceId=%s, flowRuleCount=%d", d.id(), empty ? 0 : flows.size()); 98 print("deviceId=%s, flowRuleCount=%d", d.id(), empty ? 0 : flows.size());
96 if (!empty) { 99 if (!empty) {
97 for (FlowEntry f : flows) { 100 for (FlowEntry f : flows) {
98 - print(FMT, Long.toHexString(f.id().value()), f.state(), f.bytes(), 101 + print(FMT, Long.toHexString(f.id().value()), f.state(),
99 - f.packets(), f.life(), f.priority()); 102 + f.bytes(), f.packets(), f.life(), f.priority(),
103 + coreService.getAppId(f.appId()).name());
100 print(SFMT, f.selector().criteria()); 104 print(SFMT, f.selector().criteria());
101 print(TFMT, f.treatment().instructions()); 105 print(TFMT, f.treatment().instructions());
102 } 106 }
......
1 package org.onlab.onos; 1 package org.onlab.onos;
2 2
3 -import java.util.Objects;
4 -import java.util.concurrent.atomic.AtomicInteger;
5 3
6 /** 4 /**
7 - * Application id generator class. 5 + * Application identifier.
8 */ 6 */
9 -public final class ApplicationId { 7 +public interface ApplicationId {
10 8
11 - private static final AtomicInteger ID_DISPENCER = new AtomicInteger(1); 9 + /**
12 - private final Integer id; 10 + * Returns the application id.
13 - 11 + * @return a short value
14 - // Ban public construction 12 + */
15 - private ApplicationId(Integer id) { 13 + short id();
16 - this.id = id;
17 - }
18 -
19 - public Integer id() {
20 - return id;
21 - }
22 -
23 - public static ApplicationId valueOf(Integer id) {
24 - return new ApplicationId(id);
25 - }
26 -
27 - @Override
28 - public int hashCode() {
29 - return Objects.hash(id);
30 - }
31 -
32 - @Override
33 - public boolean equals(Object obj) {
34 - if (this == obj) {
35 - return true;
36 - }
37 - if (obj == null) {
38 - return false;
39 - }
40 - if (!(obj instanceof ApplicationId)) {
41 - return false;
42 - }
43 - ApplicationId other = (ApplicationId) obj;
44 - return Objects.equals(this.id, other.id);
45 - }
46 14
47 /** 15 /**
48 - * Returns a new application id. 16 + * Returns the applications supplied identifier.
49 - * 17 + * @return a string identifier
50 - * @return app id
51 */ 18 */
52 - public static ApplicationId getAppId() { 19 + String name();
53 - return new ApplicationId(ApplicationId.ID_DISPENCER.getAndIncrement());
54 - }
55 20
56 } 21 }
......
...@@ -12,4 +12,21 @@ public interface CoreService { ...@@ -12,4 +12,21 @@ public interface CoreService {
12 */ 12 */
13 Version version(); 13 Version version();
14 14
15 + /**
16 + * Registers a new application by its name, which is expected
17 + * to follow the reverse DNS convention, e.g.
18 + * {@code org.flying.circus.app}
19 + *
20 + * @param identifier string identifier
21 + * @return the application id
22 + */
23 + ApplicationId registerApplication(String identifier);
24 +
25 + /**
26 + * Returns an existing application id from a given id.
27 + * @param id the short value of the id
28 + * @return an application id
29 + */
30 + ApplicationId getAppId(Short id);
31 +
15 } 32 }
......
...@@ -34,7 +34,7 @@ public interface MastershipService { ...@@ -34,7 +34,7 @@ public interface MastershipService {
34 /** 34 /**
35 * Abandons mastership of the specified device on the local node thus 35 * Abandons mastership of the specified device on the local node thus
36 * forcing selection of a new master. If the local node is not a master 36 * forcing selection of a new master. If the local node is not a master
37 - * for this device, no action will be taken. 37 + * for this device, no master selection will occur.
38 * 38 *
39 * @param deviceId the identifier of the device 39 * @param deviceId the identifier of the device
40 */ 40 */
......
...@@ -66,12 +66,25 @@ public interface MastershipStore extends Store<MastershipEvent, MastershipStoreD ...@@ -66,12 +66,25 @@ public interface MastershipStore extends Store<MastershipEvent, MastershipStoreD
66 MastershipTerm getTermFor(DeviceId deviceId); 66 MastershipTerm getTermFor(DeviceId deviceId);
67 67
68 /** 68 /**
69 - * Revokes a controller instance's mastership over a device and hands 69 + * Sets a controller instance's mastership role to STANDBY for a device.
70 - * over mastership to another controller instance. 70 + * If the role is MASTER, another controller instance will be selected
71 + * as a candidate master.
71 * 72 *
72 * @param nodeId the controller instance identifier 73 * @param nodeId the controller instance identifier
73 - * @param deviceId device to revoke mastership for 74 + * @param deviceId device to revoke mastership role for
74 * @return a mastership event 75 * @return a mastership event
75 */ 76 */
76 - MastershipEvent unsetMaster(NodeId nodeId, DeviceId deviceId); 77 + MastershipEvent setStandby(NodeId nodeId, DeviceId deviceId);
78 +
79 + /**
80 + * Allows a controller instance to give up its current role for a device.
81 + * If the role is MASTER, another controller instance will be selected
82 + * as a candidate master.
83 + *
84 + * @param nodeId the controller instance identifier
85 + * @param deviceId device to revoke mastership role for
86 + * @return a mastership event
87 + */
88 + MastershipEvent relinquishRole(NodeId nodeId, DeviceId deviceId);
89 +
77 } 90 }
......
...@@ -42,6 +42,7 @@ public interface DeviceService { ...@@ -42,6 +42,7 @@ public interface DeviceService {
42 * @param deviceId device identifier 42 * @param deviceId device identifier
43 * @return designated mastership role 43 * @return designated mastership role
44 */ 44 */
45 + //XXX do we want this method here when MastershipService already does?
45 MastershipRole getRole(DeviceId deviceId); 46 MastershipRole getRole(DeviceId deviceId);
46 47
47 48
......
1 +package org.onlab.onos.net.flow;
2 +
3 +import java.util.List;
4 +
5 +/**
6 + * Interface capturing the result of a batch operation.
7 + *
8 + */
9 +public interface BatchOperationResult<T> {
10 +
11 + /**
12 + * Returns whether the operation was successful.
13 + * @return true if successful, false otherwise
14 + */
15 + boolean isSuccess();
16 +
17 + /**
18 + * Obtains a list of items which failed.
19 + * @return a list of failures
20 + */
21 + List<T> failedItems();
22 +
23 +}
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 -public class CompletedBatchOperation { 3 +import java.util.List;
4 +
5 +import com.google.common.collect.ImmutableList;
6 +
7 +public class CompletedBatchOperation implements BatchOperationResult<FlowEntry> {
8 +
9 +
10 + private final boolean success;
11 + private final List<FlowEntry> failures;
12 +
13 + public CompletedBatchOperation(boolean success, List<FlowEntry> failures) {
14 + this.success = success;
15 + this.failures = ImmutableList.copyOf(failures);
16 + }
17 +
18 + @Override
19 + public boolean isSuccess() {
20 + return success;
21 + }
22 +
23 + @Override
24 + public List<FlowEntry> failedItems() {
25 + return failures;
26 + }
4 27
5 28
6 } 29 }
......
...@@ -17,6 +17,10 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -17,6 +17,10 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
17 17
18 private long lastSeen = -1; 18 private long lastSeen = -1;
19 19
20 + private final int errType;
21 +
22 + private final int errCode;
23 +
20 24
21 public DefaultFlowEntry(DeviceId deviceId, TrafficSelector selector, 25 public DefaultFlowEntry(DeviceId deviceId, TrafficSelector selector,
22 TrafficTreatment treatment, int priority, FlowEntryState state, 26 TrafficTreatment treatment, int priority, FlowEntryState state,
...@@ -27,6 +31,8 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -27,6 +31,8 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
27 this.life = life; 31 this.life = life;
28 this.packets = packets; 32 this.packets = packets;
29 this.bytes = bytes; 33 this.bytes = bytes;
34 + this.errCode = -1;
35 + this.errType = -1;
30 this.lastSeen = System.currentTimeMillis(); 36 this.lastSeen = System.currentTimeMillis();
31 } 37 }
32 38
...@@ -37,6 +43,8 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -37,6 +43,8 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
37 this.life = life; 43 this.life = life;
38 this.packets = packets; 44 this.packets = packets;
39 this.bytes = bytes; 45 this.bytes = bytes;
46 + this.errCode = -1;
47 + this.errType = -1;
40 this.lastSeen = System.currentTimeMillis(); 48 this.lastSeen = System.currentTimeMillis();
41 } 49 }
42 50
...@@ -46,9 +54,18 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -46,9 +54,18 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
46 this.life = 0; 54 this.life = 0;
47 this.packets = 0; 55 this.packets = 0;
48 this.bytes = 0; 56 this.bytes = 0;
57 + this.errCode = -1;
58 + this.errType = -1;
49 this.lastSeen = System.currentTimeMillis(); 59 this.lastSeen = System.currentTimeMillis();
50 } 60 }
51 61
62 + public DefaultFlowEntry(FlowRule rule, int errType, int errCode) {
63 + super(rule);
64 + this.state = FlowEntryState.FAILED;
65 + this.errType = errType;
66 + this.errCode = errCode;
67 + }
68 +
52 @Override 69 @Override
53 public long life() { 70 public long life() {
54 return life; 71 return life;
...@@ -100,6 +117,16 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -100,6 +117,16 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
100 } 117 }
101 118
102 @Override 119 @Override
120 + public int errType() {
121 + return this.errType;
122 + }
123 +
124 + @Override
125 + public int errCode() {
126 + return this.errCode;
127 + }
128 +
129 + @Override
103 public String toString() { 130 public String toString() {
104 return toStringHelper(this) 131 return toStringHelper(this)
105 .add("rule", super.toString()) 132 .add("rule", super.toString())
...@@ -108,4 +135,6 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { ...@@ -108,4 +135,6 @@ public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
108 } 135 }
109 136
110 137
138 +
139 +
111 } 140 }
......
...@@ -21,7 +21,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -21,7 +21,7 @@ public class DefaultFlowRule implements FlowRule {
21 21
22 private final FlowId id; 22 private final FlowId id;
23 23
24 - private final ApplicationId appId; 24 + private final short appId;
25 25
26 private final int timeout; 26 private final int timeout;
27 27
...@@ -36,7 +36,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -36,7 +36,7 @@ public class DefaultFlowRule implements FlowRule {
36 this.timeout = timeout; 36 this.timeout = timeout;
37 this.created = System.currentTimeMillis(); 37 this.created = System.currentTimeMillis();
38 38
39 - this.appId = ApplicationId.valueOf((int) (flowId >> 32)); 39 + this.appId = (short) (flowId >>> 48);
40 this.id = FlowId.valueOf(flowId); 40 this.id = FlowId.valueOf(flowId);
41 } 41 }
42 42
...@@ -52,11 +52,11 @@ public class DefaultFlowRule implements FlowRule { ...@@ -52,11 +52,11 @@ public class DefaultFlowRule implements FlowRule {
52 this.priority = priority; 52 this.priority = priority;
53 this.selector = selector; 53 this.selector = selector;
54 this.treatment = treatement; 54 this.treatment = treatement;
55 - this.appId = appId; 55 + this.appId = appId.id();
56 this.timeout = timeout; 56 this.timeout = timeout;
57 this.created = System.currentTimeMillis(); 57 this.created = System.currentTimeMillis();
58 58
59 - this.id = FlowId.valueOf((((long) appId().id()) << 32) | (this.hash() & 0xffffffffL)); 59 + this.id = FlowId.valueOf((((long) this.appId) << 48) | (this.hash() & 0x0000ffffffffL));
60 } 60 }
61 61
62 public DefaultFlowRule(FlowRule rule) { 62 public DefaultFlowRule(FlowRule rule) {
...@@ -78,7 +78,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -78,7 +78,7 @@ public class DefaultFlowRule implements FlowRule {
78 } 78 }
79 79
80 @Override 80 @Override
81 - public ApplicationId appId() { 81 + public short appId() {
82 return appId; 82 return appId;
83 } 83 }
84 84
......
...@@ -140,6 +140,16 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -140,6 +140,16 @@ public final class DefaultTrafficSelector implements TrafficSelector {
140 } 140 }
141 141
142 @Override 142 @Override
143 + public Builder matchTcpSrc(Short tcpPort) {
144 + return add(Criteria.matchTcpSrc(tcpPort));
145 + }
146 +
147 + @Override
148 + public Builder matchTcpDst(Short tcpPort) {
149 + return add(Criteria.matchTcpDst(tcpPort));
150 + }
151 +
152 + @Override
143 public TrafficSelector build() { 153 public TrafficSelector build() {
144 return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values())); 154 return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
145 } 155 }
......
...@@ -29,7 +29,12 @@ public interface FlowEntry extends FlowRule { ...@@ -29,7 +29,12 @@ public interface FlowEntry extends FlowRule {
29 /** 29 /**
30 * Flow has been removed from flow table and can be purged. 30 * Flow has been removed from flow table and can be purged.
31 */ 31 */
32 - REMOVED 32 + REMOVED,
33 +
34 + /**
35 + * Indicates that the installation of this flow has failed.
36 + */
37 + FAILED
33 } 38 }
34 39
35 /** 40 /**
...@@ -95,4 +100,16 @@ public interface FlowEntry extends FlowRule { ...@@ -95,4 +100,16 @@ public interface FlowEntry extends FlowRule {
95 */ 100 */
96 void setBytes(long bytes); 101 void setBytes(long bytes);
97 102
103 + /**
104 + * Indicates the error type.
105 + * @return an integer value of the error
106 + */
107 + int errType();
108 +
109 + /**
110 + * Indicates the error code.
111 + * @return an integer value of the error
112 + */
113 + int errCode();
114 +
98 } 115 }
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 -import org.onlab.onos.ApplicationId;
4 import org.onlab.onos.net.DeviceId; 3 import org.onlab.onos.net.DeviceId;
5 import org.onlab.onos.net.intent.BatchOperationTarget; 4 import org.onlab.onos.net.intent.BatchOperationTarget;
6 5
...@@ -26,7 +25,7 @@ public interface FlowRule extends BatchOperationTarget { ...@@ -26,7 +25,7 @@ public interface FlowRule extends BatchOperationTarget {
26 * 25 *
27 * @return an applicationId 26 * @return an applicationId
28 */ 27 */
29 - ApplicationId appId(); 28 + short appId();
30 29
31 /** 30 /**
32 * Returns the flow rule priority given in natural order; higher numbers 31 * Returns the flow rule priority given in natural order; higher numbers
......
...@@ -37,6 +37,12 @@ public interface FlowRuleProvider extends Provider { ...@@ -37,6 +37,12 @@ public interface FlowRuleProvider extends Provider {
37 */ 37 */
38 void removeRulesById(ApplicationId id, FlowRule... flowRules); 38 void removeRulesById(ApplicationId id, FlowRule... flowRules);
39 39
40 - Future<Void> executeBatch(BatchOperation<FlowRuleBatchEntry> batch); 40 + /**
41 + * Installs a batch of flow rules. Each flowrule is associated to an
42 + * operation which results in either addition, removal or modification.
43 + * @param batch a batch of flow rules
44 + * @return a future indicating the status of this execution
45 + */
46 + Future<CompletedBatchOperation> executeBatch(BatchOperation<FlowRuleBatchEntry> batch);
41 47
42 } 48 }
......
...@@ -98,6 +98,20 @@ public interface TrafficSelector { ...@@ -98,6 +98,20 @@ public interface TrafficSelector {
98 public Builder matchIPDst(IpPrefix ip); 98 public Builder matchIPDst(IpPrefix ip);
99 99
100 /** 100 /**
101 + * Matches a TCP source port number.
102 + * @param tcpPort a TCP source port number
103 + * @return a selection builder
104 + */
105 + public Builder matchTcpSrc(Short tcpPort);
106 +
107 + /**
108 + * Matches a TCP destination port number.
109 + * @param tcpPort a TCP destination port number
110 + * @return a selection builder
111 + */
112 + public Builder matchTcpDst(Short tcpPort);
113 +
114 + /**
101 * Builds an immutable traffic selector. 115 * Builds an immutable traffic selector.
102 * 116 *
103 * @return traffic selector 117 * @return traffic selector
......
...@@ -113,6 +113,25 @@ public final class Criteria { ...@@ -113,6 +113,25 @@ public final class Criteria {
113 return new IPCriterion(ip, Type.IPV4_DST); 113 return new IPCriterion(ip, Type.IPV4_DST);
114 } 114 }
115 115
116 + /**
117 + * Creates a match on TCP source port field using the specified value.
118 + *
119 + * @param tcpPort
120 + * @return match criterion
121 + */
122 + public static Criterion matchTcpSrc(Short tcpPort) {
123 + return new TcpPortCriterion(tcpPort, Type.TCP_SRC);
124 + }
125 +
126 + /**
127 + * Creates a match on TCP destination port field using the specified value.
128 + *
129 + * @param tcpPort
130 + * @return match criterion
131 + */
132 + public static Criterion matchTcpDst(Short tcpPort) {
133 + return new TcpPortCriterion(tcpPort, Type.TCP_DST);
134 + }
116 135
117 /* 136 /*
118 * Implementations of criteria. 137 * Implementations of criteria.
...@@ -437,4 +456,49 @@ public final class Criteria { ...@@ -437,4 +456,49 @@ public final class Criteria {
437 } 456 }
438 457
439 458
459 + public static final class TcpPortCriterion implements Criterion {
460 +
461 + private final Short tcpPort;
462 + private final Type type;
463 +
464 + public TcpPortCriterion(Short tcpPort, Type type) {
465 + this.tcpPort = tcpPort;
466 + this.type = type;
467 + }
468 +
469 + @Override
470 + public Type type() {
471 + return this.type;
472 + }
473 +
474 + public Short tcpPort() {
475 + return this.tcpPort;
476 + }
477 +
478 + @Override
479 + public String toString() {
480 + return toStringHelper(type().toString())
481 + .add("tcpPort", tcpPort).toString();
482 + }
483 +
484 + @Override
485 + public int hashCode() {
486 + return Objects.hash(tcpPort, type);
487 + }
488 +
489 + @Override
490 + public boolean equals(Object obj) {
491 + if (this == obj) {
492 + return true;
493 + }
494 + if (obj instanceof TcpPortCriterion) {
495 + TcpPortCriterion that = (TcpPortCriterion) obj;
496 + return Objects.equals(tcpPort, that.tcpPort) &&
497 + Objects.equals(type, that.type);
498 +
499 +
500 + }
501 + return false;
502 + }
503 + }
440 } 504 }
......
1 package org.onlab.onos.net.intent; 1 package org.onlab.onos.net.intent;
2 2
3 +import java.util.concurrent.Future;
4 +
5 +import org.onlab.onos.net.flow.CompletedBatchOperation;
6 +
3 /** 7 /**
4 * Abstraction of entity capable of installing intents to the environment. 8 * Abstraction of entity capable of installing intents to the environment.
5 */ 9 */
...@@ -10,7 +14,7 @@ public interface IntentInstaller<T extends InstallableIntent> { ...@@ -10,7 +14,7 @@ public interface IntentInstaller<T extends InstallableIntent> {
10 * @param intent intent to be installed 14 * @param intent intent to be installed
11 * @throws IntentException if issues are encountered while installing the intent 15 * @throws IntentException if issues are encountered while installing the intent
12 */ 16 */
13 - void install(T intent); 17 + Future<CompletedBatchOperation> install(T intent);
14 18
15 /** 19 /**
16 * Uninstalls the specified intent from the environment. 20 * Uninstalls the specified intent from the environment.
...@@ -18,5 +22,5 @@ public interface IntentInstaller<T extends InstallableIntent> { ...@@ -18,5 +22,5 @@ public interface IntentInstaller<T extends InstallableIntent> {
18 * @param intent intent to be uninstalled 22 * @param intent intent to be uninstalled
19 * @throws IntentException if issues are encountered while uninstalling the intent 23 * @throws IntentException if issues are encountered while uninstalling the intent
20 */ 24 */
21 - void uninstall(T intent); 25 + Future<CompletedBatchOperation> uninstall(T intent);
22 } 26 }
......
...@@ -33,6 +33,8 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { ...@@ -33,6 +33,8 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {
33 33
34 /** 34 /**
35 * Returns the number of intents in the store. 35 * Returns the number of intents in the store.
36 + *
37 + * @return the number of intents in the store
36 */ 38 */
37 long getIntentCount(); 39 long getIntentCount();
38 40
...@@ -44,7 +46,7 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { ...@@ -44,7 +46,7 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {
44 Iterable<Intent> getIntents(); 46 Iterable<Intent> getIntents();
45 47
46 /** 48 /**
47 - * Returns the intent with the specified identifer. 49 + * Returns the intent with the specified identifier.
48 * 50 *
49 * @param intentId intent identification 51 * @param intentId intent identification
50 * @return intent or null if not found 52 * @return intent or null if not found
...@@ -94,7 +96,6 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { ...@@ -94,7 +96,6 @@ public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {
94 * specified original intent. 96 * specified original intent.
95 * 97 *
96 * @param intentId original intent identifier 98 * @param intentId original intent identifier
97 - * @return compiled state transition event
98 */ 99 */
99 void removeInstalledIntents(IntentId intentId); 100 void removeInstalledIntents(IntentId intentId);
100 101
......
...@@ -53,4 +53,4 @@ ...@@ -53,4 +53,4 @@
53 * while the system determines where to perform the compilation or while it 53 * while the system determines where to perform the compilation or while it
54 * performs global recomputation/optimization across all prior intents. 54 * performs global recomputation/optimization across all prior intents.
55 */ 55 */
56 -package org.onlab.onos.net.intent;
...\ No newline at end of file ...\ No newline at end of file
56 +package org.onlab.onos.net.intent;
......
1 package org.onlab.onos.net.intent; 1 package org.onlab.onos.net.intent;
2 2
3 -import org.junit.After; 3 +import static org.junit.Assert.assertEquals;
4 -import org.junit.Before; 4 +import static org.junit.Assert.assertFalse;
5 -import org.junit.Test; 5 +import static org.junit.Assert.assertNull;
6 +import static org.junit.Assert.fail;
7 +import static org.onlab.onos.net.intent.IntentEvent.Type.FAILED;
8 +import static org.onlab.onos.net.intent.IntentEvent.Type.INSTALLED;
9 +import static org.onlab.onos.net.intent.IntentEvent.Type.SUBMITTED;
10 +import static org.onlab.onos.net.intent.IntentEvent.Type.WITHDRAWN;
6 11
7 import java.util.ArrayList; 12 import java.util.ArrayList;
8 import java.util.Arrays; 13 import java.util.Arrays;
9 import java.util.Collections; 14 import java.util.Collections;
10 import java.util.Iterator; 15 import java.util.Iterator;
11 import java.util.List; 16 import java.util.List;
17 +import java.util.concurrent.Future;
12 18
13 -import static org.junit.Assert.*; 19 +import org.junit.After;
14 -import static org.onlab.onos.net.intent.IntentEvent.Type.*; 20 +import org.junit.Before;
21 +import org.junit.Test;
22 +import org.onlab.onos.net.flow.CompletedBatchOperation;
15 23
16 /** 24 /**
17 * Suite of tests for the intent service contract. 25 * Suite of tests for the intent service contract.
...@@ -290,17 +298,19 @@ public class IntentServiceTest { ...@@ -290,17 +298,19 @@ public class IntentServiceTest {
290 } 298 }
291 299
292 @Override 300 @Override
293 - public void install(TestInstallableIntent intent) { 301 + public Future<CompletedBatchOperation> install(TestInstallableIntent intent) {
294 if (fail) { 302 if (fail) {
295 throw new IntentException("install failed by design"); 303 throw new IntentException("install failed by design");
296 } 304 }
305 + return null;
297 } 306 }
298 307
299 @Override 308 @Override
300 - public void uninstall(TestInstallableIntent intent) { 309 + public Future<CompletedBatchOperation> uninstall(TestInstallableIntent intent) {
301 if (fail) { 310 if (fail) {
302 throw new IntentException("remove failed by design"); 311 throw new IntentException("remove failed by design");
303 } 312 }
313 + return null;
304 } 314 }
305 } 315 }
306 316
......
...@@ -82,7 +82,7 @@ implements MastershipService, MastershipAdminService { ...@@ -82,7 +82,7 @@ implements MastershipService, MastershipAdminService {
82 if (role.equals(MastershipRole.MASTER)) { 82 if (role.equals(MastershipRole.MASTER)) {
83 event = store.setMaster(nodeId, deviceId); 83 event = store.setMaster(nodeId, deviceId);
84 } else { 84 } else {
85 - event = store.unsetMaster(nodeId, deviceId); 85 + event = store.setStandby(nodeId, deviceId);
86 } 86 }
87 87
88 if (event != null) { 88 if (event != null) {
...@@ -98,13 +98,10 @@ implements MastershipService, MastershipAdminService { ...@@ -98,13 +98,10 @@ implements MastershipService, MastershipAdminService {
98 98
99 @Override 99 @Override
100 public void relinquishMastership(DeviceId deviceId) { 100 public void relinquishMastership(DeviceId deviceId) {
101 - MastershipRole role = getLocalRole(deviceId); 101 + MastershipEvent event = null;
102 - if (!role.equals(MastershipRole.MASTER)) { 102 + event = store.relinquishRole(
103 - return;
104 - }
105 -
106 - MastershipEvent event = store.unsetMaster(
107 clusterService.getLocalNode().id(), deviceId); 103 clusterService.getLocalNode().id(), deviceId);
104 +
108 if (event != null) { 105 if (event != null) {
109 post(event); 106 post(event);
110 } 107 }
......
1 -package org.onlab.onos.cluster.impl; 1 +package org.onlab.onos.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;
5 import org.apache.felix.scr.annotations.Service; 5 import org.apache.felix.scr.annotations.Service;
6 +import org.onlab.onos.ApplicationId;
6 import org.onlab.onos.CoreService; 7 import org.onlab.onos.CoreService;
7 import org.onlab.onos.Version; 8 import org.onlab.onos.Version;
8 import org.onlab.util.Tools; 9 import org.onlab.util.Tools;
9 10
10 import java.io.File; 11 import java.io.File;
11 import java.util.List; 12 import java.util.List;
13 +import java.util.Map;
14 +import java.util.concurrent.ConcurrentHashMap;
15 +import java.util.concurrent.atomic.AtomicInteger;
12 16
13 /** 17 /**
14 * Core service implementation. 18 * Core service implementation.
...@@ -17,9 +21,13 @@ import java.util.List; ...@@ -17,9 +21,13 @@ import java.util.List;
17 @Service 21 @Service
18 public class CoreManager implements CoreService { 22 public class CoreManager implements CoreService {
19 23
24 + private static final AtomicInteger ID_DISPENSER = new AtomicInteger(1);
25 +
20 private static final File VERSION_FILE = new File("../VERSION"); 26 private static final File VERSION_FILE = new File("../VERSION");
21 private static Version version = Version.version("1.0.0-SNAPSHOT"); 27 private static Version version = Version.version("1.0.0-SNAPSHOT");
22 28
29 + private final Map<Short, DefaultApplicationId> appIds = new ConcurrentHashMap<>();
30 +
23 // TODO: work in progress 31 // TODO: work in progress
24 32
25 @Activate 33 @Activate
...@@ -35,4 +43,17 @@ public class CoreManager implements CoreService { ...@@ -35,4 +43,17 @@ public class CoreManager implements CoreService {
35 return version; 43 return version;
36 } 44 }
37 45
46 + @Override
47 + public ApplicationId getAppId(Short id) {
48 + return appIds.get(id);
49 + }
50 +
51 + @Override
52 + public ApplicationId registerApplication(String name) {
53 + short id = (short) ID_DISPENSER.getAndIncrement();
54 + DefaultApplicationId appId = new DefaultApplicationId(id, name);
55 + appIds.put(id, appId);
56 + return appId;
57 + }
58 +
38 } 59 }
......
1 +package org.onlab.onos.impl;
2 +
3 +import org.onlab.onos.ApplicationId;
4 +
5 +import java.util.Objects;
6 +
7 +import static com.google.common.base.MoreObjects.toStringHelper;
8 +
9 +/**
10 + * Application id generator class.
11 + */
12 +public class DefaultApplicationId implements ApplicationId {
13 +
14 + private final short id;
15 + private final String name;
16 +
17 + // Ban public construction
18 + protected DefaultApplicationId(Short id, String identifier) {
19 + this.id = id;
20 + this.name = identifier;
21 + }
22 +
23 + @Override
24 + public short id() {
25 + return id;
26 + }
27 +
28 + @Override
29 + public String name() {
30 + return name;
31 + }
32 +
33 + @Override
34 + public int hashCode() {
35 + return Objects.hash(id);
36 + }
37 +
38 + @Override
39 + public boolean equals(Object obj) {
40 + if (this == obj) {
41 + return true;
42 + }
43 + if (obj instanceof DefaultApplicationId) {
44 + DefaultApplicationId other = (DefaultApplicationId) obj;
45 + return Objects.equals(this.id, other.id);
46 + }
47 + return false;
48 + }
49 +
50 + @Override
51 + public String toString() {
52 + return toStringHelper(this).add("id", id).add("name", name).toString();
53 + }
54 +
55 +}
1 +/**
2 + *
3 + */
4 +package org.onlab.onos.impl;
...\ No newline at end of file ...\ No newline at end of file
...@@ -143,7 +143,7 @@ public class DeviceManager ...@@ -143,7 +143,7 @@ public class DeviceManager
143 143
144 // Applies the specified role to the device; ignores NONE 144 // Applies the specified role to the device; ignores NONE
145 private void applyRole(DeviceId deviceId, MastershipRole newRole) { 145 private void applyRole(DeviceId deviceId, MastershipRole newRole) {
146 - if (newRole != MastershipRole.NONE) { 146 + if (newRole.equals(MastershipRole.NONE)) {
147 Device device = store.getDevice(deviceId); 147 Device device = store.getDevice(deviceId);
148 // FIXME: Device might not be there yet. (eventual consistent) 148 // FIXME: Device might not be there yet. (eventual consistent)
149 if (device == null) { 149 if (device == null) {
...@@ -257,13 +257,14 @@ public class DeviceManager ...@@ -257,13 +257,14 @@ public class DeviceManager
257 // temporarily request for Master Role and mark offline. 257 // temporarily request for Master Role and mark offline.
258 if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) { 258 if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) {
259 log.debug("Device {} disconnected, but I am not the master", deviceId); 259 log.debug("Device {} disconnected, but I am not the master", deviceId);
260 + //let go of any role anyways
261 + mastershipService.relinquishMastership(deviceId);
260 return; 262 return;
261 } 263 }
262 DeviceEvent event = store.markOffline(deviceId); 264 DeviceEvent event = store.markOffline(deviceId);
263 - 265 + //we're no longer capable of being master or a candidate.
264 mastershipService.relinquishMastership(deviceId); 266 mastershipService.relinquishMastership(deviceId);
265 267
266 - //we're no longer capable of mastership.
267 if (event != null) { 268 if (event != null) {
268 log.info("Device {} disconnected", deviceId); 269 log.info("Device {} disconnected", deviceId);
269 post(event); 270 post(event);
...@@ -319,24 +320,29 @@ public class DeviceManager ...@@ -319,24 +320,29 @@ public class DeviceManager
319 } 320 }
320 321
321 // Intercepts mastership events 322 // Intercepts mastership events
322 - private class InternalMastershipListener 323 + private class InternalMastershipListener implements MastershipListener {
323 - implements MastershipListener { 324 +
324 @Override 325 @Override
325 public void event(MastershipEvent event) { 326 public void event(MastershipEvent event) {
326 - final NodeId myNodeId = clusterService.getLocalNode().id(); 327 + final DeviceId did = event.subject();
327 - if (myNodeId.equals(event.master())) { 328 + if (isAvailable(did)) {
328 - 329 + final NodeId myNodeId = clusterService.getLocalNode().id();
329 - MastershipTerm term = mastershipService.requestTermService() 330 +
330 - .getMastershipTerm(event.subject()); 331 + if (myNodeId.equals(event.master())) {
331 - 332 + MastershipTerm term = termService.getMastershipTerm(did);
332 - if (term.master().equals(myNodeId)) { 333 +
333 - // only set the new term if I am the master 334 + if (term.master().equals(myNodeId)) {
334 - clockProviderService.setMastershipTerm(event.subject(), term); 335 + // only set the new term if I am the master
336 + clockProviderService.setMastershipTerm(did, term);
337 + }
338 + applyRole(did, MastershipRole.MASTER);
339 + } else {
340 + applyRole(did, MastershipRole.STANDBY);
335 } 341 }
336 -
337 - applyRole(event.subject(), MastershipRole.MASTER);
338 } else { 342 } else {
339 - applyRole(event.subject(), MastershipRole.STANDBY); 343 + //device dead to node, give up
344 + mastershipService.relinquishMastership(did);
345 + applyRole(did, MastershipRole.STANDBY);
340 } 346 }
341 } 347 }
342 } 348 }
......
...@@ -5,10 +5,12 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,10 +5,12 @@ import static org.slf4j.LoggerFactory.getLogger;
5 5
6 import java.util.Iterator; 6 import java.util.Iterator;
7 import java.util.List; 7 import java.util.List;
8 +import java.util.concurrent.CancellationException;
8 import java.util.concurrent.ExecutionException; 9 import java.util.concurrent.ExecutionException;
9 import java.util.concurrent.Future; 10 import java.util.concurrent.Future;
10 import java.util.concurrent.TimeUnit; 11 import java.util.concurrent.TimeUnit;
11 import java.util.concurrent.TimeoutException; 12 import java.util.concurrent.TimeoutException;
13 +import java.util.concurrent.atomic.AtomicReference;
12 14
13 import org.apache.felix.scr.annotations.Activate; 15 import org.apache.felix.scr.annotations.Activate;
14 import org.apache.felix.scr.annotations.Component; 16 import org.apache.felix.scr.annotations.Component;
...@@ -26,6 +28,7 @@ import org.onlab.onos.net.flow.CompletedBatchOperation; ...@@ -26,6 +28,7 @@ import org.onlab.onos.net.flow.CompletedBatchOperation;
26 import org.onlab.onos.net.flow.FlowEntry; 28 import org.onlab.onos.net.flow.FlowEntry;
27 import org.onlab.onos.net.flow.FlowRule; 29 import org.onlab.onos.net.flow.FlowRule;
28 import org.onlab.onos.net.flow.FlowRuleBatchEntry; 30 import org.onlab.onos.net.flow.FlowRuleBatchEntry;
31 +import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
29 import org.onlab.onos.net.flow.FlowRuleBatchOperation; 32 import org.onlab.onos.net.flow.FlowRuleBatchOperation;
30 import org.onlab.onos.net.flow.FlowRuleEvent; 33 import org.onlab.onos.net.flow.FlowRuleEvent;
31 import org.onlab.onos.net.flow.FlowRuleListener; 34 import org.onlab.onos.net.flow.FlowRuleListener;
...@@ -52,6 +55,8 @@ public class FlowRuleManager ...@@ -52,6 +55,8 @@ public class FlowRuleManager
52 extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService> 55 extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
53 implements FlowRuleService, FlowRuleProviderRegistry { 56 implements FlowRuleService, FlowRuleProviderRegistry {
54 57
58 + enum BatchState { STARTED, FINISHED, CANCELLED };
59 +
55 public static final String FLOW_RULE_NULL = "FlowRule cannot be null"; 60 public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
56 private final Logger log = getLogger(getClass()); 61 private final Logger log = getLogger(getClass());
57 62
...@@ -144,7 +149,7 @@ public class FlowRuleManager ...@@ -144,7 +149,7 @@ public class FlowRuleManager
144 FlowRuleBatchOperation batch) { 149 FlowRuleBatchOperation batch) {
145 Multimap<FlowRuleProvider, FlowRuleBatchEntry> batches = 150 Multimap<FlowRuleProvider, FlowRuleBatchEntry> batches =
146 ArrayListMultimap.create(); 151 ArrayListMultimap.create();
147 - List<Future<Void>> futures = Lists.newArrayList(); 152 + List<Future<CompletedBatchOperation>> futures = Lists.newArrayList();
148 for (FlowRuleBatchEntry fbe : batch.getOperations()) { 153 for (FlowRuleBatchEntry fbe : batch.getOperations()) {
149 final FlowRule f = fbe.getTarget(); 154 final FlowRule f = fbe.getTarget();
150 final Device device = deviceService.getDevice(f.deviceId()); 155 final Device device = deviceService.getDevice(f.deviceId());
...@@ -165,10 +170,10 @@ public class FlowRuleManager ...@@ -165,10 +170,10 @@ public class FlowRuleManager
165 for (FlowRuleProvider provider : batches.keySet()) { 170 for (FlowRuleProvider provider : batches.keySet()) {
166 FlowRuleBatchOperation b = 171 FlowRuleBatchOperation b =
167 new FlowRuleBatchOperation(batches.get(provider)); 172 new FlowRuleBatchOperation(batches.get(provider));
168 - Future<Void> future = provider.executeBatch(b); 173 + Future<CompletedBatchOperation> future = provider.executeBatch(b);
169 futures.add(future); 174 futures.add(future);
170 } 175 }
171 - return new FlowRuleBatchFuture(futures); 176 + return new FlowRuleBatchFuture(futures, batches);
172 } 177 }
173 178
174 @Override 179 @Override
...@@ -341,59 +346,140 @@ public class FlowRuleManager ...@@ -341,59 +346,140 @@ public class FlowRuleManager
341 private class FlowRuleBatchFuture 346 private class FlowRuleBatchFuture
342 implements Future<CompletedBatchOperation> { 347 implements Future<CompletedBatchOperation> {
343 348
344 - private final List<Future<Void>> futures; 349 + private final List<Future<CompletedBatchOperation>> futures;
350 + private final Multimap<FlowRuleProvider, FlowRuleBatchEntry> batches;
351 + private final AtomicReference<BatchState> state;
352 + private CompletedBatchOperation overall;
353 +
354 +
345 355
346 - public FlowRuleBatchFuture(List<Future<Void>> futures) { 356 + public FlowRuleBatchFuture(List<Future<CompletedBatchOperation>> futures,
357 + Multimap<FlowRuleProvider, FlowRuleBatchEntry> batches) {
347 this.futures = futures; 358 this.futures = futures;
359 + this.batches = batches;
360 + state = new AtomicReference<FlowRuleManager.BatchState>();
361 + state.set(BatchState.STARTED);
348 } 362 }
349 363
350 @Override 364 @Override
351 public boolean cancel(boolean mayInterruptIfRunning) { 365 public boolean cancel(boolean mayInterruptIfRunning) {
352 - // TODO Auto-generated method stub 366 + if (state.get() == BatchState.FINISHED) {
353 - return false; 367 + return false;
368 + }
369 + if (!state.compareAndSet(BatchState.STARTED, BatchState.CANCELLED)) {
370 + return false;
371 + }
372 + cleanUpBatch();
373 + for (Future<CompletedBatchOperation> f : futures) {
374 + f.cancel(mayInterruptIfRunning);
375 + }
376 + return true;
354 } 377 }
355 378
356 @Override 379 @Override
357 public boolean isCancelled() { 380 public boolean isCancelled() {
358 - // TODO Auto-generated method stub 381 + return state.get() == BatchState.CANCELLED;
359 - return false;
360 } 382 }
361 383
362 @Override 384 @Override
363 public boolean isDone() { 385 public boolean isDone() {
364 - boolean isDone = true; 386 + return state.get() == BatchState.FINISHED;
365 - for (Future<Void> future : futures) {
366 - isDone &= future.isDone();
367 - }
368 - return isDone;
369 } 387 }
370 388
389 +
371 @Override 390 @Override
372 public CompletedBatchOperation get() throws InterruptedException, 391 public CompletedBatchOperation get() throws InterruptedException,
373 - ExecutionException { 392 + ExecutionException {
374 - // TODO Auto-generated method stub 393 +
375 - for (Future<Void> future : futures) { 394 + if (isDone()) {
376 - future.get(); 395 + return overall;
396 + }
397 +
398 + boolean success = true;
399 + List<FlowEntry> failed = Lists.newLinkedList();
400 + CompletedBatchOperation completed;
401 + for (Future<CompletedBatchOperation> future : futures) {
402 + completed = future.get();
403 + success = validateBatchOperation(failed, completed, future);
377 } 404 }
378 - return new CompletedBatchOperation(); 405 +
406 + return finalizeBatchOperation(success, failed);
407 +
379 } 408 }
380 409
381 @Override 410 @Override
382 public CompletedBatchOperation get(long timeout, TimeUnit unit) 411 public CompletedBatchOperation get(long timeout, TimeUnit unit)
383 throws InterruptedException, ExecutionException, 412 throws InterruptedException, ExecutionException,
384 TimeoutException { 413 TimeoutException {
385 - // TODO we should decrement the timeout 414 +
415 + if (isDone()) {
416 + return overall;
417 + }
418 + boolean success = true;
419 + List<FlowEntry> failed = Lists.newLinkedList();
420 + CompletedBatchOperation completed;
386 long start = System.nanoTime(); 421 long start = System.nanoTime();
387 long end = start + unit.toNanos(timeout); 422 long end = start + unit.toNanos(timeout);
388 - for (Future<Void> future : futures) { 423 +
424 + for (Future<CompletedBatchOperation> future : futures) {
389 long now = System.nanoTime(); 425 long now = System.nanoTime();
390 long thisTimeout = end - now; 426 long thisTimeout = end - now;
391 - future.get(thisTimeout, TimeUnit.NANOSECONDS); 427 + completed = future.get(thisTimeout, TimeUnit.NANOSECONDS);
428 + success = validateBatchOperation(failed, completed, future);
392 } 429 }
393 - return new CompletedBatchOperation(); 430 + return finalizeBatchOperation(success, failed);
394 } 431 }
395 432
433 + private boolean validateBatchOperation(List<FlowEntry> failed,
434 + CompletedBatchOperation completed,
435 + Future<CompletedBatchOperation> future) {
436 +
437 + if (isCancelled()) {
438 + throw new CancellationException();
439 + }
440 + if (!completed.isSuccess()) {
441 + failed.addAll(completed.failedItems());
442 + cleanUpBatch();
443 + cancelAllSubBatches();
444 + return false;
445 + }
446 + return true;
447 + }
448 +
449 + private void cancelAllSubBatches() {
450 + for (Future<CompletedBatchOperation> f : futures) {
451 + f.cancel(true);
452 + }
453 + }
454 +
455 + private CompletedBatchOperation finalizeBatchOperation(boolean success,
456 + List<FlowEntry> failed) {
457 + synchronized (this) {
458 + if (!state.compareAndSet(BatchState.STARTED, BatchState.FINISHED)) {
459 + if (state.get() == BatchState.FINISHED) {
460 + return overall;
461 + }
462 + throw new CancellationException();
463 + }
464 + overall = new CompletedBatchOperation(success, failed);
465 + return overall;
466 + }
467 + }
468 +
469 + private void cleanUpBatch() {
470 + for (FlowRuleBatchEntry fbe : batches.values()) {
471 + if (fbe.getOperator() == FlowRuleOperation.ADD ||
472 + fbe.getOperator() == FlowRuleOperation.MODIFY) {
473 + store.deleteFlowRule(fbe.getTarget());
474 + } else if (fbe.getOperator() == FlowRuleOperation.REMOVE) {
475 + store.storeFlowRule(fbe.getTarget());
476 + }
477 + }
478 +
479 + }
396 } 480 }
397 481
398 482
483 +
484 +
399 } 485 }
......
...@@ -13,12 +13,17 @@ import static org.onlab.util.Tools.namedThreads; ...@@ -13,12 +13,17 @@ import static org.onlab.util.Tools.namedThreads;
13 import static org.slf4j.LoggerFactory.getLogger; 13 import static org.slf4j.LoggerFactory.getLogger;
14 14
15 import java.util.ArrayList; 15 import java.util.ArrayList;
16 +import java.util.Iterator;
16 import java.util.List; 17 import java.util.List;
17 import java.util.Map; 18 import java.util.Map;
18 import java.util.Objects; 19 import java.util.Objects;
19 import java.util.concurrent.ConcurrentHashMap; 20 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.ConcurrentMap; 21 import java.util.concurrent.ConcurrentMap;
22 +import java.util.concurrent.ExecutionException;
21 import java.util.concurrent.ExecutorService; 23 import java.util.concurrent.ExecutorService;
24 +import java.util.concurrent.Future;
25 +import java.util.concurrent.TimeUnit;
26 +import java.util.concurrent.TimeoutException;
22 27
23 import org.apache.felix.scr.annotations.Activate; 28 import org.apache.felix.scr.annotations.Activate;
24 import org.apache.felix.scr.annotations.Component; 29 import org.apache.felix.scr.annotations.Component;
...@@ -28,6 +33,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -28,6 +33,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
28 import org.apache.felix.scr.annotations.Service; 33 import org.apache.felix.scr.annotations.Service;
29 import org.onlab.onos.event.AbstractListenerRegistry; 34 import org.onlab.onos.event.AbstractListenerRegistry;
30 import org.onlab.onos.event.EventDeliveryService; 35 import org.onlab.onos.event.EventDeliveryService;
36 +import org.onlab.onos.net.flow.CompletedBatchOperation;
31 import org.onlab.onos.net.intent.InstallableIntent; 37 import org.onlab.onos.net.intent.InstallableIntent;
32 import org.onlab.onos.net.intent.Intent; 38 import org.onlab.onos.net.intent.Intent;
33 import org.onlab.onos.net.intent.IntentCompiler; 39 import org.onlab.onos.net.intent.IntentCompiler;
...@@ -44,7 +50,9 @@ import org.onlab.onos.net.intent.IntentStore; ...@@ -44,7 +50,9 @@ import org.onlab.onos.net.intent.IntentStore;
44 import org.onlab.onos.net.intent.IntentStoreDelegate; 50 import org.onlab.onos.net.intent.IntentStoreDelegate;
45 import org.slf4j.Logger; 51 import org.slf4j.Logger;
46 52
53 +import com.google.common.collect.ImmutableList;
47 import com.google.common.collect.ImmutableMap; 54 import com.google.common.collect.ImmutableMap;
55 +import com.google.common.collect.Lists;
48 56
49 /** 57 /**
50 * An implementation of Intent Manager. 58 * An implementation of Intent Manager.
...@@ -67,7 +75,8 @@ public class IntentManager ...@@ -67,7 +75,8 @@ public class IntentManager
67 private final AbstractListenerRegistry<IntentEvent, IntentListener> 75 private final AbstractListenerRegistry<IntentEvent, IntentListener>
68 listenerRegistry = new AbstractListenerRegistry<>(); 76 listenerRegistry = new AbstractListenerRegistry<>();
69 77
70 - private final ExecutorService executor = newSingleThreadExecutor(namedThreads("onos-intents")); 78 + private ExecutorService executor;
79 + private ExecutorService monitorExecutor;
71 80
72 private final IntentStoreDelegate delegate = new InternalStoreDelegate(); 81 private final IntentStoreDelegate delegate = new InternalStoreDelegate();
73 private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate(); 82 private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate();
...@@ -86,6 +95,8 @@ public class IntentManager ...@@ -86,6 +95,8 @@ public class IntentManager
86 store.setDelegate(delegate); 95 store.setDelegate(delegate);
87 trackerService.setDelegate(topoDelegate); 96 trackerService.setDelegate(topoDelegate);
88 eventDispatcher.addSink(IntentEvent.class, listenerRegistry); 97 eventDispatcher.addSink(IntentEvent.class, listenerRegistry);
98 + executor = newSingleThreadExecutor(namedThreads("onos-intents"));
99 + monitorExecutor = newSingleThreadExecutor(namedThreads("onos-intent-monitor"));
89 log.info("Started"); 100 log.info("Started");
90 } 101 }
91 102
...@@ -94,6 +105,8 @@ public class IntentManager ...@@ -94,6 +105,8 @@ public class IntentManager
94 store.unsetDelegate(delegate); 105 store.unsetDelegate(delegate);
95 trackerService.unsetDelegate(topoDelegate); 106 trackerService.unsetDelegate(topoDelegate);
96 eventDispatcher.removeSink(IntentEvent.class); 107 eventDispatcher.removeSink(IntentEvent.class);
108 + executor.shutdown();
109 + monitorExecutor.shutdown();
97 log.info("Stopped"); 110 log.info("Stopped");
98 } 111 }
99 112
...@@ -240,14 +253,23 @@ public class IntentManager ...@@ -240,14 +253,23 @@ public class IntentManager
240 } 253 }
241 } 254 }
242 255
243 - // FIXME: To make SDN-IP workable ASAP, only single level compilation is implemented 256 + /**
244 - // TODO: implement compilation traversing tree structure 257 + * Compiles an intent recursively.
258 + *
259 + * @param intent intent
260 + * @return result of compilation
261 + */
245 private List<InstallableIntent> compileIntent(Intent intent) { 262 private List<InstallableIntent> compileIntent(Intent intent) {
263 + if (intent instanceof InstallableIntent) {
264 + return ImmutableList.of((InstallableIntent) intent);
265 + }
266 +
246 List<InstallableIntent> installable = new ArrayList<>(); 267 List<InstallableIntent> installable = new ArrayList<>();
268 + // TODO do we need to registerSubclassCompiler?
247 for (Intent compiled : getCompiler(intent).compile(intent)) { 269 for (Intent compiled : getCompiler(intent).compile(intent)) {
248 - InstallableIntent installableIntent = (InstallableIntent) compiled; 270 + installable.addAll(compileIntent(compiled));
249 - installable.add(installableIntent);
250 } 271 }
272 +
251 return installable; 273 return installable;
252 } 274 }
253 275
...@@ -261,6 +283,7 @@ public class IntentManager ...@@ -261,6 +283,7 @@ public class IntentManager
261 // Indicate that the intent is entering the installing phase. 283 // Indicate that the intent is entering the installing phase.
262 store.setState(intent, INSTALLING); 284 store.setState(intent, INSTALLING);
263 285
286 + List<Future<CompletedBatchOperation>> installFutures = Lists.newArrayList();
264 try { 287 try {
265 List<InstallableIntent> installables = store.getInstallableIntents(intent.id()); 288 List<InstallableIntent> installables = store.getInstallableIntents(intent.id());
266 if (installables != null) { 289 if (installables != null) {
...@@ -268,17 +291,20 @@ public class IntentManager ...@@ -268,17 +291,20 @@ public class IntentManager
268 registerSubclassInstallerIfNeeded(installable); 291 registerSubclassInstallerIfNeeded(installable);
269 trackerService.addTrackedResources(intent.id(), 292 trackerService.addTrackedResources(intent.id(),
270 installable.requiredLinks()); 293 installable.requiredLinks());
271 - getInstaller(installable).install(installable); 294 + Future<CompletedBatchOperation> future = getInstaller(installable).install(installable);
295 + installFutures.add(future);
272 } 296 }
273 } 297 }
274 - eventDispatcher.post(store.setState(intent, INSTALLED)); 298 + // FIXME we have to wait for the installable intents
275 - 299 + //eventDispatcher.post(store.setState(intent, INSTALLED));
300 + monitorExecutor.execute(new IntentInstallMonitor(intent, installFutures, INSTALLED));
276 } catch (Exception e) { 301 } catch (Exception e) {
277 log.warn("Unable to install intent {} due to: {}", intent.id(), e); 302 log.warn("Unable to install intent {} due to: {}", intent.id(), e);
278 - uninstallIntent(intent); 303 + uninstallIntent(intent, RECOMPILING);
279 304
280 // If compilation failed, kick off the recompiling phase. 305 // If compilation failed, kick off the recompiling phase.
281 - executeRecompilingPhase(intent); 306 + // FIXME
307 + //executeRecompilingPhase(intent);
282 } 308 }
283 } 309 }
284 310
...@@ -327,12 +353,14 @@ public class IntentManager ...@@ -327,12 +353,14 @@ public class IntentManager
327 private void executeWithdrawingPhase(Intent intent) { 353 private void executeWithdrawingPhase(Intent intent) {
328 // Indicate that the intent is being withdrawn. 354 // Indicate that the intent is being withdrawn.
329 store.setState(intent, WITHDRAWING); 355 store.setState(intent, WITHDRAWING);
330 - uninstallIntent(intent); 356 + uninstallIntent(intent, WITHDRAWN);
331 357
332 // If all went well, disassociate the top-level intent with its 358 // If all went well, disassociate the top-level intent with its
333 // installable derivatives and mark it as withdrawn. 359 // installable derivatives and mark it as withdrawn.
334 - store.removeInstalledIntents(intent.id()); 360 + // FIXME need to clean up
335 - eventDispatcher.post(store.setState(intent, WITHDRAWN)); 361 + //store.removeInstalledIntents(intent.id());
362 + // FIXME
363 + //eventDispatcher.post(store.setState(intent, WITHDRAWN));
336 } 364 }
337 365
338 /** 366 /**
...@@ -340,14 +368,17 @@ public class IntentManager ...@@ -340,14 +368,17 @@ public class IntentManager
340 * 368 *
341 * @param intent intent to be uninstalled 369 * @param intent intent to be uninstalled
342 */ 370 */
343 - private void uninstallIntent(Intent intent) { 371 + private void uninstallIntent(Intent intent, IntentState nextState) {
372 + List<Future<CompletedBatchOperation>> uninstallFutures = Lists.newArrayList();
344 try { 373 try {
345 List<InstallableIntent> installables = store.getInstallableIntents(intent.id()); 374 List<InstallableIntent> installables = store.getInstallableIntents(intent.id());
346 if (installables != null) { 375 if (installables != null) {
347 for (InstallableIntent installable : installables) { 376 for (InstallableIntent installable : installables) {
348 - getInstaller(installable).uninstall(installable); 377 + Future<CompletedBatchOperation> future = getInstaller(installable).uninstall(installable);
378 + uninstallFutures.add(future);
349 } 379 }
350 } 380 }
381 + monitorExecutor.execute(new IntentInstallMonitor(intent, uninstallFutures, nextState));
351 } catch (IntentException e) { 382 } catch (IntentException e) {
352 log.warn("Unable to uninstall intent {} due to: {}", intent.id(), e); 383 log.warn("Unable to uninstall intent {} due to: {}", intent.id(), e);
353 } 384 }
...@@ -422,9 +453,10 @@ public class IntentManager ...@@ -422,9 +453,10 @@ public class IntentManager
422 // Attempt recompilation of the specified intents first. 453 // Attempt recompilation of the specified intents first.
423 for (IntentId intentId : intentIds) { 454 for (IntentId intentId : intentIds) {
424 Intent intent = getIntent(intentId); 455 Intent intent = getIntent(intentId);
425 - uninstallIntent(intent); 456 + uninstallIntent(intent, RECOMPILING);
426 457
427 - executeRecompilingPhase(intent); 458 + //FIXME
459 + //executeRecompilingPhase(intent);
428 } 460 }
429 461
430 if (compileAllFailed) { 462 if (compileAllFailed) {
...@@ -460,4 +492,49 @@ public class IntentManager ...@@ -460,4 +492,49 @@ public class IntentManager
460 } 492 }
461 } 493 }
462 494
495 + private class IntentInstallMonitor implements Runnable {
496 +
497 + private final Intent intent;
498 + private final List<Future<CompletedBatchOperation>> futures;
499 + private final IntentState nextState;
500 +
501 + public IntentInstallMonitor(Intent intent,
502 + List<Future<CompletedBatchOperation>> futures, IntentState nextState) {
503 + this.intent = intent;
504 + this.futures = futures;
505 + this.nextState = nextState;
506 + }
507 +
508 + private void updateIntent(Intent intent) {
509 + if (nextState == RECOMPILING) {
510 + executor.execute(new IntentTask(nextState, intent));
511 + } else if (nextState == INSTALLED || nextState == WITHDRAWN) {
512 + eventDispatcher.post(store.setState(intent, nextState));
513 + } else {
514 + log.warn("Invalid next intent state {} for intent {}", nextState, intent);
515 + }
516 + }
517 +
518 + @Override
519 + public void run() {
520 + for (Iterator<Future<CompletedBatchOperation>> i = futures.iterator(); i.hasNext();) {
521 + Future<CompletedBatchOperation> future = i.next();
522 + try {
523 + // TODO: we may want to get the future here and go back to the future.
524 + CompletedBatchOperation completed = future.get(100, TimeUnit.NANOSECONDS);
525 + // TODO check if future succeeded and if not report fail items
526 + i.remove();
527 +
528 + } catch (TimeoutException | InterruptedException | ExecutionException te) {
529 + log.debug("Intallations of intent {} is still pending", intent);
530 + }
531 + }
532 + if (futures.isEmpty()) {
533 + updateIntent(intent);
534 + } else {
535 + // resubmit ourselves if we are not done yet
536 + monitorExecutor.submit(this);
537 + }
538 + }
539 + }
463 } 540 }
......
...@@ -5,7 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,7 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger;
5 5
6 import java.util.Iterator; 6 import java.util.Iterator;
7 import java.util.List; 7 import java.util.List;
8 -import java.util.concurrent.ExecutionException; 8 +import java.util.concurrent.Future;
9 9
10 import org.apache.felix.scr.annotations.Activate; 10 import org.apache.felix.scr.annotations.Activate;
11 import org.apache.felix.scr.annotations.Component; 11 import org.apache.felix.scr.annotations.Component;
...@@ -13,8 +13,10 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -13,8 +13,10 @@ import org.apache.felix.scr.annotations.Deactivate;
13 import org.apache.felix.scr.annotations.Reference; 13 import org.apache.felix.scr.annotations.Reference;
14 import org.apache.felix.scr.annotations.ReferenceCardinality; 14 import org.apache.felix.scr.annotations.ReferenceCardinality;
15 import org.onlab.onos.ApplicationId; 15 import org.onlab.onos.ApplicationId;
16 +import org.onlab.onos.CoreService;
16 import org.onlab.onos.net.ConnectPoint; 17 import org.onlab.onos.net.ConnectPoint;
17 import org.onlab.onos.net.Link; 18 import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.flow.CompletedBatchOperation;
18 import org.onlab.onos.net.flow.DefaultFlowRule; 20 import org.onlab.onos.net.flow.DefaultFlowRule;
19 import org.onlab.onos.net.flow.DefaultTrafficSelector; 21 import org.onlab.onos.net.flow.DefaultTrafficSelector;
20 import org.onlab.onos.net.flow.FlowRule; 22 import org.onlab.onos.net.flow.FlowRule;
...@@ -45,10 +47,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -45,10 +47,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
45 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 47 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
46 protected FlowRuleService flowRuleService; 48 protected FlowRuleService flowRuleService;
47 49
48 - private final ApplicationId appId = ApplicationId.getAppId(); 50 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 + protected CoreService coreService;
52 +
53 + private ApplicationId appId;
49 54
50 @Activate 55 @Activate
51 public void activate() { 56 public void activate() {
57 + appId = coreService.registerApplication("org.onlab.onos.net.intent");
52 intentManager.registerInstaller(PathIntent.class, this); 58 intentManager.registerInstaller(PathIntent.class, this);
53 } 59 }
54 60
...@@ -57,8 +63,26 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -57,8 +63,26 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
57 intentManager.unregisterInstaller(PathIntent.class); 63 intentManager.unregisterInstaller(PathIntent.class);
58 } 64 }
59 65
66 + /**
67 + * Apply a list of FlowRules.
68 + *
69 + * @param rules rules to apply
70 + */
71 + private Future<CompletedBatchOperation> applyBatch(List<FlowRuleBatchEntry> rules) {
72 + FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules);
73 + Future<CompletedBatchOperation> future = flowRuleService.applyBatch(batch);
74 + return future;
75 +// try {
76 +// //FIXME don't do this here
77 +// future.get();
78 +// } catch (InterruptedException | ExecutionException e) {
79 +// // TODO Auto-generated catch block
80 +// e.printStackTrace();
81 +// }
82 + }
83 +
60 @Override 84 @Override
61 - public void install(PathIntent intent) { 85 + public Future<CompletedBatchOperation> install(PathIntent intent) {
62 TrafficSelector.Builder builder = 86 TrafficSelector.Builder builder =
63 DefaultTrafficSelector.builder(intent.selector()); 87 DefaultTrafficSelector.builder(intent.selector());
64 Iterator<Link> links = intent.path().links().iterator(); 88 Iterator<Link> links = intent.path().links().iterator();
...@@ -74,20 +98,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -74,20 +98,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
74 builder.build(), treatment, 98 builder.build(), treatment,
75 123, appId, 600); 99 123, appId, 600);
76 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); 100 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
77 - //flowRuleService.applyFlowRules(rule);
78 prev = link.dst(); 101 prev = link.dst();
79 } 102 }
80 - FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules); 103 +
81 - try { 104 + return applyBatch(rules);
82 - flowRuleService.applyBatch(batch).get();
83 - } catch (InterruptedException | ExecutionException e) {
84 - // TODO Auto-generated catch block
85 - e.printStackTrace();
86 - }
87 } 105 }
88 106
89 @Override 107 @Override
90 - public void uninstall(PathIntent intent) { 108 + public Future<CompletedBatchOperation> uninstall(PathIntent intent) {
91 TrafficSelector.Builder builder = 109 TrafficSelector.Builder builder =
92 DefaultTrafficSelector.builder(intent.selector()); 110 DefaultTrafficSelector.builder(intent.selector());
93 Iterator<Link> links = intent.path().links().iterator(); 111 Iterator<Link> links = intent.path().links().iterator();
...@@ -103,15 +121,131 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -103,15 +121,131 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
103 builder.build(), treatment, 121 builder.build(), treatment,
104 123, appId, 600); 122 123, appId, 600);
105 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule)); 123 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
106 - //flowRuleService.removeFlowRules(rule);
107 prev = link.dst(); 124 prev = link.dst();
108 } 125 }
109 - FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules); 126 + return applyBatch(rules);
110 - try { 127 + }
111 - flowRuleService.applyBatch(batch).get(); 128 +
112 - } catch (InterruptedException | ExecutionException e) { 129 + // TODO refactor below this line... ----------------------------
113 - // TODO Auto-generated catch block 130 +
114 - e.printStackTrace(); 131 + /**
132 + * Generates the series of MatchActionOperations from the
133 + * {@link FlowBatchOperation}.
134 + * <p>
135 + * FIXME: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
136 + * <p>
137 + * FIXME: MatchActionOperations should have dependency field to the other
138 + * match action operations, and this method should use this.
139 + *
140 + * @param op the {@link FlowBatchOperation} object
141 + * @return the list of {@link MatchActionOperations} objects
142 + */
143 + /*
144 + private List<MatchActionOperations>
145 + generateMatchActionOperationsList(FlowBatchOperation op) {
146 +
147 + // MatchAction operations at head (ingress) switches.
148 + MatchActionOperations headOps = matchActionService.createOperationsList();
149 +
150 + // MatchAction operations at rest of the switches.
151 + MatchActionOperations tailOps = matchActionService.createOperationsList();
152 +
153 + MatchActionOperations removeOps = matchActionService.createOperationsList();
154 +
155 + for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
156 +
157 + if (e.getOperator() == FlowBatchOperation.Operator.ADD) {
158 + generateInstallMatchActionOperations(e, tailOps, headOps);
159 + } else if (e.getOperator() == FlowBatchOperation.Operator.REMOVE) {
160 + generateRemoveMatchActionOperations(e, removeOps);
161 + } else {
162 + throw new UnsupportedOperationException(
163 + "FlowManager supports ADD and REMOVE operations only.");
164 + }
165 +
166 + }
167 +
168 + return Arrays.asList(tailOps, headOps, removeOps);
169 + }
170 + */
171 +
172 + /**
173 + * Generates MatchActionOperations for an INSTALL FlowBatchOperation.
174 + * <p/>
175 + * FIXME: Currently only supports flows that generate exactly two match
176 + * action operation sets.
177 + *
178 + * @param e Flow BatchOperationEntry
179 + * @param tailOps MatchActionOperation set that the tail
180 + * MatchActionOperations will be placed in
181 + * @param headOps MatchActionOperation set that the head
182 + * MatchActionOperations will be placed in
183 + */
184 + /*
185 + private void generateInstallMatchActionOperations(
186 + BatchOperationEntry<Operator, ?> e,
187 + MatchActionOperations tailOps,
188 + MatchActionOperations headOps) {
189 +
190 + if (!(e.getTarget() instanceof Flow)) {
191 + throw new IllegalStateException(
192 + "The target is not Flow object: " + e.getTarget());
193 + }
194 +
195 + // Compile flows to match-actions
196 + Flow flow = (Flow) e.getTarget();
197 + List<MatchActionOperations> maOps = flow.compile(
198 + e.getOperator(), matchActionService);
199 + verifyNotNull(maOps, "Could not compile the flow: " + flow);
200 + verify(maOps.size() == 2,
201 + "The flow generates unspported match-action operations.");
202 +
203 + // Map FlowId to MatchActionIds
204 + for (MatchActionOperations maOp : maOps) {
205 + for (MatchActionOperationEntry entry : maOp.getOperations()) {
206 + flowMatchActionsMap.put(
207 + KryoFactory.serialize(flow.getId()),
208 + KryoFactory.serialize(entry.getTarget()));
209 + }
210 + }
211 +
212 + // Merge match-action operations
213 + for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
214 + verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
215 + tailOps.addOperation(mae);
216 + }
217 + for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
218 + verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
219 + headOps.addOperation(mae);
220 + }
221 + }
222 + */
223 + /**
224 + * Generates MatchActionOperations for a REMOVE FlowBatchOperation.
225 + *
226 + * @param e Flow BatchOperationEntry
227 + * @param removeOps MatchActionOperation set that the remove
228 + * MatchActionOperations will be placed in
229 + */
230 + /*
231 + private void generateRemoveMatchActionOperations(
232 + BatchOperationEntry<Operator, ?> e,
233 + MatchActionOperations removeOps) {
234 +
235 + if (!(e.getTarget() instanceof FlowId)) {
236 + throw new IllegalStateException(
237 + "The target is not a FlowId object: " + e.getTarget());
238 + }
239 +
240 + // Compile flows to match-actions
241 + FlowId flowId = (FlowId) e.getTarget();
242 +
243 + for (byte[] matchActionIdBytes :
244 + flowMatchActionsMap.remove(KryoFactory.serialize(flowId))) {
245 + MatchActionId matchActionId = KryoFactory.deserialize(matchActionIdBytes);
246 + removeOps.addOperation(new MatchActionOperationEntry(
247 + MatchActionOperations.Operator.REMOVE, matchActionId));
115 } 248 }
116 } 249 }
250 + */
117 } 251 }
......
...@@ -55,6 +55,7 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -55,6 +55,7 @@ public class ProxyArpManager implements ProxyArpService {
55 private static final String REQUEST_NULL = "Arp request cannot be null."; 55 private static final String REQUEST_NULL = "Arp request cannot be null.";
56 private static final String REQUEST_NOT_ARP = "Ethernet frame does not contain ARP request."; 56 private static final String REQUEST_NOT_ARP = "Ethernet frame does not contain ARP request.";
57 private static final String NOT_ARP_REQUEST = "ARP is not a request."; 57 private static final String NOT_ARP_REQUEST = "ARP is not a request.";
58 + private static final String NOT_ARP_REPLY = "ARP is not a reply.";
58 59
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected HostService hostService; 61 protected HostService hostService;
...@@ -141,7 +142,7 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -141,7 +142,7 @@ public class ProxyArpManager implements ProxyArpService {
141 checkArgument(eth.getEtherType() == Ethernet.TYPE_ARP, 142 checkArgument(eth.getEtherType() == Ethernet.TYPE_ARP,
142 REQUEST_NOT_ARP); 143 REQUEST_NOT_ARP);
143 ARP arp = (ARP) eth.getPayload(); 144 ARP arp = (ARP) eth.getPayload();
144 - checkArgument(arp.getOpCode() == ARP.OP_REPLY, NOT_ARP_REQUEST); 145 + checkArgument(arp.getOpCode() == ARP.OP_REPLY, NOT_ARP_REPLY);
145 146
146 Host h = hostService.getHost(HostId.hostId(eth.getDestinationMAC(), 147 Host h = hostService.getHost(HostId.hostId(eth.getDestinationMAC(),
147 VlanId.vlanId(eth.getVlanID()))); 148 VlanId.vlanId(eth.getVlanID())));
......
...@@ -272,7 +272,8 @@ public class DeviceManagerTest { ...@@ -272,7 +272,8 @@ public class DeviceManagerTest {
272 } 272 }
273 } 273 }
274 274
275 - private static class TestMastershipService extends MastershipServiceAdapter { 275 + private static class TestMastershipService
276 + extends MastershipServiceAdapter {
276 @Override 277 @Override
277 public MastershipRole getLocalRole(DeviceId deviceId) { 278 public MastershipRole getLocalRole(DeviceId deviceId) {
278 return MastershipRole.MASTER; 279 return MastershipRole.MASTER;
......
...@@ -19,6 +19,7 @@ import org.junit.Before; ...@@ -19,6 +19,7 @@ import org.junit.Before;
19 import org.junit.Test; 19 import org.junit.Test;
20 import org.onlab.onos.ApplicationId; 20 import org.onlab.onos.ApplicationId;
21 import org.onlab.onos.event.impl.TestEventDispatcher; 21 import org.onlab.onos.event.impl.TestEventDispatcher;
22 +import org.onlab.onos.impl.DefaultApplicationId;
22 import org.onlab.onos.net.DefaultDevice; 23 import org.onlab.onos.net.DefaultDevice;
23 import org.onlab.onos.net.Device; 24 import org.onlab.onos.net.Device;
24 import org.onlab.onos.net.Device.Type; 25 import org.onlab.onos.net.Device.Type;
...@@ -28,6 +29,7 @@ import org.onlab.onos.net.Port; ...@@ -28,6 +29,7 @@ import org.onlab.onos.net.Port;
28 import org.onlab.onos.net.PortNumber; 29 import org.onlab.onos.net.PortNumber;
29 import org.onlab.onos.net.device.DeviceListener; 30 import org.onlab.onos.net.device.DeviceListener;
30 import org.onlab.onos.net.device.DeviceService; 31 import org.onlab.onos.net.device.DeviceService;
32 +import org.onlab.onos.net.flow.CompletedBatchOperation;
31 import org.onlab.onos.net.flow.DefaultFlowEntry; 33 import org.onlab.onos.net.flow.DefaultFlowEntry;
32 import org.onlab.onos.net.flow.DefaultFlowRule; 34 import org.onlab.onos.net.flow.DefaultFlowRule;
33 import org.onlab.onos.net.flow.FlowEntry; 35 import org.onlab.onos.net.flow.FlowEntry;
...@@ -58,6 +60,8 @@ import com.google.common.collect.Sets; ...@@ -58,6 +60,8 @@ import com.google.common.collect.Sets;
58 */ 60 */
59 public class FlowRuleManagerTest { 61 public class FlowRuleManagerTest {
60 62
63 +
64 +
61 private static final ProviderId PID = new ProviderId("of", "foo"); 65 private static final ProviderId PID = new ProviderId("of", "foo");
62 private static final DeviceId DID = DeviceId.deviceId("of:001"); 66 private static final DeviceId DID = DeviceId.deviceId("of:001");
63 private static final int TIMEOUT = 10; 67 private static final int TIMEOUT = 10;
...@@ -86,7 +90,7 @@ public class FlowRuleManagerTest { ...@@ -86,7 +90,7 @@ public class FlowRuleManagerTest {
86 mgr.addListener(listener); 90 mgr.addListener(listener);
87 provider = new TestProvider(PID); 91 provider = new TestProvider(PID);
88 providerService = registry.register(provider); 92 providerService = registry.register(provider);
89 - appId = ApplicationId.getAppId(); 93 + appId = new TestApplicationId((short) 0, "FlowRuleManagerTest");
90 assertTrue("provider should be registered", 94 assertTrue("provider should be registered",
91 registry.getProviders().contains(provider.id())); 95 registry.getProviders().contains(provider.id()));
92 } 96 }
...@@ -408,7 +412,7 @@ public class FlowRuleManagerTest { ...@@ -408,7 +412,7 @@ public class FlowRuleManagerTest {
408 } 412 }
409 413
410 @Override 414 @Override
411 - public Future<Void> executeBatch( 415 + public Future<CompletedBatchOperation> executeBatch(
412 BatchOperation<FlowRuleBatchEntry> batch) { 416 BatchOperation<FlowRuleBatchEntry> batch) {
413 // TODO Auto-generated method stub 417 // TODO Auto-generated method stub
414 return null; 418 return null;
...@@ -474,4 +478,11 @@ public class FlowRuleManagerTest { ...@@ -474,4 +478,11 @@ public class FlowRuleManagerTest {
474 478
475 } 479 }
476 480
481 + public class TestApplicationId extends DefaultApplicationId {
482 +
483 + public TestApplicationId(short id, String name) {
484 + super(id, name);
485 + }
486 + }
487 +
477 } 488 }
......
...@@ -43,8 +43,8 @@ public class DistributedFlowRuleStore ...@@ -43,8 +43,8 @@ public class DistributedFlowRuleStore
43 private final Multimap<DeviceId, FlowEntry> flowEntries = 43 private final Multimap<DeviceId, FlowEntry> flowEntries =
44 ArrayListMultimap.<DeviceId, FlowEntry>create(); 44 ArrayListMultimap.<DeviceId, FlowEntry>create();
45 45
46 - private final Multimap<ApplicationId, FlowRule> flowEntriesById = 46 + private final Multimap<Short, FlowRule> flowEntriesById =
47 - ArrayListMultimap.<ApplicationId, FlowRule>create(); 47 + ArrayListMultimap.<Short, FlowRule>create();
48 48
49 @Activate 49 @Activate
50 public void activate() { 50 public void activate() {
...@@ -83,7 +83,7 @@ public class DistributedFlowRuleStore ...@@ -83,7 +83,7 @@ public class DistributedFlowRuleStore
83 83
84 @Override 84 @Override
85 public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) { 85 public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
86 - Collection<FlowRule> rules = flowEntriesById.get(appId); 86 + Collection<FlowRule> rules = flowEntriesById.get(appId.id());
87 if (rules == null) { 87 if (rules == null) {
88 return Collections.emptyList(); 88 return Collections.emptyList();
89 } 89 }
......
...@@ -43,8 +43,8 @@ public class DistributedFlowRuleStore ...@@ -43,8 +43,8 @@ public class DistributedFlowRuleStore
43 private final Multimap<DeviceId, FlowEntry> flowEntries = 43 private final Multimap<DeviceId, FlowEntry> flowEntries =
44 ArrayListMultimap.<DeviceId, FlowEntry>create(); 44 ArrayListMultimap.<DeviceId, FlowEntry>create();
45 45
46 - private final Multimap<ApplicationId, FlowRule> flowEntriesById = 46 + private final Multimap<Short, FlowRule> flowEntriesById =
47 - ArrayListMultimap.<ApplicationId, FlowRule>create(); 47 + ArrayListMultimap.<Short, FlowRule>create();
48 48
49 @Activate 49 @Activate
50 public void activate() { 50 public void activate() {
...@@ -83,7 +83,7 @@ public class DistributedFlowRuleStore ...@@ -83,7 +83,7 @@ public class DistributedFlowRuleStore
83 83
84 @Override 84 @Override
85 public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) { 85 public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
86 - Collection<FlowRule> rules = flowEntriesById.get(appId); 86 + Collection<FlowRule> rules = flowEntriesById.get(appId.id());
87 if (rules == null) { 87 if (rules == null) {
88 return Collections.emptyList(); 88 return Collections.emptyList();
89 } 89 }
......
...@@ -42,8 +42,8 @@ public class SimpleFlowRuleStore ...@@ -42,8 +42,8 @@ public class SimpleFlowRuleStore
42 private final Multimap<DeviceId, FlowEntry> flowEntries = 42 private final Multimap<DeviceId, FlowEntry> flowEntries =
43 ArrayListMultimap.<DeviceId, FlowEntry>create(); 43 ArrayListMultimap.<DeviceId, FlowEntry>create();
44 44
45 - private final Multimap<ApplicationId, FlowRule> flowEntriesById = 45 + private final Multimap<Short, FlowRule> flowEntriesById =
46 - ArrayListMultimap.<ApplicationId, FlowRule>create(); 46 + ArrayListMultimap.<Short, FlowRule>create();
47 47
48 @Activate 48 @Activate
49 public void activate() { 49 public void activate() {
...@@ -82,7 +82,7 @@ public class SimpleFlowRuleStore ...@@ -82,7 +82,7 @@ public class SimpleFlowRuleStore
82 82
83 @Override 83 @Override
84 public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) { 84 public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
85 - Collection<FlowRule> rules = flowEntriesById.get(appId); 85 + Collection<FlowRule> rules = flowEntriesById.get(appId.id());
86 if (rules == null) { 86 if (rules == null) {
87 return Collections.emptyList(); 87 return Collections.emptyList();
88 } 88 }
......
...@@ -174,7 +174,7 @@ public class SimpleMastershipStore ...@@ -174,7 +174,7 @@ public class SimpleMastershipStore
174 } 174 }
175 175
176 @Override 176 @Override
177 - public MastershipEvent unsetMaster(NodeId nodeId, DeviceId deviceId) { 177 + public MastershipEvent setStandby(NodeId nodeId, DeviceId deviceId) {
178 MastershipRole role = getRole(nodeId, deviceId); 178 MastershipRole role = getRole(nodeId, deviceId);
179 synchronized (this) { 179 synchronized (this) {
180 switch (role) { 180 switch (role) {
...@@ -214,4 +214,9 @@ public class SimpleMastershipStore ...@@ -214,4 +214,9 @@ public class SimpleMastershipStore
214 return backup; 214 return backup;
215 } 215 }
216 216
217 + @Override
218 + public MastershipEvent relinquishRole(NodeId nodeId, DeviceId deviceId) {
219 + return setStandby(nodeId, deviceId);
220 + }
221 +
217 } 222 }
......
...@@ -129,22 +129,22 @@ public class SimpleMastershipStoreTest { ...@@ -129,22 +129,22 @@ public class SimpleMastershipStoreTest {
129 public void unsetMaster() { 129 public void unsetMaster() {
130 //NONE - record backup but take no other action 130 //NONE - record backup but take no other action
131 put(DID1, N1, false, false); 131 put(DID1, N1, false, false);
132 - sms.unsetMaster(N1, DID1); 132 + sms.setStandby(N1, DID1);
133 assertTrue("not backed up", sms.backups.contains(N1)); 133 assertTrue("not backed up", sms.backups.contains(N1));
134 sms.termMap.clear(); 134 sms.termMap.clear();
135 - sms.unsetMaster(N1, DID1); 135 + sms.setStandby(N1, DID1);
136 assertTrue("term not set", sms.termMap.containsKey(DID1)); 136 assertTrue("term not set", sms.termMap.containsKey(DID1));
137 137
138 //no backup, MASTER 138 //no backup, MASTER
139 put(DID1, N1, true, true); 139 put(DID1, N1, true, true);
140 - assertNull("wrong event", sms.unsetMaster(N1, DID1)); 140 + assertNull("wrong event", sms.setStandby(N1, DID1));
141 assertNull("wrong node", sms.masterMap.get(DID1)); 141 assertNull("wrong node", sms.masterMap.get(DID1));
142 142
143 //backup, switch 143 //backup, switch
144 sms.masterMap.clear(); 144 sms.masterMap.clear();
145 put(DID1, N1, true, true); 145 put(DID1, N1, true, true);
146 put(DID2, N2, true, true); 146 put(DID2, N2, true, true);
147 - assertEquals("wrong event", MASTER_CHANGED, sms.unsetMaster(N1, DID1).type()); 147 + assertEquals("wrong event", MASTER_CHANGED, sms.setStandby(N1, DID1).type());
148 } 148 }
149 149
150 //helper to populate master/backup structures 150 //helper to populate master/backup structures
......
...@@ -981,11 +981,13 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -981,11 +981,13 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
981 // switch was a duplicate-dpid, calling the method below would clear 981 // switch was a duplicate-dpid, calling the method below would clear
982 // all state for the original switch (with the same dpid), 982 // all state for the original switch (with the same dpid),
983 // which we obviously don't want. 983 // which we obviously don't want.
984 + log.info("{}:removal called");
984 sw.removeConnectedSwitch(); 985 sw.removeConnectedSwitch();
985 } else { 986 } else {
986 // A duplicate was disconnected on this ChannelHandler, 987 // A duplicate was disconnected on this ChannelHandler,
987 // this is the same switch reconnecting, but the original state was 988 // this is the same switch reconnecting, but the original state was
988 // not cleaned up - XXX check liveness of original ChannelHandler 989 // not cleaned up - XXX check liveness of original ChannelHandler
990 + log.info("{}:duplicate found");
989 duplicateDpidFound = Boolean.FALSE; 991 duplicateDpidFound = Boolean.FALSE;
990 } 992 }
991 } else { 993 } else {
......
...@@ -307,9 +307,11 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -307,9 +307,11 @@ public class OpenFlowControllerImpl implements OpenFlowController {
307 connectedSwitches.remove(dpid); 307 connectedSwitches.remove(dpid);
308 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid); 308 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
309 if (sw == null) { 309 if (sw == null) {
310 + log.warn("sw was null for {}", dpid);
310 sw = activeEqualSwitches.remove(dpid); 311 sw = activeEqualSwitches.remove(dpid);
311 } 312 }
312 for (OpenFlowSwitchListener l : ofSwitchListener) { 313 for (OpenFlowSwitchListener l : ofSwitchListener) {
314 + log.warn("removal for {}", dpid);
313 l.switchRemoved(dpid); 315 l.switchRemoved(dpid);
314 } 316 }
315 } 317 }
......
...@@ -27,6 +27,8 @@ import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcp ...@@ -27,6 +27,8 @@ import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcp
27 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction; 27 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
28 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; 28 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
29 import org.projectfloodlight.openflow.protocol.OFFactory; 29 import org.projectfloodlight.openflow.protocol.OFFactory;
30 +import org.projectfloodlight.openflow.protocol.OFFlowAdd;
31 +import org.projectfloodlight.openflow.protocol.OFFlowDelete;
30 import org.projectfloodlight.openflow.protocol.OFFlowMod; 32 import org.projectfloodlight.openflow.protocol.OFFlowMod;
31 import org.projectfloodlight.openflow.protocol.OFFlowModFlags; 33 import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
32 import org.projectfloodlight.openflow.protocol.action.OFAction; 34 import org.projectfloodlight.openflow.protocol.action.OFAction;
...@@ -68,12 +70,13 @@ public class FlowModBuilder { ...@@ -68,12 +70,13 @@ public class FlowModBuilder {
68 this.cookie = flowRule.id(); 70 this.cookie = flowRule.id();
69 } 71 }
70 72
71 - public OFFlowMod buildFlowAdd() { 73 + public OFFlowAdd buildFlowAdd() {
72 Match match = buildMatch(); 74 Match match = buildMatch();
73 List<OFAction> actions = buildActions(); 75 List<OFAction> actions = buildActions();
74 76
75 //TODO: what to do without bufferid? do we assume that there will be a pktout as well? 77 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
76 - OFFlowMod fm = factory.buildFlowAdd() 78 + OFFlowAdd fm = factory.buildFlowAdd()
79 + .setXid(cookie.value())
77 .setCookie(U64.of(cookie.value())) 80 .setCookie(U64.of(cookie.value()))
78 .setBufferId(OFBufferId.NO_BUFFER) 81 .setBufferId(OFBufferId.NO_BUFFER)
79 .setActions(actions) 82 .setActions(actions)
...@@ -92,6 +95,7 @@ public class FlowModBuilder { ...@@ -92,6 +95,7 @@ public class FlowModBuilder {
92 95
93 //TODO: what to do without bufferid? do we assume that there will be a pktout as well? 96 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
94 OFFlowMod fm = factory.buildFlowModify() 97 OFFlowMod fm = factory.buildFlowModify()
98 + .setXid(cookie.value())
95 .setCookie(U64.of(cookie.value())) 99 .setCookie(U64.of(cookie.value()))
96 .setBufferId(OFBufferId.NO_BUFFER) 100 .setBufferId(OFBufferId.NO_BUFFER)
97 .setActions(actions) 101 .setActions(actions)
...@@ -104,11 +108,12 @@ public class FlowModBuilder { ...@@ -104,11 +108,12 @@ public class FlowModBuilder {
104 108
105 } 109 }
106 110
107 - public OFFlowMod buildFlowDel() { 111 + public OFFlowDelete buildFlowDel() {
108 Match match = buildMatch(); 112 Match match = buildMatch();
109 List<OFAction> actions = buildActions(); 113 List<OFAction> actions = buildActions();
110 114
111 - OFFlowMod fm = factory.buildFlowDelete() 115 + OFFlowDelete fm = factory.buildFlowDelete()
116 + .setXid(cookie.value())
112 .setCookie(U64.of(cookie.value())) 117 .setCookie(U64.of(cookie.value()))
113 .setBufferId(OFBufferId.NO_BUFFER) 118 .setBufferId(OFBufferId.NO_BUFFER)
114 .setActions(actions) 119 .setActions(actions)
......
...@@ -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 ow='onos-watch'
36 alias go='ob && ot && onos -w' 37 alias go='ob && ot && onos -w'
37 alias pub='onos-push-update-bundle' 38 alias pub='onos-push-update-bundle'
38 39
......
1 #------------------------------------------------------------------------------ 1 #------------------------------------------------------------------------------
2 -# Echoes project-level directory if a Java file within is newer than its 2 +# Echoes project-level directory if a Java file within is newer than the
3 -# class file counterpart 3 +# target directory.
4 #------------------------------------------------------------------------------ 4 #------------------------------------------------------------------------------
5 5
6 javaFile=${1#*\/src\/*\/java/} 6 javaFile=${1#*\/src\/*\/java/}
...@@ -10,9 +10,7 @@ basename=${1/*\//} ...@@ -10,9 +10,7 @@ basename=${1/*\//}
10 10
11 src=${1/$javaFile/} 11 src=${1/$javaFile/}
12 project=${src/src*/} 12 project=${src/src*/}
13 -classFile=${javaFile/.java/.class} 13 +target=$project/target
14 14
15 -[ ${project}target/classes/$classFile -nt ${src}$javaFile -o \ 15 +[ $target -nt ${src}$javaFile ] || echo ${src/src*/}
16 - ${project}target/test-classes/$classFile -nt ${src}$javaFile ] \
17 - || echo ${src/src*/}
18 16
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
7 . $ONOS_ROOT/tools/build/envDefaults 7 . $ONOS_ROOT/tools/build/envDefaults
8 8
9 cd ~/.m2/repository 9 cd ~/.m2/repository
10 -jar=$(find org/onlab -type f -name '*.jar' | grep $1 | grep -v -e -tests | head -n 1) 10 +jar=$(find org/onlab -type f -name '*.jar' | grep -e $1 | grep -v -e -tests | head -n 1)
11 11
12 [ -z "$jar" ] && echo "No bundle $1 found for" && exit 1 12 [ -z "$jar" ] && echo "No bundle $1 found for" && exit 1
13 13
......
1 +#!/bin/bash
2 +#-------------------------------------------------------------------------------
3 +# Monitors selected set of ONOS commands using the system watch command.
4 +#-------------------------------------------------------------------------------
5 +
6 +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
7 +. $ONOS_ROOT/tools/build/envDefaults
8 +
9 +node=${1:-$OCI}
10 +
11 +commands="${2:-summary,intents,flows,hosts}"
12 +
13 +aux=/tmp/onos-watch.$$
14 +trap "rm -f $aux" EXIT
15 +
16 +echo "$commands" | tr ',' '\n' > $aux
17 +watch $3 "onos $node -b <$aux 2>/dev/null"
...@@ -11,6 +11,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -11,6 +11,7 @@ import org.apache.felix.scr.annotations.Deactivate;
11 import org.slf4j.Logger; 11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory; 12 import org.slf4j.LoggerFactory;
13 13
14 +import com.codahale.metrics.ConsoleReporter;
14 import com.codahale.metrics.Counter; 15 import com.codahale.metrics.Counter;
15 import com.codahale.metrics.Gauge; 16 import com.codahale.metrics.Gauge;
16 import com.codahale.metrics.Histogram; 17 import com.codahale.metrics.Histogram;
...@@ -18,7 +19,6 @@ import com.codahale.metrics.Meter; ...@@ -18,7 +19,6 @@ import com.codahale.metrics.Meter;
18 import com.codahale.metrics.Metric; 19 import com.codahale.metrics.Metric;
19 import com.codahale.metrics.MetricFilter; 20 import com.codahale.metrics.MetricFilter;
20 import com.codahale.metrics.MetricRegistry; 21 import com.codahale.metrics.MetricRegistry;
21 -import com.codahale.metrics.Slf4jReporter;
22 import com.codahale.metrics.Timer; 22 import com.codahale.metrics.Timer;
23 23
24 /** 24 /**
...@@ -70,16 +70,20 @@ public final class MetricsManager implements MetricsService { ...@@ -70,16 +70,20 @@ public final class MetricsManager implements MetricsService {
70 /** 70 /**
71 * Default Reporter for this metrics manager. 71 * Default Reporter for this metrics manager.
72 */ 72 */
73 - private final Slf4jReporter reporter; 73 + //private final Slf4jReporter reporter;
74 + private final ConsoleReporter reporter;
74 75
75 public MetricsManager() { 76 public MetricsManager() {
76 this.metricsRegistry = new MetricRegistry(); 77 this.metricsRegistry = new MetricRegistry();
77 - this.reporter = Slf4jReporter.forRegistry(this.metricsRegistry) 78 +// this.reporter = Slf4jReporter.forRegistry(this.metricsRegistry)
78 - .outputTo(log) 79 +// .outputTo(log)
80 +// .convertRatesTo(TimeUnit.SECONDS)
81 +// .convertDurationsTo(TimeUnit.MICROSECONDS)
82 +// .build();
83 + this.reporter = ConsoleReporter.forRegistry(this.metricsRegistry)
79 .convertRatesTo(TimeUnit.SECONDS) 84 .convertRatesTo(TimeUnit.SECONDS)
80 - .convertDurationsTo(TimeUnit.NANOSECONDS) 85 + .convertDurationsTo(TimeUnit.MICROSECONDS)
81 .build(); 86 .build();
82 - reporter.start(1, TimeUnit.MINUTES);
83 } 87 }
84 88
85 @Activate 89 @Activate
......