Merge remote-tracking branch 'origin/master'
diff --git a/apps/fwd/src/main/java/org/onlab/onos/fwd/ReactiveForwarding.java b/apps/fwd/src/main/java/org/onlab/onos/fwd/ReactiveForwarding.java
index 62b0b84..49a420f 100644
--- a/apps/fwd/src/main/java/org/onlab/onos/fwd/ReactiveForwarding.java
+++ b/apps/fwd/src/main/java/org/onlab/onos/fwd/ReactiveForwarding.java
@@ -1,5 +1,10 @@
package org.onlab.onos.fwd;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Dictionary;
+import java.util.Set;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -30,11 +35,6 @@
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
-import java.util.Dictionary;
-import java.util.Set;
-
-import static org.slf4j.LoggerFactory.getLogger;
-
/**
* Sample reactive forwarding application.
*/
@@ -206,7 +206,7 @@
treat.setOutput(portNumber);
FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
- builder.build(), treat.build(), PRIORITY, appId, TIMEOUT);
+ builder.build(), treat.build(), PRIORITY, appId, TIMEOUT, false);
flowRuleService.applyFlowRules(f);
}
diff --git a/cli/src/main/java/org/onlab/onos/cli/RolesCommand.java b/cli/src/main/java/org/onlab/onos/cli/RolesCommand.java
index b81a0c2..55f59d5 100644
--- a/cli/src/main/java/org/onlab/onos/cli/RolesCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/RolesCommand.java
@@ -21,7 +21,7 @@
description = "Lists mastership roles of nodes for each device.")
public class RolesCommand extends AbstractShellCommand {
- private static final String FMT_HDR = "%s: master=%s, standbys=%s";
+ private static final String FMT_HDR = "%s: master=%s, standbys=[ %s]";
@Override
protected void execute() {
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/RoleInfo.java b/core/api/src/main/java/org/onlab/onos/cluster/RoleInfo.java
index 45b96ab..767884d 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/RoleInfo.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/RoleInfo.java
@@ -3,10 +3,11 @@
import java.util.List;
import java.util.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
/**
- * A container for detailed role information for a device,
+ * An immutable container for role information for a device,
* within the current cluster. Role attributes include current
* master and a preference-ordered list of backup nodes.
*/
@@ -52,12 +53,9 @@
@Override
public String toString() {
- final StringBuilder builder = new StringBuilder();
- builder.append("master:").append(master).append(",");
- builder.append("backups:");
- for (NodeId n : backups) {
- builder.append(" ").append(n);
- }
- return builder.toString();
+ return MoreObjects.toStringHelper(this.getClass())
+ .add("master", master)
+ .add("backups", backups)
+ .toString();
}
}
diff --git a/core/api/src/main/java/org/onlab/onos/mastership/MastershipEvent.java b/core/api/src/main/java/org/onlab/onos/mastership/MastershipEvent.java
index 9f75fc4..dcb2d95 100644
--- a/core/api/src/main/java/org/onlab/onos/mastership/MastershipEvent.java
+++ b/core/api/src/main/java/org/onlab/onos/mastership/MastershipEvent.java
@@ -1,6 +1,7 @@
package org.onlab.onos.mastership;
import org.onlab.onos.cluster.NodeId;
+import org.onlab.onos.cluster.RoleInfo;
import org.onlab.onos.event.AbstractEvent;
import org.onlab.onos.net.DeviceId;
@@ -9,9 +10,8 @@
*/
public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceId> {
- //do we worry about explicitly setting slaves/equals? probably not,
- //to keep it simple
- NodeId node;
+ //Contains master and standby information.
+ RoleInfo roleInfo;
/**
* Type of mastership events.
@@ -29,16 +29,16 @@
}
/**
- * Creates an event of a given type and for the specified device, master,
- * and the current time.
+ * Creates an event of a given type and for the specified device,
+ * role information, and the current time.
*
* @param type device event type
* @param device event device subject
- * @param node master ID subject
+ * @param info mastership role information subject
*/
- public MastershipEvent(Type type, DeviceId device, NodeId node) {
+ public MastershipEvent(Type type, DeviceId device, RoleInfo info) {
super(type, device);
- this.node = node;
+ this.roleInfo = info;
}
/**
@@ -50,9 +50,9 @@
* @param master master ID subject
* @param time occurrence time
*/
- public MastershipEvent(Type type, DeviceId device, NodeId master, long time) {
+ public MastershipEvent(Type type, DeviceId device, RoleInfo info, long time) {
super(type, device, time);
- this.node = master;
+ this.roleInfo = info;
}
/**
@@ -63,7 +63,17 @@
*
* @return node ID as a subject
*/
+ //XXX to-be removed - or keep for convenience?
public NodeId node() {
- return node;
+ return roleInfo.master();
+ }
+
+ /**
+ * Returns the current role state for the subject.
+ *
+ * @return RoleInfo associated with Device ID subject
+ */
+ public RoleInfo roleInfo() {
+ return roleInfo;
}
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowEntry.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowEntry.java
index 905469f..cf448cb 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowEntry.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowEntry.java
@@ -27,7 +27,7 @@
TrafficTreatment treatment, int priority, FlowEntryState state,
long life, long packets, long bytes, long flowId,
int timeout) {
- super(deviceId, selector, treatment, priority, flowId, timeout);
+ super(deviceId, selector, treatment, priority, flowId, timeout, false);
this.state = state;
this.life = life;
this.packets = packets;
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
index 6ecbbbc..a6593a8 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
@@ -24,16 +24,18 @@
private final short appId;
private final int timeout;
+ private final boolean permanent;
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatment, int priority, long flowId,
- int timeout) {
+ int timeout, boolean permanent) {
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
this.treatment = treatment;
this.timeout = timeout;
+ this.permanent = permanent;
this.created = System.currentTimeMillis();
this.appId = (short) (flowId >>> 48);
@@ -42,7 +44,7 @@
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatement, int priority, ApplicationId appId,
- int timeout) {
+ int timeout, boolean permanent) {
if (priority < FlowRule.MIN_PRIORITY) {
throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
@@ -54,6 +56,7 @@
this.treatment = treatement;
this.appId = appId.id();
this.timeout = timeout;
+ this.permanent = permanent;
this.created = System.currentTimeMillis();
this.id = FlowId.valueOf((((long) this.appId) << 48) | (this.hash() & 0x0000ffffffffL));
@@ -67,6 +70,7 @@
this.appId = rule.appId();
this.id = rule.id();
this.timeout = rule.timeout();
+ this.permanent = rule.isPermanent();
this.created = System.currentTimeMillis();
}
@@ -157,4 +161,9 @@
return timeout;
}
+ @Override
+ public boolean isPermanent() {
+ return permanent;
+ }
+
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
index c63f247..3ac277d 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
@@ -59,8 +59,16 @@
/**
* Returns the timeout for this flow requested by an application.
+ *
* @return integer value of the timeout
*/
int timeout();
+ /**
+ * Returns whether the flow is permanent i.e. does not time out.
+ *
+ * @return true if the flow is permanent, otherwise false
+ */
+ boolean isPermanent();
+
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
index 525946e..67e0867 100644
--- a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
@@ -327,6 +327,10 @@
if (storedRule == null) {
return false;
}
+ if (storedRule.isPermanent()) {
+ return true;
+ }
+
final long timeout = storedRule.timeout() * 1000;
final long currentTime = System.currentTimeMillis();
if (storedRule.packets() != swRule.packets()) {
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/LinkCollectionIntentInstaller.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/LinkCollectionIntentInstaller.java
index 2deb837..b3eb0f5 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/LinkCollectionIntentInstaller.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/LinkCollectionIntentInstaller.java
@@ -117,7 +117,7 @@
TrafficTreatment treatment = builder().setOutput(outPort).build();
FlowRule rule = new DefaultFlowRule(deviceId,
- selector, treatment, 123, appId, 600);
+ selector, treatment, 123, appId, 0, true);
return new FlowRuleBatchEntry(operation, rule);
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
index 0baea5a..a7381b7 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
@@ -73,7 +73,7 @@
FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
builder.build(), treatment,
- 123, appId, 15);
+ 123, appId, 0, true);
rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
prev = link.dst();
}
@@ -95,7 +95,7 @@
.setOutput(link.src().port()).build();
FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
builder.build(), treatment,
- 123, appId, 600);
+ 123, appId, 0, true);
rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
prev = link.dst();
}
diff --git a/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java b/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
index dff740a..ca7cc07 100644
--- a/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
+++ b/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
@@ -1,7 +1,11 @@
package org.onlab.onos.net.flow.impl;
import static java.util.Collections.EMPTY_LIST;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
@@ -115,7 +119,7 @@
private FlowRule flowRule(int tsval, int trval) {
TestSelector ts = new TestSelector(tsval);
TestTreatment tr = new TestTreatment(trval);
- return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT);
+ return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT, false);
}
diff --git a/core/store/dist/src/test/java/org/onlab/onos/store/flow/impl/ReplicaInfoManagerTest.java b/core/store/dist/src/test/java/org/onlab/onos/store/flow/impl/ReplicaInfoManagerTest.java
index 105e37b..e2a3ddf 100644
--- a/core/store/dist/src/test/java/org/onlab/onos/store/flow/impl/ReplicaInfoManagerTest.java
+++ b/core/store/dist/src/test/java/org/onlab/onos/store/flow/impl/ReplicaInfoManagerTest.java
@@ -5,6 +5,7 @@
import java.util.Collections;
import java.util.Map;
+import java.util.LinkedList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -12,6 +13,7 @@
import org.junit.Before;
import org.junit.Test;
import org.onlab.onos.cluster.NodeId;
+import org.onlab.onos.cluster.RoleInfo;
import org.onlab.onos.event.AbstractListenerRegistry;
import org.onlab.onos.event.DefaultEventSinkRegistry;
import org.onlab.onos.event.Event;
@@ -87,7 +89,8 @@
service.addListener(new MasterNodeCheck(latch, DID1, NID1));
// fake MastershipEvent
- eventDispatcher.post(new MastershipEvent(Type.MASTER_CHANGED, DID1, NID1));
+ eventDispatcher.post(new MastershipEvent(Type.MASTER_CHANGED, DID1,
+ new RoleInfo(NID1, new LinkedList<NodeId>())));
assertTrue(latch.await(1, TimeUnit.SECONDS));
}
diff --git a/core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/DistributedMastershipStore.java b/core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/DistributedMastershipStore.java
index aaf056c..74ca8cd 100644
--- a/core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/DistributedMastershipStore.java
+++ b/core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/DistributedMastershipStore.java
@@ -136,13 +136,13 @@
rv.reassign(nodeId, STANDBY, NONE);
roleMap.put(deviceId, rv);
updateTerm(deviceId);
- return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId);
+ return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
case NONE:
rv.add(MASTER, nodeId);
rv.reassign(nodeId, STANDBY, NONE);
roleMap.put(deviceId, rv);
updateTerm(deviceId);
- return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId);
+ return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
default:
log.warn("unknown Mastership Role {}", role);
return null;
@@ -306,7 +306,7 @@
roleMap.put(deviceId, rv);
Integer term = terms.get(deviceId);
terms.put(deviceId, ++term);
- return new MastershipEvent(MASTER_CHANGED, deviceId, backup);
+ return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
}
}
@@ -373,7 +373,7 @@
return;
}
notifyDelegate(new MastershipEvent(
- MASTER_CHANGED, event.getKey(), event.getValue().get(MASTER)));
+ MASTER_CHANGED, event.getKey(), event.getValue().roleInfo()));
}
@Override
diff --git a/core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/RoleValue.java b/core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/RoleValue.java
index 1ccee6b..c156143 100644
--- a/core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/RoleValue.java
+++ b/core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/RoleValue.java
@@ -10,6 +10,9 @@
import org.onlab.onos.cluster.RoleInfo;
import org.onlab.onos.net.MastershipRole;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
/**
* A structure that holds node mastership roles associated with a
* {@link DeviceId}. This structure needs to be locked through IMap.
@@ -109,14 +112,10 @@
@Override
public String toString() {
- final StringBuilder builder = new StringBuilder();
+ ToStringHelper helper = MoreObjects.toStringHelper(this.getClass());
for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) {
- builder.append(el.getKey().toString()).append(": [");
- for (NodeId n : el.getValue()) {
- builder.append(n);
- }
- builder.append("]\n");
+ helper.add(el.getKey().toString(), el.getValue());
}
- return builder.toString();
+ return helper.toString();
}
}
diff --git a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleMastershipStore.java b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleMastershipStore.java
index fe34959..709c95a 100644
--- a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleMastershipStore.java
+++ b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleMastershipStore.java
@@ -29,6 +29,8 @@
import org.onlab.packet.IpPrefix;
import org.slf4j.Logger;
+import com.google.common.collect.Lists;
+
import static org.onlab.onos.mastership.MastershipEvent.Type.*;
/**
@@ -89,7 +91,8 @@
}
}
- return new MastershipEvent(MASTER_CHANGED, deviceId, nodeId);
+ return new MastershipEvent(MASTER_CHANGED, deviceId,
+ new RoleInfo(nodeId, Lists.newLinkedList(backups)));
}
@Override
@@ -196,7 +199,8 @@
} else {
masterMap.put(deviceId, backup);
termMap.get(deviceId).incrementAndGet();
- return new MastershipEvent(MASTER_CHANGED, deviceId, backup);
+ return new MastershipEvent(MASTER_CHANGED, deviceId,
+ new RoleInfo(backup, Lists.newLinkedList(backups)));
}
case STANDBY:
case NONE:
diff --git a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java
index 9924a71..cfc3134 100644
--- a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java
@@ -78,7 +78,7 @@
if (addedRule) {
FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
buildSelector(), buildTreatment(), stat.getPriority(),
- stat.getCookie().getValue(), stat.getIdleTimeout());
+ stat.getCookie().getValue(), stat.getIdleTimeout(), false);
return new DefaultFlowEntry(rule, FlowEntryState.ADDED,
stat.getDurationSec(), stat.getPacketCount().getValue(),
stat.getByteCount().getValue());
@@ -86,7 +86,7 @@
} else {
FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
buildSelector(), null, removed.getPriority(),
- removed.getCookie().getValue(), removed.getIdleTimeout());
+ removed.getCookie().getValue(), removed.getIdleTimeout(), false);
return new DefaultFlowEntry(rule, FlowEntryState.REMOVED, removed.getDurationSec(),
removed.getPacketCount().getValue(), removed.getByteCount().getValue());
}