ONOS-5808: Allocate BW from ConnectivityIntentCompiler and unit tests for partial failure
Change-Id: I2eb3c16efbce619db6d0d2ba415a35752a61ece4
diff --git a/core/api/src/main/java/org/onosproject/net/intent/Key.java b/core/api/src/main/java/org/onosproject/net/intent/Key.java
index b4dab2d..e8e4af7 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/Key.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/Key.java
@@ -19,6 +19,8 @@
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import org.onosproject.core.ApplicationId;
+import org.onosproject.net.resource.ResourceConsumer;
+import org.onosproject.net.resource.ResourceConsumerId;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
@@ -28,7 +30,7 @@
*/
// TODO maybe pull this up to utils
@Beta
-public abstract class Key implements Comparable<Key> {
+public abstract class Key implements Comparable<Key>, ResourceConsumer {
//TODO consider making this a HashCode object (worry about performance)
private final long hash;
@@ -54,6 +56,8 @@
* Creates a key based on the provided string.
* <p>
* Note: Two keys with equal value, but different appId, are not equal.
+ * Warning: it is caller responsibility to make sure the hashed value of
+ * {@code value} is unique.
* </p>
*
* @param key the provided string
@@ -79,6 +83,11 @@
return new LongKey(key, appId);
}
+ @Override
+ public ResourceConsumerId consumerId() {
+ return ResourceConsumerId.of(hash(), getClass());
+ }
+
private static final class StringKey extends Key {
private final ApplicationId appId;
diff --git a/core/api/src/test/java/org/onosproject/net/NetTestTools.java b/core/api/src/test/java/org/onosproject/net/NetTestTools.java
index d6227a7..dd03a09 100644
--- a/core/api/src/test/java/org/onosproject/net/NetTestTools.java
+++ b/core/api/src/test/java/org/onosproject/net/NetTestTools.java
@@ -76,17 +76,27 @@
}
// Crates a new host with the specified id
- public static Host host(String id, String did) {
+ public static Host host(String id, String did, long port) {
return new DefaultHost(PID, hid(id), valueOf(1234), vlanId((short) 2),
- new HostLocation(did(did), portNumber(1), 321),
+ new HostLocation(did(did), portNumber(port), 321),
new HashSet<>());
}
+ // Crates a new host with the specified id
+ public static Host host(String id, String did) {
+ return host(id, did, 1);
+ }
+
// Short-hand for creating a connection point.
public static ConnectPoint connectPoint(String id, int port) {
return new ConnectPoint(did(id), portNumber(port));
}
+ // Short-hand for creating a connection point.
+ public static ConnectPoint connectPointNoOF(String id, int port) {
+ return new ConnectPoint(DeviceId.deviceId(id), portNumber(port));
+ }
+
// Short-hand for creating a link.
public static Link link(String src, int sp, String dst, int dp) {
return new DefaultLink(PID,
@@ -95,6 +105,14 @@
Link.Type.DIRECT, Link.State.ACTIVE);
}
+ // Short-hand for creating a link.
+ public static Link linkNoPrefixes(String src, int sp, String dst, int dp) {
+ return new DefaultLink(PID,
+ connectPointNoOF(src, sp),
+ connectPointNoOF(dst, dp),
+ Link.Type.DIRECT, Link.State.ACTIVE);
+ }
+
/**
* Short-hand for creating a link.
*
@@ -110,21 +128,21 @@
public static Path createPath(String... ids) {
List<Link> links = new ArrayList<>();
for (int i = 0; i < ids.length - 1; i++) {
- links.add(link(ids[i], i, ids[i + 1], i));
+ links.add(link(ids[i], 2, ids[i + 1], 1));
}
return new DefaultPath(PID, links, ids.length);
}
- // Creates a path that leads through the given devices.
+ // Creates a path that leads through the given hosts.
public static Path createPath(boolean srcIsEdge, boolean dstIsEdge, String... ids) {
List<Link> links = new ArrayList<>();
for (int i = 0; i < ids.length - 1; i++) {
if (i == 0 && srcIsEdge) {
- links.add(DefaultEdgeLink.createEdgeLink(host(ids[i], ids[i + 1]), true));
+ links.add(DefaultEdgeLink.createEdgeLink(host(ids[i], ids[i + 1], 1), true));
} else if (i == ids.length - 2 && dstIsEdge) {
- links.add(DefaultEdgeLink.createEdgeLink(host(ids[i + 1], ids[i]), false));
+ links.add(DefaultEdgeLink.createEdgeLink(host(ids[i + 1], ids[i], 2), false));
} else {
- links.add(link(ids[i], i, ids[i + 1], i));
+ links.add(link(ids[i], 2, ids[i + 1], 1));
}
}
return new DefaultPath(PID, links, ids.length);
diff --git a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
index a944ca6..cef5b67 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
@@ -17,9 +17,9 @@
import com.google.common.base.MoreObjects;
import org.onlab.graph.Weight;
-import org.onlab.util.Bandwidth;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.core.GroupId;
+import org.onosproject.net.DefaultPath;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.HostId;
@@ -38,13 +38,7 @@
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.Instructions.MetadataInstruction;
-import org.onosproject.net.resource.DiscreteResourceId;
-import org.onosproject.net.resource.Resource;
-import org.onosproject.net.resource.ResourceAllocation;
-import org.onosproject.net.resource.ResourceConsumer;
-import org.onosproject.net.resource.ResourceId;
-import org.onosproject.net.resource.ResourceListener;
-import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.topology.DefaultTopologyEdge;
import org.onosproject.net.topology.DefaultTopologyVertex;
import org.onosproject.net.topology.LinkWeigher;
@@ -52,13 +46,13 @@
import org.onosproject.net.topology.TopologyVertex;
import org.onosproject.store.Timestamp;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
@@ -185,8 +179,7 @@
* Mock path service for creating paths within the test.
*
*/
- public static class Mp2MpMockPathService
- extends PathServiceAdapter {
+ public static class Mp2MpMockPathService extends PathServiceAdapter {
final String[] pathHops;
final String[] reversePathHops;
@@ -242,84 +235,74 @@
}
}
- public static final class MockResourceService implements ResourceService {
+ /**
+ * Mock path service for creating paths for MP2SP intent tests, returning
+ * pre-determined paths.
+ */
+ public static class FixedMP2MPMockPathService extends PathServiceAdapter {
- private final double bandwidth;
+ final String[] pathHops;
- public static ResourceService makeBandwidthResourceService(double bandwidth) {
- return new MockResourceService(bandwidth);
- }
+ public static final String DPID_1 = "of:s1";
+ public static final String DPID_2 = "of:s2";
+ public static final String DPID_3 = "of:s3";
+ public static final String DPID_4 = "of:s4";
- private MockResourceService(double bandwidth) {
- this.bandwidth = bandwidth;
+ /**
+ * Constructor that provides a set of hops to mock.
+ *
+ * @param pathHops path hops to mock
+ */
+ public FixedMP2MPMockPathService(String[] pathHops) {
+ this.pathHops = pathHops;
}
@Override
- public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<? extends Resource> resources) {
- return null;
- }
-
- @Override
- public boolean release(List<ResourceAllocation> allocations) {
- return false;
- }
-
- @Override
- public boolean release(ResourceConsumer consumer) {
- return false;
- }
-
- @Override
- public List<ResourceAllocation> getResourceAllocations(ResourceId id) {
- return null;
- }
-
- @Override
- public <T> Collection<ResourceAllocation> getResourceAllocations(DiscreteResourceId parent, Class<T> cls) {
- return null;
- }
-
- @Override
- public Collection<ResourceAllocation> getResourceAllocations(ResourceConsumer consumer) {
- return null;
- }
-
- @Override
- public Set<Resource> getAvailableResources(DiscreteResourceId parent) {
- return null;
- }
-
- @Override
- public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) {
- return null;
- }
-
- @Override
- public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) {
- return null;
- }
-
- @Override
- public Set<Resource> getRegisteredResources(DiscreteResourceId parent) {
- return null;
- }
-
- @Override
- public boolean isAvailable(Resource resource) {
- if (!resource.isTypeOf(Bandwidth.class)) {
- return false;
+ public Set<Path> getPaths(ElementId src, ElementId dst) {
+ List<Link> links = new ArrayList<>();
+ Set<Path> result = new HashSet<>();
+ ProviderId providerId = new ProviderId("of", "foo");
+ DefaultPath path;
+ if (src.toString().equals(DPID_1) && dst.toString().equals(DPID_4)) {
+ links.add(NetTestTools.linkNoPrefixes(src.toString(), 2, pathHops[0], 1));
+ links.add(NetTestTools.linkNoPrefixes(pathHops[0], 2, dst.toString(), 1));
+ } else if (src.toString().equals(DPID_2) && dst.toString().equals(DPID_4)) {
+ links.add(NetTestTools.linkNoPrefixes(src.toString(), 2, pathHops[0], 3));
+ links.add(NetTestTools.linkNoPrefixes(pathHops[0], 2, dst.toString(), 1));
+ } else if (src.toString().equals(DPID_4) && dst.toString().equals(DPID_1)) {
+ links.add(NetTestTools.linkNoPrefixes(src.toString(), 2, pathHops[0], 1));
+ links.add(NetTestTools.linkNoPrefixes(pathHops[0], 2, dst.toString(), 1));
+ } else if (src.toString().equals(DPID_4) && dst.toString().equals(DPID_2)) {
+ links.add(NetTestTools.linkNoPrefixes(src.toString(), 2, pathHops[0], 1));
+ links.add(NetTestTools.linkNoPrefixes(pathHops[0], 3, dst.toString(), 1));
+ } else {
+ return result;
}
+ path = new DefaultPath(providerId, links, 3);
+ result.add(path);
- Optional<Double> value = resource.valueAs(Double.class);
- return value.filter(requested -> requested <= bandwidth).isPresent();
+ return result;
}
@Override
- public void addListener(ResourceListener listener) {
- }
+ public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeigher weigher) {
+ final Set<Path> paths = getPaths(src, dst);
- @Override
- public void removeListener(ResourceListener listener) {
+ for (Path path : paths) {
+ final DeviceId srcDevice = path.src().elementId() instanceof DeviceId ? path.src().deviceId() : null;
+ final DeviceId dstDevice = path.dst().elementId() instanceof DeviceId ? path.dst().deviceId() : null;
+ if (srcDevice != null && dstDevice != null) {
+ final TopologyVertex srcVertex = new DefaultTopologyVertex(srcDevice);
+ final TopologyVertex dstVertex = new DefaultTopologyVertex(dstDevice);
+ final Link link = link(src.toString(), 1, dst.toString(), 1);
+
+ final Weight weightValue = weigher.weight(new DefaultTopologyEdge(srcVertex, dstVertex, link));
+ if (weightValue.isNegative()) {
+ return new HashSet<>();
+ }
+ }
+ }
+ return paths;
}
}
@@ -500,5 +483,4 @@
return true;
}
}
-
}
diff --git a/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
index 436a763..3a8b4e4 100644
--- a/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
+++ b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
@@ -20,6 +20,7 @@
import org.onlab.packet.MplsLabel;
import org.onlab.packet.VlanId;
+import org.onlab.util.Bandwidth;
import org.onlab.util.Tools;
import org.onosproject.net.TributarySlot;
@@ -35,10 +36,22 @@
public class MockResourceService implements ResourceService {
+ private double bandwidth = 1000.0;
private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
public Set<Short> availableVlanLabels = new HashSet<>();
public Set<Integer> availableMplsLabels = new HashSet<>();
+ public MockResourceService(){}
+
+ // To express a custom bandwidth available (in bps)
+ public static ResourceService makeCustomBandwidthResourceService(double bandwidth) {
+ return new MockResourceService(bandwidth);
+ }
+
+ private MockResourceService(double bandwidth) {
+ this.bandwidth = bandwidth;
+ }
+
@Override
public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<? extends Resource> resources) {
assignment.putAll(
@@ -181,6 +194,11 @@
@Override
public boolean isAvailable(Resource resource) {
+ if (resource.isTypeOf(Bandwidth.class)) {
+ // If there's is enough bandwidth available return true; false otherwise
+ Optional<Double> value = resource.valueAs(Double.class);
+ return value.filter(requested -> requested <= bandwidth).isPresent();
+ }
return true;
}