Merge "Applied some fixes to Intents"
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/Intent.java b/core/api/src/main/java/org/onlab/onos/net/intent/Intent.java
index 206552e..885b851 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/Intent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/Intent.java
@@ -19,6 +19,7 @@
import org.onlab.onos.net.NetworkResource;
import org.onlab.onos.net.flow.BatchOperationTarget;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
@@ -93,9 +94,10 @@
* @param fields intent fields
* @return intent identifier
*/
- protected static IntentId id(Object... fields) {
+ protected static IntentId id(Class<?> intentClass, Object... fields) {
// FIXME: spread the bits across the full long spectrum
- return IntentId.valueOf(Objects.hash(fields));
+ return IntentId.valueOf(Objects.hash(intentClass.getName(),
+ Arrays.hashCode(fields)));
}
/**
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceAllocation.java b/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceAllocation.java
index 7499f6d..1c81f1f 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceAllocation.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceAllocation.java
@@ -15,6 +15,8 @@
*/
package org.onlab.onos.net.resource;
+import java.util.Objects;
+
/**
* Representation of allocated lambda resource.
*/
@@ -45,4 +47,21 @@
public Lambda lambda() {
return lambda;
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(lambda);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final LambdaResourceAllocation other = (LambdaResourceAllocation) obj;
+ return Objects.equals(this.lambda, other.lambda);
+ }
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
index 7b1d7a9..31df87a 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
@@ -407,6 +407,8 @@
List<Intent> installables = store.getInstallableIntents(intent.id());
if (installables != null) {
for (Intent installable : installables) {
+ trackerService.removeTrackedResources(intent.id(),
+ installable.resources());
List<FlowRuleBatchOperation> batches = getInstaller(installable).uninstall(installable);
uninstallWork.addAll(batches);
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
index f0747dd..5faae4d 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
@@ -94,7 +94,26 @@
@Override
public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) {
LinkResourceAllocations allocations = assignWavelength(intent);
+ return generateRules(intent, allocations, FlowRuleOperation.ADD);
+ }
+ @Override
+ public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
+ LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
+ return generateRules(intent, allocations, FlowRuleOperation.REMOVE);
+ }
+
+ private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
+ LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
+ intent.path().links())
+ .addLambdaRequest();
+ LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
+ return retLambda;
+ }
+
+ private List<FlowRuleBatchOperation> generateRules(OpticalPathIntent intent,
+ LinkResourceAllocations allocations,
+ FlowRuleOperation operation) {
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchInport(intent.src().port());
@@ -128,7 +147,7 @@
100,
true);
- rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
+ rules.add(new FlowRuleBatchEntry(operation, rule));
prev = link.dst();
selectorBuilder.matchInport(link.dst().port());
@@ -136,28 +155,20 @@
}
// build the last T port rule
- TrafficTreatment treatmentLast = builder()
- .setOutput(intent.dst().port()).build();
+ TrafficTreatment.Builder treatmentLast = builder();
+ treatmentLast.setOutput(intent.dst().port());
FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
selectorBuilder.build(),
- treatmentLast,
+ treatmentLast.build(),
100,
appId,
100,
true);
- rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
+ rules.add(new FlowRuleBatchEntry(operation, rule));
return Lists.newArrayList(new FlowRuleBatchOperation(rules));
}
- private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
- LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
- intent.path().links())
- .addLambdaRequest();
- LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
- return retLambda;
- }
-
/*private Lambda assignWavelength(List<Link> links) {
// TODO More wavelength assignment algorithm
int wavenum = 0;
@@ -194,64 +205,4 @@
}
return false;
}*/
-
- @Override
- public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
- LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
-
- TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
- selectorBuilder.matchInport(intent.src().port());
-
- TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-
- List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
- ConnectPoint prev = intent.src();
-
- //TODO throw exception if the lambda was not retrieved successfully
- for (Link link : intent.path().links()) {
- Lambda la = null;
- for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
- if (allocation.type() == ResourceType.LAMBDA) {
- la = ((LambdaResourceAllocation) allocation).lambda();
- break;
- }
- }
-
- if (la == null) {
- log.info("Lambda was not retrieved successfully");
- return null;
- }
-
- treatmentBuilder.setOutput(link.src().port());
- treatmentBuilder.setLambda((short) la.toInt());
-
- FlowRule rule = new DefaultFlowRule(prev.deviceId(),
- selectorBuilder.build(),
- treatmentBuilder.build(),
- 100,
- appId,
- 100,
- true);
- rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
-
- prev = link.dst();
- selectorBuilder.matchInport(link.dst().port());
- selectorBuilder.matchLambda((short) la.toInt());
- }
-
- // build the last T port rule
- TrafficTreatment treatmentLast = builder()
- .setOutput(intent.dst().port()).build();
- FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
- selectorBuilder.build(),
- treatmentLast,
- 100,
- appId,
- 100,
- true);
- rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
-
- return Lists.newArrayList(new FlowRuleBatchOperation(rules));
- }
-
}
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/DistributedLinkResourceStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/DistributedLinkResourceStore.java
new file mode 100644
index 0000000..41172cd
--- /dev/null
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/DistributedLinkResourceStore.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onlab.onos.store.resource.impl;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.intent.IntentId;
+import org.onlab.onos.net.resource.Bandwidth;
+import org.onlab.onos.net.resource.BandwidthResourceAllocation;
+import org.onlab.onos.net.resource.Lambda;
+import org.onlab.onos.net.resource.LambdaResourceAllocation;
+import org.onlab.onos.net.resource.LinkResourceAllocations;
+import org.onlab.onos.net.resource.LinkResourceStore;
+import org.onlab.onos.net.resource.ResourceAllocation;
+import org.onlab.onos.net.resource.ResourceType;
+import org.slf4j.Logger;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Manages link resources using trivial in-memory structures implementation.
+ */
+@Component(immediate = true)
+@Service
+public class DistributedLinkResourceStore implements LinkResourceStore {
+ private final Logger log = getLogger(getClass());
+ private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
+ private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
+ private Map<Link, Set<ResourceAllocation>> freeResources;
+
+ @Activate
+ public void activate() {
+ linkResourceAllocationsMap = new HashMap<>();
+ allocatedResources = new HashMap<>();
+ freeResources = new HashMap<>();
+
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ log.info("Stopped");
+ }
+
+ /**
+ * Returns free resources for a given link obtaining from topology
+ * information.
+ *
+ * @param link the target link
+ * @return free resources
+ */
+ private Set<ResourceAllocation> readOriginalFreeResources(Link link) {
+ // TODO read capacity and lambda resources from topology
+ Set<ResourceAllocation> allocations = new HashSet<>();
+ for (int i = 1; i <= 100; i++) {
+ allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
+ }
+ allocations.add(new BandwidthResourceAllocation(Bandwidth.valueOf(1000000)));
+ return allocations;
+ }
+
+ /**
+ * Finds and returns {@link org.onlab.onos.net.resource.BandwidthResourceAllocation} object from a given
+ * set.
+ *
+ * @param freeRes a set of ResourceAllocation object.
+ * @return {@link org.onlab.onos.net.resource.BandwidthResourceAllocation} object if found, otherwise
+ * {@link org.onlab.onos.net.resource.BandwidthResourceAllocation} object with 0 bandwidth
+ *
+ */
+ private BandwidthResourceAllocation getBandwidth(Set<ResourceAllocation> freeRes) {
+ for (ResourceAllocation res : freeRes) {
+ if (res.type() == ResourceType.BANDWIDTH) {
+ return (BandwidthResourceAllocation) res;
+ }
+ }
+ return new BandwidthResourceAllocation(Bandwidth.valueOf(0));
+ }
+
+ /**
+ * Subtracts given resources from free resources for given link.
+ *
+ * @param link the target link
+ * @param allocations the resources to be subtracted
+ */
+ private void subtractFreeResources(Link link, LinkResourceAllocations allocations) {
+ // TODO Use lock or version for updating freeResources.
+ checkNotNull(link);
+ Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
+ Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
+ for (ResourceAllocation res : subRes) {
+ switch (res.type()) {
+ case BANDWIDTH:
+ BandwidthResourceAllocation ba = getBandwidth(freeRes);
+ double requestedBandwidth =
+ ((BandwidthResourceAllocation) res).bandwidth().toDouble();
+ double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
+ checkState(newBandwidth >= 0.0);
+ freeRes.remove(ba);
+ freeRes.add(new BandwidthResourceAllocation(
+ Bandwidth.valueOf(newBandwidth)));
+ break;
+ case LAMBDA:
+ checkState(freeRes.remove(res));
+ break;
+ default:
+ break;
+ }
+ }
+ freeResources.put(link, freeRes);
+
+ }
+
+ /**
+ * Adds given resources to free resources for given link.
+ *
+ * @param link the target link
+ * @param allocations the resources to be added
+ */
+ private void addFreeResources(Link link, LinkResourceAllocations allocations) {
+ // TODO Use lock or version for updating freeResources.
+ Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
+ Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
+ for (ResourceAllocation res : addRes) {
+ switch (res.type()) {
+ case BANDWIDTH:
+ BandwidthResourceAllocation ba = getBandwidth(freeRes);
+ double requestedBandwidth =
+ ((BandwidthResourceAllocation) res).bandwidth().toDouble();
+ double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
+ freeRes.remove(ba);
+ freeRes.add(new BandwidthResourceAllocation(
+ Bandwidth.valueOf(newBandwidth)));
+ break;
+ case LAMBDA:
+ checkState(freeRes.add(res));
+ break;
+ default:
+ break;
+ }
+ }
+ freeResources.put(link, freeRes);
+ }
+
+ @Override
+ public Set<ResourceAllocation> getFreeResources(Link link) {
+ checkNotNull(link);
+ Set<ResourceAllocation> freeRes = freeResources.get(link);
+ if (freeRes == null) {
+ freeRes = readOriginalFreeResources(link);
+ }
+
+ return freeRes;
+ }
+
+ @Override
+ public void allocateResources(LinkResourceAllocations allocations) {
+ checkNotNull(allocations);
+ linkResourceAllocationsMap.put(allocations.intendId(), allocations);
+ for (Link link : allocations.links()) {
+ subtractFreeResources(link, allocations);
+ Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
+ if (linkAllocs == null) {
+ linkAllocs = new HashSet<>();
+ }
+ linkAllocs.add(allocations);
+ allocatedResources.put(link, linkAllocs);
+ }
+ }
+
+ @Override
+ public void releaseResources(LinkResourceAllocations allocations) {
+ checkNotNull(allocations);
+ linkResourceAllocationsMap.remove(allocations);
+ for (Link link : allocations.links()) {
+ addFreeResources(link, allocations);
+ Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
+ if (linkAllocs == null) {
+ log.error("Missing resource allocation.");
+ } else {
+ linkAllocs.remove(allocations);
+ }
+ allocatedResources.put(link, linkAllocs);
+ }
+ }
+
+ @Override
+ public LinkResourceAllocations getAllocations(IntentId intentId) {
+ checkNotNull(intentId);
+ return linkResourceAllocationsMap.get(intentId);
+ }
+
+ @Override
+ public Iterable<LinkResourceAllocations> getAllocations(Link link) {
+ checkNotNull(link);
+ Set<LinkResourceAllocations> result = allocatedResources.get(link);
+ if (result == null) {
+ result = Collections.emptySet();
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ @Override
+ public Iterable<LinkResourceAllocations> getAllocations() {
+ return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
+ }
+
+}
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/package-info.java b/core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/package-info.java
new file mode 100644
index 0000000..1e34e37
--- /dev/null
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Implementation of distributed packet store.
+ */
+package org.onlab.onos.store.resource.impl;
\ No newline at end of file
diff --git a/core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java
index b91e8fc..2a4c10c 100644
--- a/core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java
@@ -71,11 +71,14 @@
import org.onlab.onos.net.intent.IntentState;
import org.onlab.onos.net.intent.LinkCollectionIntent;
import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
+import org.onlab.onos.net.intent.OpticalConnectivityIntent;
+import org.onlab.onos.net.intent.OpticalPathIntent;
import org.onlab.onos.net.intent.PathIntent;
import org.onlab.onos.net.intent.PointToPointIntent;
import org.onlab.onos.net.link.DefaultLinkDescription;
import org.onlab.onos.net.packet.DefaultOutboundPacket;
import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.net.resource.LinkResourceRequest;
import org.onlab.onos.store.Timestamp;
import org.onlab.packet.ChassisId;
import org.onlab.packet.IpAddress;
@@ -182,7 +185,10 @@
HostToHostIntent.class,
PointToPointIntent.class,
MultiPointToSinglePointIntent.class,
- LinkCollectionIntent.class
+ LinkCollectionIntent.class,
+ OpticalConnectivityIntent.class,
+ OpticalPathIntent.class,
+ LinkResourceRequest.class
)
.register(DefaultApplicationId.class, new DefaultApplicationIdSerializer())
.register(URI.class, new URISerializer())