Madan Jampani

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

Showing 23 changed files with 300 additions and 63 deletions
1 package org.onlab.onos.fwd; 1 package org.onlab.onos.fwd;
2 2
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.Dictionary;
6 +import java.util.Set;
7 +
3 import org.apache.felix.scr.annotations.Activate; 8 import org.apache.felix.scr.annotations.Activate;
4 import org.apache.felix.scr.annotations.Component; 9 import org.apache.felix.scr.annotations.Component;
5 import org.apache.felix.scr.annotations.Deactivate; 10 import org.apache.felix.scr.annotations.Deactivate;
...@@ -30,11 +35,6 @@ import org.onlab.packet.Ethernet; ...@@ -30,11 +35,6 @@ import org.onlab.packet.Ethernet;
30 import org.osgi.service.component.ComponentContext; 35 import org.osgi.service.component.ComponentContext;
31 import org.slf4j.Logger; 36 import org.slf4j.Logger;
32 37
33 -import java.util.Dictionary;
34 -import java.util.Set;
35 -
36 -import static org.slf4j.LoggerFactory.getLogger;
37 -
38 /** 38 /**
39 * Sample reactive forwarding application. 39 * Sample reactive forwarding application.
40 */ 40 */
...@@ -206,7 +206,7 @@ public class ReactiveForwarding { ...@@ -206,7 +206,7 @@ public class ReactiveForwarding {
206 treat.setOutput(portNumber); 206 treat.setOutput(portNumber);
207 207
208 FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), 208 FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
209 - builder.build(), treat.build(), PRIORITY, appId, TIMEOUT); 209 + builder.build(), treat.build(), PRIORITY, appId, TIMEOUT, false);
210 210
211 flowRuleService.applyFlowRules(f); 211 flowRuleService.applyFlowRules(f);
212 } 212 }
......
...@@ -21,7 +21,7 @@ import org.onlab.onos.net.device.DeviceService; ...@@ -21,7 +21,7 @@ import org.onlab.onos.net.device.DeviceService;
21 description = "Lists mastership roles of nodes for each device.") 21 description = "Lists mastership roles of nodes for each device.")
22 public class RolesCommand extends AbstractShellCommand { 22 public class RolesCommand extends AbstractShellCommand {
23 23
24 - private static final String FMT_HDR = "%s: master=%s, standbys=%s"; 24 + private static final String FMT_HDR = "%s: master=%s, standbys=[ %s]";
25 25
26 @Override 26 @Override
27 protected void execute() { 27 protected void execute() {
......
1 package org.onlab.onos.cli.net; 1 package org.onlab.onos.cli.net;
2 2
3 +import com.fasterxml.jackson.databind.JsonNode;
4 +import com.fasterxml.jackson.databind.ObjectMapper;
5 +import com.fasterxml.jackson.databind.node.ArrayNode;
6 +import com.fasterxml.jackson.databind.node.ObjectNode;
3 import org.apache.karaf.shell.commands.Command; 7 import org.apache.karaf.shell.commands.Command;
4 import org.onlab.onos.cli.AbstractShellCommand; 8 import org.onlab.onos.cli.AbstractShellCommand;
9 +import org.onlab.onos.net.ConnectPoint;
10 +import org.onlab.onos.net.Link;
11 +import org.onlab.onos.net.NetworkResource;
12 +import org.onlab.onos.net.intent.ConnectivityIntent;
5 import org.onlab.onos.net.intent.Intent; 13 import org.onlab.onos.net.intent.Intent;
6 import org.onlab.onos.net.intent.IntentService; 14 import org.onlab.onos.net.intent.IntentService;
7 import org.onlab.onos.net.intent.IntentState; 15 import org.onlab.onos.net.intent.IntentState;
16 +import org.onlab.onos.net.intent.LinkCollectionIntent;
17 +import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
18 +import org.onlab.onos.net.intent.PathIntent;
19 +import org.onlab.onos.net.intent.PointToPointIntent;
20 +import org.onlab.onos.net.intent.SinglePointToMultiPointIntent;
21 +
22 +import java.util.List;
23 +import java.util.Set;
8 24
9 /** 25 /**
10 * Lists the inventory of intents and their states. 26 * Lists the inventory of intents and their states.
...@@ -16,11 +32,137 @@ public class IntentsListCommand extends AbstractShellCommand { ...@@ -16,11 +32,137 @@ public class IntentsListCommand extends AbstractShellCommand {
16 @Override 32 @Override
17 protected void execute() { 33 protected void execute() {
18 IntentService service = get(IntentService.class); 34 IntentService service = get(IntentService.class);
19 - for (Intent intent : service.getIntents()) { 35 + if (outputJson()) {
20 - IntentState state = service.getIntentState(intent.id()); 36 + print("%s", json(service, service.getIntents()));
21 - print("id=%s, state=%s, appId=%s, %s", 37 + } else {
22 - intent.id(), state, intent.appId().name(), intent); 38 + for (Intent intent : service.getIntents()) {
39 + IntentState state = service.getIntentState(intent.id());
40 + print("id=%s, state=%s, type=%s, appId=%s",
41 + intent.id(), state, intent.getClass().getSimpleName(),
42 + intent.appId().name());
43 + printDetails(service, intent);
44 + }
45 + }
46 + }
47 +
48 + private void printDetails(IntentService service, Intent intent) {
49 + if (intent.resources() != null && !intent.resources().isEmpty()) {
50 + print(" resources=%s", intent.resources());
51 + }
52 + if (intent instanceof ConnectivityIntent) {
53 + ConnectivityIntent ci = (ConnectivityIntent) intent;
54 + if (!ci.selector().criteria().isEmpty()) {
55 + print(" selector=%s", ci.selector().criteria());
56 + }
57 + if (!ci.treatment().instructions().isEmpty()) {
58 + print(" treatment=%s", ci.treatment().instructions());
59 + }
60 + }
61 +
62 + if (intent instanceof PointToPointIntent) {
63 + PointToPointIntent pi = (PointToPointIntent) intent;
64 + print(" ingress=%s, egress=%s", pi.ingressPoint(), pi.egressPoint());
65 + } else if (intent instanceof MultiPointToSinglePointIntent) {
66 + MultiPointToSinglePointIntent pi = (MultiPointToSinglePointIntent) intent;
67 + print(" ingress=%s, egress=%s", pi.ingressPoints(), pi.egressPoint());
68 + } else if (intent instanceof SinglePointToMultiPointIntent) {
69 + SinglePointToMultiPointIntent pi = (SinglePointToMultiPointIntent) intent;
70 + print(" ingress=%s, egress=%s", pi.ingressPoint(), pi.egressPoints());
71 + } else if (intent instanceof PathIntent) {
72 + PathIntent pi = (PathIntent) intent;
73 + print(" path=%s, cost=%d", pi.path().links(), pi.path().cost());
74 + } else if (intent instanceof LinkCollectionIntent) {
75 + LinkCollectionIntent li = (LinkCollectionIntent) intent;
76 + print(" links=%s", li.links());
77 + print(" egress=%s", li.egressPoint());
78 + }
79 +
80 + List<Intent> installable = service.getInstallableIntents(intent.id());
81 + if (installable != null && !installable.isEmpty()) {
82 + print(" installable=%s", installable);
83 + }
84 + }
85 +
86 + // Produces JSON array of the specified intents.
87 + private JsonNode json(IntentService service, Iterable<Intent> intents) {
88 + ObjectMapper mapper = new ObjectMapper();
89 + ArrayNode result = mapper.createArrayNode();
90 + for (Intent intent : intents) {
91 + result.add(json(service, mapper, intent));
92 + }
93 + return result;
94 + }
95 +
96 + private JsonNode json(IntentService service, ObjectMapper mapper, Intent intent) {
97 + ObjectNode result = mapper.createObjectNode()
98 + .put("id", intent.id().toString())
99 + .put("type", intent.getClass().getSimpleName())
100 + .put("appId", intent.appId().name());
101 +
102 + IntentState state = service.getIntentState(intent.id());
103 + if (state != null) {
104 + result.put("state", state.toString());
105 + }
106 +
107 + if (intent.resources() != null && !intent.resources().isEmpty()) {
108 + ArrayNode rnode = mapper.createArrayNode();
109 + for (NetworkResource resource : intent.resources()) {
110 + rnode.add(resource.toString());
111 + }
112 + result.set("resources", rnode);
113 + }
114 +
115 + if (intent instanceof ConnectivityIntent) {
116 + ConnectivityIntent ci = (ConnectivityIntent) intent;
117 + if (!ci.selector().criteria().isEmpty()) {
118 + result.put("selector", ci.selector().criteria().toString());
119 + }
120 + if (!ci.treatment().instructions().isEmpty()) {
121 + result.put("treatment", ci.treatment().instructions().toString());
122 + }
123 + }
124 +
125 + if (intent instanceof PathIntent) {
126 + PathIntent pi = (PathIntent) intent;
127 + ArrayNode pnode = mapper.createArrayNode();
128 + for (Link link : pi.path().links()) {
129 + pnode.add(link.toString());
130 + }
131 + result.set("path", pnode);
132 +
133 + } else if (intent instanceof PointToPointIntent) {
134 + PointToPointIntent pi = (PointToPointIntent) intent;
135 + result.set("ingress", LinksListCommand.json(mapper, pi.ingressPoint()));
136 + result.set("egress", LinksListCommand.json(mapper, pi.egressPoint()));
137 +
138 + } else if (intent instanceof MultiPointToSinglePointIntent) {
139 + MultiPointToSinglePointIntent pi = (MultiPointToSinglePointIntent) intent;
140 + result.set("ingress", json(mapper, pi.ingressPoints()));
141 + result.set("egress", LinksListCommand.json(mapper, pi.egressPoint()));
142 +
143 + } else if (intent instanceof SinglePointToMultiPointIntent) {
144 + SinglePointToMultiPointIntent pi = (SinglePointToMultiPointIntent) intent;
145 + result.set("ingress", LinksListCommand.json(mapper, pi.ingressPoint()));
146 + result.set("egress", json(mapper, pi.egressPoints()));
147 +
148 + } else if (intent instanceof LinkCollectionIntent) {
149 + LinkCollectionIntent li = (LinkCollectionIntent) intent;
150 + result.set("links", LinksListCommand.json(li.links()));
151 + }
152 +
153 + List<Intent> installable = service.getInstallableIntents(intent.id());
154 + if (installable != null && !installable.isEmpty()) {
155 + result.set("installable", json(service, installable));
156 + }
157 + return result;
158 + }
159 +
160 + private JsonNode json(ObjectMapper mapper, Set<ConnectPoint> connectPoints) {
161 + ArrayNode result = mapper.createArrayNode();
162 + for (ConnectPoint cp : connectPoints) {
163 + result.add(LinksListCommand.json(mapper, cp));
23 } 164 }
165 + return result;
24 } 166 }
25 167
26 } 168 }
......
...@@ -3,10 +3,11 @@ package org.onlab.onos.cluster; ...@@ -3,10 +3,11 @@ package org.onlab.onos.cluster;
3 import java.util.List; 3 import java.util.List;
4 import java.util.Objects; 4 import java.util.Objects;
5 5
6 +import com.google.common.base.MoreObjects;
6 import com.google.common.collect.ImmutableList; 7 import com.google.common.collect.ImmutableList;
7 8
8 /** 9 /**
9 - * A container for detailed role information for a device, 10 + * An immutable container for role information for a device,
10 * within the current cluster. Role attributes include current 11 * within the current cluster. Role attributes include current
11 * master and a preference-ordered list of backup nodes. 12 * master and a preference-ordered list of backup nodes.
12 */ 13 */
...@@ -52,12 +53,9 @@ public class RoleInfo { ...@@ -52,12 +53,9 @@ public class RoleInfo {
52 53
53 @Override 54 @Override
54 public String toString() { 55 public String toString() {
55 - final StringBuilder builder = new StringBuilder(); 56 + return MoreObjects.toStringHelper(this.getClass())
56 - builder.append("master:").append(master).append(","); 57 + .add("master", master)
57 - builder.append("backups:"); 58 + .add("backups", backups)
58 - for (NodeId n : backups) { 59 + .toString();
59 - builder.append(" ").append(n);
60 - }
61 - return builder.toString();
62 } 60 }
63 } 61 }
......
1 package org.onlab.onos.mastership; 1 package org.onlab.onos.mastership;
2 2
3 import org.onlab.onos.cluster.NodeId; 3 import org.onlab.onos.cluster.NodeId;
4 +import org.onlab.onos.cluster.RoleInfo;
4 import org.onlab.onos.event.AbstractEvent; 5 import org.onlab.onos.event.AbstractEvent;
5 import org.onlab.onos.net.DeviceId; 6 import org.onlab.onos.net.DeviceId;
6 7
...@@ -9,9 +10,8 @@ import org.onlab.onos.net.DeviceId; ...@@ -9,9 +10,8 @@ import org.onlab.onos.net.DeviceId;
9 */ 10 */
10 public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceId> { 11 public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceId> {
11 12
12 - //do we worry about explicitly setting slaves/equals? probably not, 13 + //Contains master and standby information.
13 - //to keep it simple 14 + RoleInfo roleInfo;
14 - NodeId node;
15 15
16 /** 16 /**
17 * Type of mastership events. 17 * Type of mastership events.
...@@ -29,16 +29,16 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -29,16 +29,16 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
29 } 29 }
30 30
31 /** 31 /**
32 - * Creates an event of a given type and for the specified device, master, 32 + * Creates an event of a given type and for the specified device,
33 - * and the current time. 33 + * role information, and the current time.
34 * 34 *
35 * @param type device event type 35 * @param type device event type
36 * @param device event device subject 36 * @param device event device subject
37 - * @param node master ID subject 37 + * @param info mastership role information subject
38 */ 38 */
39 - public MastershipEvent(Type type, DeviceId device, NodeId node) { 39 + public MastershipEvent(Type type, DeviceId device, RoleInfo info) {
40 super(type, device); 40 super(type, device);
41 - this.node = node; 41 + this.roleInfo = info;
42 } 42 }
43 43
44 /** 44 /**
...@@ -50,9 +50,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -50,9 +50,9 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
50 * @param master master ID subject 50 * @param master master ID subject
51 * @param time occurrence time 51 * @param time occurrence time
52 */ 52 */
53 - public MastershipEvent(Type type, DeviceId device, NodeId master, long time) { 53 + public MastershipEvent(Type type, DeviceId device, RoleInfo info, long time) {
54 super(type, device, time); 54 super(type, device, time);
55 - this.node = master; 55 + this.roleInfo = info;
56 } 56 }
57 57
58 /** 58 /**
...@@ -63,7 +63,17 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -63,7 +63,17 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
63 * 63 *
64 * @return node ID as a subject 64 * @return node ID as a subject
65 */ 65 */
66 + //XXX to-be removed - or keep for convenience?
66 public NodeId node() { 67 public NodeId node() {
67 - return node; 68 + return roleInfo.master();
69 + }
70 +
71 + /**
72 + * Returns the current role state for the subject.
73 + *
74 + * @return RoleInfo associated with Device ID subject
75 + */
76 + public RoleInfo roleInfo() {
77 + return roleInfo;
68 } 78 }
69 } 79 }
......
...@@ -27,7 +27,7 @@ public class DefaultFlowEntry extends DefaultFlowRule ...@@ -27,7 +27,7 @@ public class DefaultFlowEntry extends DefaultFlowRule
27 TrafficTreatment treatment, int priority, FlowEntryState state, 27 TrafficTreatment treatment, int priority, FlowEntryState state,
28 long life, long packets, long bytes, long flowId, 28 long life, long packets, long bytes, long flowId,
29 int timeout) { 29 int timeout) {
30 - super(deviceId, selector, treatment, priority, flowId, timeout); 30 + super(deviceId, selector, treatment, priority, flowId, timeout, false);
31 this.state = state; 31 this.state = state;
32 this.life = life; 32 this.life = life;
33 this.packets = packets; 33 this.packets = packets;
......
...@@ -24,16 +24,18 @@ public class DefaultFlowRule implements FlowRule { ...@@ -24,16 +24,18 @@ public class DefaultFlowRule implements FlowRule {
24 private final short appId; 24 private final short appId;
25 25
26 private final int timeout; 26 private final int timeout;
27 + private final boolean permanent;
27 28
28 29
29 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, 30 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
30 TrafficTreatment treatment, int priority, long flowId, 31 TrafficTreatment treatment, int priority, long flowId,
31 - int timeout) { 32 + int timeout, boolean permanent) {
32 this.deviceId = deviceId; 33 this.deviceId = deviceId;
33 this.priority = priority; 34 this.priority = priority;
34 this.selector = selector; 35 this.selector = selector;
35 this.treatment = treatment; 36 this.treatment = treatment;
36 this.timeout = timeout; 37 this.timeout = timeout;
38 + this.permanent = permanent;
37 this.created = System.currentTimeMillis(); 39 this.created = System.currentTimeMillis();
38 40
39 this.appId = (short) (flowId >>> 48); 41 this.appId = (short) (flowId >>> 48);
...@@ -42,7 +44,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -42,7 +44,7 @@ public class DefaultFlowRule implements FlowRule {
42 44
43 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, 45 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
44 TrafficTreatment treatement, int priority, ApplicationId appId, 46 TrafficTreatment treatement, int priority, ApplicationId appId,
45 - int timeout) { 47 + int timeout, boolean permanent) {
46 48
47 if (priority < FlowRule.MIN_PRIORITY) { 49 if (priority < FlowRule.MIN_PRIORITY) {
48 throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY); 50 throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
...@@ -54,6 +56,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -54,6 +56,7 @@ public class DefaultFlowRule implements FlowRule {
54 this.treatment = treatement; 56 this.treatment = treatement;
55 this.appId = appId.id(); 57 this.appId = appId.id();
56 this.timeout = timeout; 58 this.timeout = timeout;
59 + this.permanent = permanent;
57 this.created = System.currentTimeMillis(); 60 this.created = System.currentTimeMillis();
58 61
59 this.id = FlowId.valueOf((((long) this.appId) << 48) | (this.hash() & 0x0000ffffffffL)); 62 this.id = FlowId.valueOf((((long) this.appId) << 48) | (this.hash() & 0x0000ffffffffL));
...@@ -67,6 +70,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -67,6 +70,7 @@ public class DefaultFlowRule implements FlowRule {
67 this.appId = rule.appId(); 70 this.appId = rule.appId();
68 this.id = rule.id(); 71 this.id = rule.id();
69 this.timeout = rule.timeout(); 72 this.timeout = rule.timeout();
73 + this.permanent = rule.isPermanent();
70 this.created = System.currentTimeMillis(); 74 this.created = System.currentTimeMillis();
71 75
72 } 76 }
...@@ -157,4 +161,9 @@ public class DefaultFlowRule implements FlowRule { ...@@ -157,4 +161,9 @@ public class DefaultFlowRule implements FlowRule {
157 return timeout; 161 return timeout;
158 } 162 }
159 163
164 + @Override
165 + public boolean isPermanent() {
166 + return permanent;
167 + }
168 +
160 } 169 }
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 -import com.google.common.collect.ImmutableSet; 3 +import java.util.HashMap;
4 +import java.util.Map;
5 +import java.util.Objects;
6 +import java.util.Set;
7 +
4 import org.onlab.onos.net.PortNumber; 8 import org.onlab.onos.net.PortNumber;
5 import org.onlab.onos.net.flow.criteria.Criteria; 9 import org.onlab.onos.net.flow.criteria.Criteria;
6 import org.onlab.onos.net.flow.criteria.Criterion; 10 import org.onlab.onos.net.flow.criteria.Criterion;
...@@ -8,10 +12,8 @@ import org.onlab.packet.IpPrefix; ...@@ -8,10 +12,8 @@ import org.onlab.packet.IpPrefix;
8 import org.onlab.packet.MacAddress; 12 import org.onlab.packet.MacAddress;
9 import org.onlab.packet.VlanId; 13 import org.onlab.packet.VlanId;
10 14
11 -import java.util.HashMap; 15 +import com.google.common.base.MoreObjects;
12 -import java.util.Map; 16 +import com.google.common.collect.ImmutableSet;
13 -import java.util.Objects;
14 -import java.util.Set;
15 17
16 /** 18 /**
17 * Default traffic selector implementation. 19 * Default traffic selector implementation.
...@@ -52,6 +54,13 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -52,6 +54,13 @@ public final class DefaultTrafficSelector implements TrafficSelector {
52 return false; 54 return false;
53 } 55 }
54 56
57 + @Override
58 + public String toString() {
59 + return MoreObjects.toStringHelper(getClass())
60 + .add("criteria", criteria)
61 + .toString();
62 + }
63 +
55 /** 64 /**
56 * Returns a new traffic selector builder. 65 * Returns a new traffic selector builder.
57 * 66 *
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 +import java.util.LinkedList;
4 +import java.util.List;
5 +import java.util.Objects;
6 +
3 import org.onlab.onos.net.PortNumber; 7 import org.onlab.onos.net.PortNumber;
4 import org.onlab.onos.net.flow.instructions.Instruction; 8 import org.onlab.onos.net.flow.instructions.Instruction;
5 import org.onlab.onos.net.flow.instructions.Instructions; 9 import org.onlab.onos.net.flow.instructions.Instructions;
...@@ -7,12 +11,9 @@ import org.onlab.packet.IpPrefix; ...@@ -7,12 +11,9 @@ import org.onlab.packet.IpPrefix;
7 import org.onlab.packet.MacAddress; 11 import org.onlab.packet.MacAddress;
8 import org.onlab.packet.VlanId; 12 import org.onlab.packet.VlanId;
9 13
14 +import com.google.common.base.MoreObjects;
10 import com.google.common.collect.ImmutableList; 15 import com.google.common.collect.ImmutableList;
11 16
12 -import java.util.LinkedList;
13 -import java.util.List;
14 -import java.util.Objects;
15 -
16 /** 17 /**
17 * Default traffic treatment implementation. 18 * Default traffic treatment implementation.
18 */ 19 */
...@@ -62,6 +63,13 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -62,6 +63,13 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
62 return false; 63 return false;
63 } 64 }
64 65
66 + @Override
67 + public String toString() {
68 + return MoreObjects.toStringHelper(getClass())
69 + .add("instructions", instructions)
70 + .toString();
71 + }
72 +
65 /** 73 /**
66 * Builds a list of treatments following the following order. 74 * Builds a list of treatments following the following order.
67 * Modifications -> Group -> Output (including drop) 75 * Modifications -> Group -> Output (including drop)
......
...@@ -59,8 +59,16 @@ public interface FlowRule extends BatchOperationTarget { ...@@ -59,8 +59,16 @@ public interface FlowRule extends BatchOperationTarget {
59 59
60 /** 60 /**
61 * Returns the timeout for this flow requested by an application. 61 * Returns the timeout for this flow requested by an application.
62 + *
62 * @return integer value of the timeout 63 * @return integer value of the timeout
63 */ 64 */
64 int timeout(); 65 int timeout();
65 66
67 + /**
68 + * Returns whether the flow is permanent i.e. does not time out.
69 + *
70 + * @return true if the flow is permanent, otherwise false
71 + */
72 + boolean isPermanent();
73 +
66 } 74 }
......
1 package org.onlab.onos.net.intent; 1 package org.onlab.onos.net.intent;
2 2
3 3
4 +import java.util.List;
5 +
4 /** 6 /**
5 * Service for application submitting or withdrawing their intents. 7 * Service for application submitting or withdrawing their intents.
6 */ 8 */
...@@ -68,6 +70,15 @@ public interface IntentService { ...@@ -68,6 +70,15 @@ public interface IntentService {
68 IntentState getIntentState(IntentId id); 70 IntentState getIntentState(IntentId id);
69 71
70 /** 72 /**
73 + * Returns the list of the installable events associated with the specified
74 + * top-level intent.
75 + *
76 + * @param intentId top-level intent identifier
77 + * @return compiled installable intents
78 + */
79 + List<Intent> getInstallableIntents(IntentId intentId);
80 +
81 + /**
71 * Adds the specified listener for intent events. 82 * Adds the specified listener for intent events.
72 * 83 *
73 * @param listener listener to be added 84 * @param listener listener to be added
......
...@@ -196,6 +196,11 @@ public class FakeIntentManager implements TestableIntentService { ...@@ -196,6 +196,11 @@ public class FakeIntentManager implements TestableIntentService {
196 } 196 }
197 197
198 @Override 198 @Override
199 + public List<Intent> getInstallableIntents(IntentId intentId) {
200 + return installables.get(intentId);
201 + }
202 +
203 + @Override
199 public void addListener(IntentListener listener) { 204 public void addListener(IntentListener listener) {
200 listeners.add(listener); 205 listeners.add(listener);
201 } 206 }
......
...@@ -327,6 +327,10 @@ public class FlowRuleManager ...@@ -327,6 +327,10 @@ public class FlowRuleManager
327 if (storedRule == null) { 327 if (storedRule == null) {
328 return false; 328 return false;
329 } 329 }
330 + if (storedRule.isPermanent()) {
331 + return true;
332 + }
333 +
330 final long timeout = storedRule.timeout() * 1000; 334 final long timeout = storedRule.timeout() * 1000;
331 final long currentTime = System.currentTimeMillis(); 335 final long currentTime = System.currentTimeMillis();
332 if (storedRule.packets() != swRule.packets()) { 336 if (storedRule.packets() != swRule.packets()) {
......
...@@ -153,6 +153,12 @@ public class IntentManager ...@@ -153,6 +153,12 @@ public class IntentManager
153 } 153 }
154 154
155 @Override 155 @Override
156 + public List<Intent> getInstallableIntents(IntentId intentId) {
157 + checkNotNull(intentId, INTENT_ID_NULL);
158 + return store.getInstallableIntents(intentId);
159 + }
160 +
161 + @Override
156 public void addListener(IntentListener listener) { 162 public void addListener(IntentListener listener) {
157 listenerRegistry.addListener(listener); 163 listenerRegistry.addListener(listener);
158 } 164 }
......
...@@ -117,7 +117,7 @@ public class LinkCollectionIntentInstaller implements IntentInstaller<LinkCollec ...@@ -117,7 +117,7 @@ public class LinkCollectionIntentInstaller implements IntentInstaller<LinkCollec
117 TrafficTreatment treatment = builder().setOutput(outPort).build(); 117 TrafficTreatment treatment = builder().setOutput(outPort).build();
118 118
119 FlowRule rule = new DefaultFlowRule(deviceId, 119 FlowRule rule = new DefaultFlowRule(deviceId,
120 - selector, treatment, 123, appId, 600); 120 + selector, treatment, 123, appId, 0, true);
121 121
122 return new FlowRuleBatchEntry(operation, rule); 122 return new FlowRuleBatchEntry(operation, rule);
123 } 123 }
......
...@@ -73,7 +73,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -73,7 +73,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
73 73
74 FlowRule rule = new DefaultFlowRule(link.src().deviceId(), 74 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
75 builder.build(), treatment, 75 builder.build(), treatment,
76 - 123, appId, 15); 76 + 123, appId, 0, true);
77 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)); 77 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
78 prev = link.dst(); 78 prev = link.dst();
79 } 79 }
...@@ -95,7 +95,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { ...@@ -95,7 +95,7 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
95 .setOutput(link.src().port()).build(); 95 .setOutput(link.src().port()).build();
96 FlowRule rule = new DefaultFlowRule(link.src().deviceId(), 96 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
97 builder.build(), treatment, 97 builder.build(), treatment,
98 - 123, appId, 600); 98 + 123, appId, 0, true);
99 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule)); 99 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
100 prev = link.dst(); 100 prev = link.dst();
101 } 101 }
......
1 package org.onlab.onos.net.flow.impl; 1 package org.onlab.onos.net.flow.impl;
2 2
3 import static java.util.Collections.EMPTY_LIST; 3 import static java.util.Collections.EMPTY_LIST;
4 -import static org.junit.Assert.*; 4 +import static org.junit.Assert.assertEquals;
5 +import static org.junit.Assert.assertFalse;
6 +import static org.junit.Assert.assertNotNull;
7 +import static org.junit.Assert.assertTrue;
8 +import static org.junit.Assert.fail;
5 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED; 9 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
6 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; 10 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
7 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED; 11 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
...@@ -115,7 +119,7 @@ public class FlowRuleManagerTest { ...@@ -115,7 +119,7 @@ public class FlowRuleManagerTest {
115 private FlowRule flowRule(int tsval, int trval) { 119 private FlowRule flowRule(int tsval, int trval) {
116 TestSelector ts = new TestSelector(tsval); 120 TestSelector ts = new TestSelector(tsval);
117 TestTreatment tr = new TestTreatment(trval); 121 TestTreatment tr = new TestTreatment(trval);
118 - return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT); 122 + return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT, false);
119 } 123 }
120 124
121 125
......
...@@ -5,6 +5,7 @@ import static org.junit.Assert.*; ...@@ -5,6 +5,7 @@ import static org.junit.Assert.*;
5 5
6 import java.util.Collections; 6 import java.util.Collections;
7 import java.util.Map; 7 import java.util.Map;
8 +import java.util.LinkedList;
8 import java.util.concurrent.CountDownLatch; 9 import java.util.concurrent.CountDownLatch;
9 import java.util.concurrent.TimeUnit; 10 import java.util.concurrent.TimeUnit;
10 11
...@@ -12,6 +13,7 @@ import org.junit.After; ...@@ -12,6 +13,7 @@ import org.junit.After;
12 import org.junit.Before; 13 import org.junit.Before;
13 import org.junit.Test; 14 import org.junit.Test;
14 import org.onlab.onos.cluster.NodeId; 15 import org.onlab.onos.cluster.NodeId;
16 +import org.onlab.onos.cluster.RoleInfo;
15 import org.onlab.onos.event.AbstractListenerRegistry; 17 import org.onlab.onos.event.AbstractListenerRegistry;
16 import org.onlab.onos.event.DefaultEventSinkRegistry; 18 import org.onlab.onos.event.DefaultEventSinkRegistry;
17 import org.onlab.onos.event.Event; 19 import org.onlab.onos.event.Event;
...@@ -87,7 +89,8 @@ public class ReplicaInfoManagerTest { ...@@ -87,7 +89,8 @@ public class ReplicaInfoManagerTest {
87 service.addListener(new MasterNodeCheck(latch, DID1, NID1)); 89 service.addListener(new MasterNodeCheck(latch, DID1, NID1));
88 90
89 // fake MastershipEvent 91 // fake MastershipEvent
90 - eventDispatcher.post(new MastershipEvent(Type.MASTER_CHANGED, DID1, NID1)); 92 + eventDispatcher.post(new MastershipEvent(Type.MASTER_CHANGED, DID1,
93 + new RoleInfo(NID1, new LinkedList<NodeId>())));
91 94
92 assertTrue(latch.await(1, TimeUnit.SECONDS)); 95 assertTrue(latch.await(1, TimeUnit.SECONDS));
93 } 96 }
......
...@@ -136,13 +136,13 @@ implements MastershipStore { ...@@ -136,13 +136,13 @@ implements MastershipStore {
136 rv.reassign(nodeId, STANDBY, NONE); 136 rv.reassign(nodeId, STANDBY, NONE);
137 roleMap.put(deviceId, rv); 137 roleMap.put(deviceId, rv);
138 updateTerm(deviceId); 138 updateTerm(deviceId);
139 - return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId); 139 + return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
140 case NONE: 140 case NONE:
141 rv.add(MASTER, nodeId); 141 rv.add(MASTER, nodeId);
142 rv.reassign(nodeId, STANDBY, NONE); 142 rv.reassign(nodeId, STANDBY, NONE);
143 roleMap.put(deviceId, rv); 143 roleMap.put(deviceId, rv);
144 updateTerm(deviceId); 144 updateTerm(deviceId);
145 - return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId); 145 + return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
146 default: 146 default:
147 log.warn("unknown Mastership Role {}", role); 147 log.warn("unknown Mastership Role {}", role);
148 return null; 148 return null;
...@@ -306,7 +306,7 @@ implements MastershipStore { ...@@ -306,7 +306,7 @@ implements MastershipStore {
306 roleMap.put(deviceId, rv); 306 roleMap.put(deviceId, rv);
307 Integer term = terms.get(deviceId); 307 Integer term = terms.get(deviceId);
308 terms.put(deviceId, ++term); 308 terms.put(deviceId, ++term);
309 - return new MastershipEvent(MASTER_CHANGED, deviceId, backup); 309 + return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
310 } 310 }
311 } 311 }
312 312
...@@ -373,7 +373,7 @@ implements MastershipStore { ...@@ -373,7 +373,7 @@ implements MastershipStore {
373 return; 373 return;
374 } 374 }
375 notifyDelegate(new MastershipEvent( 375 notifyDelegate(new MastershipEvent(
376 - MASTER_CHANGED, event.getKey(), event.getValue().get(MASTER))); 376 + MASTER_CHANGED, event.getKey(), event.getValue().roleInfo()));
377 } 377 }
378 378
379 @Override 379 @Override
......
...@@ -10,6 +10,9 @@ import org.onlab.onos.cluster.NodeId; ...@@ -10,6 +10,9 @@ import org.onlab.onos.cluster.NodeId;
10 import org.onlab.onos.cluster.RoleInfo; 10 import org.onlab.onos.cluster.RoleInfo;
11 import org.onlab.onos.net.MastershipRole; 11 import org.onlab.onos.net.MastershipRole;
12 12
13 +import com.google.common.base.MoreObjects;
14 +import com.google.common.base.MoreObjects.ToStringHelper;
15 +
13 /** 16 /**
14 * A structure that holds node mastership roles associated with a 17 * A structure that holds node mastership roles associated with a
15 * {@link DeviceId}. This structure needs to be locked through IMap. 18 * {@link DeviceId}. This structure needs to be locked through IMap.
...@@ -109,14 +112,10 @@ public class RoleValue { ...@@ -109,14 +112,10 @@ public class RoleValue {
109 112
110 @Override 113 @Override
111 public String toString() { 114 public String toString() {
112 - final StringBuilder builder = new StringBuilder(); 115 + ToStringHelper helper = MoreObjects.toStringHelper(this.getClass());
113 for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) { 116 for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) {
114 - builder.append(el.getKey().toString()).append(": ["); 117 + helper.add(el.getKey().toString(), el.getValue());
115 - for (NodeId n : el.getValue()) {
116 - builder.append(n);
117 - }
118 - builder.append("]\n");
119 } 118 }
120 - return builder.toString(); 119 + return helper.toString();
121 } 120 }
122 } 121 }
......
...@@ -29,6 +29,8 @@ import org.onlab.onos.store.AbstractStore; ...@@ -29,6 +29,8 @@ import org.onlab.onos.store.AbstractStore;
29 import org.onlab.packet.IpPrefix; 29 import org.onlab.packet.IpPrefix;
30 import org.slf4j.Logger; 30 import org.slf4j.Logger;
31 31
32 +import com.google.common.collect.Lists;
33 +
32 import static org.onlab.onos.mastership.MastershipEvent.Type.*; 34 import static org.onlab.onos.mastership.MastershipEvent.Type.*;
33 35
34 /** 36 /**
...@@ -89,7 +91,8 @@ public class SimpleMastershipStore ...@@ -89,7 +91,8 @@ public class SimpleMastershipStore
89 } 91 }
90 } 92 }
91 93
92 - return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId); 94 + return new MastershipEvent(MASTER_CHANGED, deviceId,
95 + new RoleInfo(nodeId, Lists.newLinkedList(backups)));
93 } 96 }
94 97
95 @Override 98 @Override
...@@ -196,7 +199,8 @@ public class SimpleMastershipStore ...@@ -196,7 +199,8 @@ public class SimpleMastershipStore
196 } else { 199 } else {
197 masterMap.put(deviceId, backup); 200 masterMap.put(deviceId, backup);
198 termMap.get(deviceId).incrementAndGet(); 201 termMap.get(deviceId).incrementAndGet();
199 - return new MastershipEvent(MASTER_CHANGED, deviceId, backup); 202 + return new MastershipEvent(MASTER_CHANGED, deviceId,
203 + new RoleInfo(backup, Lists.newLinkedList(backups)));
200 } 204 }
201 case STANDBY: 205 case STANDBY:
202 case NONE: 206 case NONE:
......
...@@ -78,7 +78,7 @@ public class FlowEntryBuilder { ...@@ -78,7 +78,7 @@ public class FlowEntryBuilder {
78 if (addedRule) { 78 if (addedRule) {
79 FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), 79 FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
80 buildSelector(), buildTreatment(), stat.getPriority(), 80 buildSelector(), buildTreatment(), stat.getPriority(),
81 - stat.getCookie().getValue(), stat.getIdleTimeout()); 81 + stat.getCookie().getValue(), stat.getIdleTimeout(), false);
82 return new DefaultFlowEntry(rule, FlowEntryState.ADDED, 82 return new DefaultFlowEntry(rule, FlowEntryState.ADDED,
83 stat.getDurationSec(), stat.getPacketCount().getValue(), 83 stat.getDurationSec(), stat.getPacketCount().getValue(),
84 stat.getByteCount().getValue()); 84 stat.getByteCount().getValue());
...@@ -86,7 +86,7 @@ public class FlowEntryBuilder { ...@@ -86,7 +86,7 @@ public class FlowEntryBuilder {
86 } else { 86 } else {
87 FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), 87 FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
88 buildSelector(), null, removed.getPriority(), 88 buildSelector(), null, removed.getPriority(),
89 - removed.getCookie().getValue(), removed.getIdleTimeout()); 89 + removed.getCookie().getValue(), removed.getIdleTimeout(), false);
90 return new DefaultFlowEntry(rule, FlowEntryState.REMOVED, removed.getDurationSec(), 90 return new DefaultFlowEntry(rule, FlowEntryState.REMOVED, removed.getDurationSec(),
91 removed.getPacketCount().getValue(), removed.getByteCount().getValue()); 91 removed.getPacketCount().getValue(), removed.getByteCount().getValue());
92 } 92 }
......
1 +#!/bin/bash
2 +# -----------------------------------------------------------------------------
3 +# Executes selected set of ONOS commands using the batch mode.
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-batch.$$
14 +trap "rm -f $aux" EXIT
15 +
16 +echo "$commands" | tr ',' '\n' > $aux
17 +onos $node -b <$aux