aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/core')
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java18
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultOchSignalComparator.java37
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/NshContextHeader.java83
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/NshServiceIndex.java83
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/NshServicePathId.java83
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/OchPort.java4
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignal.java8
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/OduCltPort.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/OmsPort.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionSelectorResolver.java40
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java4
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/LambdaQuery.java40
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java72
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java33
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/AbstractExtension.java (renamed from framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java)11
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java27
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java15
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/Extension.java71
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java15
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java24
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java28
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionCriterion.java92
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelector.java32
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java98
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalIdCriterion.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalTypeCriterion.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/PbbIsidCriterion.java75
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java53
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java17
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java36
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java162
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentUtils.java84
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/mcast/MulticastRouteService.java4
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java74
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/GeoDistanceLinkWeight.java72
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/HopCountLinkWeight.java36
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/MetricLinkWeight.java36
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathAdminService.java44
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathService.java36
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java4
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java79
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java12
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java34
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/store/persistence/PersistenceServiceAdapter.java36
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/store/persistence/TestPersistenceService.java57
-rw-r--r--framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java1
-rw-r--r--framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java84
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/edgeservice/impl/EdgeManager.java55
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java2
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java9
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java7
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java31
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java12
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/link/impl/BasicLinkOperator.java4
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java103
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java153
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java11
-rw-r--r--framework/src/onos/core/net/src/test/java/org/onosproject/net/edgeservice/impl/EdgeManagerTest.java155
-rw-r--r--framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java5
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java49
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/MappingSet.java131
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java2
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java (renamed from framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java)79
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/proxyarp/impl/DistributedProxyArpStore.java7
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/topology/impl/DistributedTopologyStore.java91
-rw-r--r--framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMapTest.java369
-rw-r--r--framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java8
-rw-r--r--framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/host/impl/DistributedHostStoreTest.java (renamed from framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/host/impl/ECHostStoreTest.java)18
-rw-r--r--framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java1
-rw-r--r--framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java4
75 files changed, 2706 insertions, 573 deletions
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java
index 8c5fb790..38b599de 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java
@@ -25,7 +25,6 @@ package org.onosproject.net;
*/
public final class AnnotationKeys {
-
// Prohibit instantiation
private AnnotationKeys() {
}
@@ -81,6 +80,12 @@ public final class AnnotationKeys {
public static final String DURABLE = "durable";
/**
+ * Annotation key for link metric; used by
+ * {@link org.onosproject.net.topology.MetricLinkWeight} function.
+ */
+ public static final String METRIC = "metric";
+
+ /**
* Annotation key for latency.
*
* @deprecated since Cardinal
@@ -108,12 +113,23 @@ public final class AnnotationKeys {
public static final String PORT_NAME = "portName";
/**
+ * Annotation key for the port mac.
+ */
+ public static final String PORT_MAC = "portMac";
+
+ /**
* Annotation key for the router ID.
*/
public static final String ROUTER_ID = "routerId";
+ /**
+ * Annotation key for the static lambda.
+ */
public static final String STATIC_LAMBDA = "staticLambda";
+ /**
+ * Annotation key for the static port.
+ */
public static final String STATIC_PORT = "staticPort";
/**
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultOchSignalComparator.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultOchSignalComparator.java
new file mode 100644
index 00000000..e605dcfd
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultOchSignalComparator.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 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.onosproject.net;
+
+import java.util.Comparator;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Comparator implementation for OchSignal. Assumes identical grid type and channel spacing.
+ */
+public class DefaultOchSignalComparator implements Comparator<OchSignal> {
+ @Override
+ public int compare(OchSignal o1, OchSignal o2) {
+ checkNotNull(o1.gridType());
+ checkNotNull(o1.channelSpacing());
+
+ checkArgument(o1.gridType().equals(o2.gridType()));
+ checkArgument(o1.channelSpacing().equals(o2.channelSpacing()));
+
+ return o1.spacingMultiplier() * o1.slotGranularity() - o2.spacingMultiplier() * o2.slotGranularity();
+ }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/NshContextHeader.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NshContextHeader.java
new file mode 100644
index 00000000..745b616f
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NshContextHeader.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2015 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.onosproject.net;
+
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+/*
+ * Representation of NSH context header value
+ */
+public final class NshContextHeader {
+
+ private final int nshContextHeader;
+
+ /**
+ * Default constructor.
+ *
+ * @param nshContextHeader nsh context header value.
+ */
+ private NshContextHeader(int nshContextHeader) {
+ this.nshContextHeader = nshContextHeader;
+ }
+
+ /**
+ * Returns the NshContextHeader by setting its value.
+ *
+ * @param nshContextHeader nsh context header value.
+ * @return NshContextHeader
+ */
+ public static NshContextHeader of(int nshContextHeader) {
+ return new NshContextHeader(nshContextHeader);
+ }
+
+
+ /**
+ * Returns nsh context header value.
+ *
+ * @return the nsh context header
+ */
+ public int nshContextHeader() {
+ return nshContextHeader;
+ }
+
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(nshContextHeader);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof NshContextHeader)) {
+ return false;
+ }
+ final NshContextHeader other = (NshContextHeader) obj;
+ return Objects.equals(this.nshContextHeader, other.nshContextHeader);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("nshContextHeader", nshContextHeader)
+ .toString();
+ }
+}
+
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/NshServiceIndex.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NshServiceIndex.java
new file mode 100644
index 00000000..7e0c914c
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NshServiceIndex.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2015 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.onosproject.net;
+
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+/*
+ * Representation of NSH Service index
+ */
+public final class NshServiceIndex {
+ private static final short MASK = 0xFF;
+ private final short serviceIndex;
+
+ /**
+ * Default constructor.
+ *
+ * @param serviceIndex nsh service index
+ */
+ private NshServiceIndex(short serviceIndex) {
+ this.serviceIndex = (short) (serviceIndex & MASK);
+ }
+
+ /**
+ * Returns the NshServiceIndex by setting its value.
+ *
+ * @param serviceIndex nsh service index
+ * @return NshServiceIndex
+ */
+ public static NshServiceIndex of(short serviceIndex) {
+ return new NshServiceIndex(serviceIndex);
+ }
+
+
+ /**
+ * Returns nsh service index value.
+ *
+ * @return the nsh service index
+ */
+ public short serviceIndex() {
+ return serviceIndex;
+ }
+
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(serviceIndex);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof NshServiceIndex)) {
+ return false;
+ }
+ final NshServiceIndex other = (NshServiceIndex) obj;
+ return Objects.equals(this.serviceIndex, other.serviceIndex);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("serviceIndex", serviceIndex)
+ .toString();
+ }
+}
+
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/NshServicePathId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NshServicePathId.java
new file mode 100644
index 00000000..16fbc4e7
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NshServicePathId.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2015 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.onosproject.net;
+
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+/*
+ * Representation of NSH Service path Identifier
+ */
+public final class NshServicePathId {
+
+ private final int servicePathId;
+
+ /**
+ * Default constructor.
+ *
+ * @param servicePathId nsh service path identifier
+ */
+ private NshServicePathId(int servicePathId) {
+ this.servicePathId = servicePathId;
+ }
+
+ /**
+ * Returns the NshServicePathId by setting its value.
+ *
+ * @param servicePathId nsh service path identifier
+ * @return NshServicePathId
+ */
+ public static NshServicePathId of(int servicePathId) {
+ return new NshServicePathId(servicePathId);
+ }
+
+
+ /**
+ * Returns nsh context service path identifier.
+ *
+ * @return the nsh context service path id
+ */
+ public int servicePathId() {
+ return servicePathId;
+ }
+
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(servicePathId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof NshServicePathId)) {
+ return false;
+ }
+ final NshServicePathId other = (NshServicePathId) obj;
+ return Objects.equals(this.servicePathId, other.servicePathId);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("servicePathId", servicePathId)
+ .toString();
+ }
+}
+
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchPort.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchPort.java
index eb956f2a..94d4d321 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchPort.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchPort.java
@@ -87,7 +87,9 @@ public class OchPort extends DefaultPort {
if (this == obj) {
return true;
}
- if (obj instanceof OchPort) {
+
+ // Subclass is considered as a change of identity, hence equals() will return false if class type don't match
+ if (obj != null && getClass() == obj.getClass()) {
final OchPort other = (OchPort) obj;
return Objects.equals(this.element().id(), other.element().id()) &&
Objects.equals(this.number(), other.number()) &&
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignal.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignal.java
index 5a5af34a..3adc9086 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignal.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignal.java
@@ -17,6 +17,7 @@ package org.onosproject.net;
import com.google.common.base.MoreObjects;
import org.onlab.util.Frequency;
+import org.onlab.util.Spectrum;
import java.util.Objects;
@@ -32,7 +33,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public class OchSignal implements Lambda {
- public static final Frequency CENTER_FREQUENCY = Frequency.ofTHz(193.1);
public static final Frequency FLEX_GRID_SLOT = Frequency.ofGHz(12.5);
private static final GridType DEFAULT_OCH_GRIDTYPE = GridType.DWDM;
private static final ChannelSpacing DEFAULT_CHANNEL_SPACING = ChannelSpacing.CHL_50GHZ;
@@ -78,7 +78,7 @@ public class OchSignal implements Lambda {
this.gridType = DEFAULT_OCH_GRIDTYPE;
this.channelSpacing = DEFAULT_CHANNEL_SPACING;
- this.spacingMultiplier = (int) (centerFrequency.subtract(OchSignal.CENTER_FREQUENCY).asHz() / grid.asHz());
+ this.spacingMultiplier = (int) (centerFrequency.subtract(Spectrum.CENTER_FREQUENCY).asHz() / grid.asHz());
this.slotGranularity = (int) Math.round((double) grid.asHz() / ChannelSpacing.CHL_12P5GHZ.frequency().asHz());
}
@@ -86,7 +86,7 @@ public class OchSignal implements Lambda {
this.gridType = DEFAULT_OCH_GRIDTYPE;
this.channelSpacing = channelSpacing;
this.spacingMultiplier = (int) Math.round((double) centerFrequency.
- subtract(OchSignal.CENTER_FREQUENCY).asHz() / channelSpacing().frequency().asHz());
+ subtract(Spectrum.CENTER_FREQUENCY).asHz() / channelSpacing().frequency().asHz());
this.slotGranularity = slotGranularity;
}
@@ -132,7 +132,7 @@ public class OchSignal implements Lambda {
* @return frequency in MHz
*/
public Frequency centralFrequency() {
- return CENTER_FREQUENCY.add(channelSpacing().frequency().multiply(spacingMultiplier));
+ return Spectrum.CENTER_FREQUENCY.add(channelSpacing().frequency().multiply(spacingMultiplier));
}
/**
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduCltPort.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduCltPort.java
index e5602f36..f51393a4 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduCltPort.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduCltPort.java
@@ -71,7 +71,7 @@ public class OduCltPort extends DefaultPort {
if (this == obj) {
return true;
}
- if (obj instanceof OduCltPort) {
+ if (obj != null && getClass() == obj.getClass()) {
final OduCltPort other = (OduCltPort) obj;
return Objects.equals(this.element().id(), other.element().id()) &&
Objects.equals(this.number(), other.number()) &&
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OmsPort.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OmsPort.java
index 753834b5..d37fe75d 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OmsPort.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OmsPort.java
@@ -102,7 +102,7 @@ public class OmsPort extends DefaultPort {
if (this == obj) {
return true;
}
- if (obj instanceof OmsPort) {
+ if (obj != null && getClass() == obj.getClass()) {
final OmsPort other = (OmsPort) obj;
return Objects.equals(this.element().id(), other.element().id()) &&
Objects.equals(this.number(), other.number()) &&
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionSelectorResolver.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionSelectorResolver.java
new file mode 100644
index 00000000..d45dd53c
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionSelectorResolver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 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.onosproject.net.behaviour;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+import org.onosproject.net.flow.criteria.ExtensionSelectorType;
+
+/**
+ * Provides access to the extension selectors implemented by this driver.
+ */
+@Beta
+public interface ExtensionSelectorResolver extends HandlerBehaviour {
+
+ /**
+ * Gets an extension selector instance of the specified type, if supported
+ * by the driver.
+ *
+ * @param type type of extension to get
+ * @return extension selector
+ * @throws UnsupportedOperationException if the extension type is not
+ * supported by this driver
+ */
+ ExtensionSelector getExtensionSelector(ExtensionSelectorType type);
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java
index 85f0216d..8ca05af3 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java
@@ -22,13 +22,13 @@ import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
/**
- * Provides access to the extension implemented by this driver.
+ * Provides access to the extension treatments implemented by this driver.
*/
@Beta
public interface ExtensionTreatmentResolver extends HandlerBehaviour {
/**
- * Gets an extension instruction instance of the specified type, if supported
+ * Gets an extension treatment instance of the specified type, if supported
* by the driver.
*
* @param type type of extension to get
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/LambdaQuery.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/LambdaQuery.java
new file mode 100644
index 00000000..e3b1d963
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/LambdaQuery.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 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.onosproject.net.behaviour;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.HandlerBehaviour;
+
+import java.util.SortedSet;
+
+/**
+ * A HandlerBehaviour to retrieve available wavelength resources.
+ */
+@Beta
+public interface LambdaQuery extends HandlerBehaviour {
+
+ // Currently returns set of FLEX GridType ochSignal instances
+ /**
+ * Returns set of Lambda instances which can be used at the port.
+ *
+ * @param port to be checked for the available resources.
+ * @return Set of OchSignals which can be used at the port.
+ */
+ SortedSet<OchSignal> queryLambdas(PortNumber port);
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java
index 2fe2b2c0..92946312 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java
@@ -15,13 +15,83 @@
*/
package org.onosproject.net.config.basics;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.ConnectPoint;
import org.onosproject.net.HostId;
+import java.util.HashSet;
+import java.util.Set;
/**
* Basic configuration for network end-station hosts.
*/
public class BasicHostConfig extends BasicElementConfig<HostId> {
+ private static final String IPS = "ips";
+ private static final String LOCATION = "location";
- // TODO: determine what aspects of configuration to add for hosts
+ @Override
+ public boolean isValid() {
+ return hasOnlyFields(IPS, LOCATION) &&
+ this.location() != null &&
+ this.ipAddresses() != null;
+ }
+ /**
+ * Gets location of the host.
+ *
+ * @return location of the host. Or null if not specified with correct format.
+ */
+ public ConnectPoint location() {
+ String location = get(LOCATION, null);
+
+ if (location != null) {
+ try {
+ return ConnectPoint.deviceConnectPoint(location);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets the location of the host.
+ *
+ * @param location location of the host.
+ * @return the config of the host.
+ */
+ public BasicHostConfig setLocation(String location) {
+ return (BasicHostConfig) setOrClear(LOCATION, location);
+ }
+
+ /**
+ * Gets IP addresses of the host.
+ *
+ * @return IP addresses of the host. Or null if not specified with correct format.
+ */
+ public Set<IpAddress> ipAddresses() {
+ HashSet<IpAddress> ipAddresses = new HashSet<>();
+ if (object.has(IPS)) {
+ ArrayNode ipNodes = (ArrayNode) object.path(IPS);
+ try {
+ ipNodes.forEach(ipNode -> {
+ ipAddresses.add(IpAddress.valueOf(ipNode.asText()));
+ });
+ return ipAddresses;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets the IP addresses of the host.
+ *
+ * @param ipAddresses IP addresses of the host.
+ * @return the config of the host.
+ */
+ public BasicHostConfig setIps(Set<IpAddress> ipAddresses) {
+ return (BasicHostConfig) setOrClear(IPS, ipAddresses);
+ }
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java
index e962110c..ed807b8f 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java
@@ -15,22 +15,32 @@
*/
package org.onosproject.net.config.basics;
+import com.fasterxml.jackson.databind.JsonNode;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
-import com.fasterxml.jackson.databind.JsonNode;
import java.time.Duration;
+import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL;
+
/**
* Basic configuration for network infrastructure link.
*/
public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> {
public static final String TYPE = "type";
+ public static final String METRIC = "metric";
public static final String LATENCY = "latency";
public static final String BANDWIDTH = "bandwidth";
public static final String IS_DURABLE = "durable";
+ @Override
+ public boolean isValid() {
+ return hasOnlyFields(TYPE, METRIC, LATENCY, BANDWIDTH, IS_DURABLE) &&
+ isNumber(METRIC, OPTIONAL) && isNumber(LATENCY, OPTIONAL) &&
+ isNumber(BANDWIDTH, OPTIONAL);
+ }
+
/**
* Returns the link type.
*
@@ -51,6 +61,27 @@ public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> {
}
/**
+ * Returns link metric value for use by
+ * {@link org.onosproject.net.topology.MetricLinkWeight} function.
+ *
+ * @return link metric; -1 if not set
+ */
+ public double metric() {
+ return get(METRIC, -1);
+ }
+
+ /**
+ * Sets the link metric for use by
+ * {@link org.onosproject.net.topology.MetricLinkWeight} function.
+ *
+ * @param metric new metric; null to clear
+ * @return self
+ */
+ public BasicLinkConfig metric(Double metric) {
+ return (BasicLinkConfig) setOrClear(METRIC, metric);
+ }
+
+ /**
* Returns link latency in terms of nanos.
*
* @return link latency; -1 if not set
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/AbstractExtension.java
index ac7c771f..b48d69ce 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/AbstractExtension.java
@@ -14,22 +14,25 @@
* limitations under the License.
*/
-package org.onosproject.net.flow.instructions;
+package org.onosproject.net.flow;
+
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
- * Abstract implementation of the set/get property methods of ExtensionInstruction.
+ * Abstract implementation of the set/get property methods of Extension.
*/
-public abstract class AbstractExtensionTreatment implements ExtensionTreatment {
+public abstract class AbstractExtension implements Extension {
private static final String INVALID_KEY = "Invalid property key: ";
private static final String INVALID_TYPE = "Given type does not match field type: ";
@Override
- public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
+ public <T> void setPropertyValue(String key, T value) throws
+ ExtensionPropertyException {
Class<?> clazz = this.getClass();
try {
Field field = clazz.getDeclaredField(key);
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
index d3c2449c..0525d8fa 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
@@ -15,14 +15,8 @@
*/
package org.onosproject.net.flow;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.TreeSet;
-
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpPrefix;
@@ -30,12 +24,19 @@ import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableSet;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeSet;
/**
* Default traffic selector implementation.
@@ -379,6 +380,12 @@ public final class DefaultTrafficSelector implements TrafficSelector {
}
@Override
+ public TrafficSelector.Builder extension(ExtensionSelector extensionSelector,
+ DeviceId deviceId) {
+ return add(Criteria.extension(extensionSelector, deviceId));
+ }
+
+ @Override
public TrafficSelector build() {
return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
index 22bff7dd..40291f57 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
@@ -489,6 +489,21 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
}
@Override
+ public Builder setArpSpa(IpAddress addr) {
+ return add(Instructions.modArpSpa(addr));
+ }
+
+ @Override
+ public Builder setArpSha(MacAddress addr) {
+ return add(Instructions.modArpSha(addr));
+ }
+
+ @Override
+ public Builder setArpOp(short op) {
+ return add(Instructions.modL3ArpOp(op));
+ }
+
+ @Override
public TrafficTreatment.Builder extension(ExtensionTreatment extension,
DeviceId deviceId) {
return add(Instructions.extension(extension, deviceId));
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/Extension.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/Extension.java
new file mode 100644
index 00000000..1d61542e
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/Extension.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 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.onosproject.net.flow;
+
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
+
+import java.util.List;
+
+/**
+ * An extension to the northbound APIs.
+ */
+public interface Extension {
+
+ /**
+ * Sets a property on the extension.
+ *
+ * @param key property key
+ * @param value value to set for the given key
+ * @param <T> class of the value
+ * @throws ExtensionPropertyException if the given key is not a valid
+ * property on this extension
+ */
+ <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException;
+
+ /**
+ * Gets a property value of an extension.
+ *
+ * @param key property key
+ * @param <T> class of the value
+ * @return value of the property
+ * @throws ExtensionPropertyException if the given key is not a valid
+ * property on this extension
+ */
+ <T> T getPropertyValue(String key) throws ExtensionPropertyException;
+
+ /**
+ * Gets a list of all properties on the extension.
+ *
+ * @return list of properties
+ */
+ List<String> getProperties();
+
+ /**
+ * Serialize the extension to a byte array.
+ *
+ * @return byte array
+ */
+ byte[] serialize();
+
+ /**
+ * Deserialize the extension from a byte array. The properties
+ * of this object will be overwritten with the data in the byte array.
+ *
+ * @param data input byte array
+ */
+ void deserialize(byte[] data);
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
index b92281f5..0d055add 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
@@ -15,8 +15,6 @@
*/
package org.onosproject.net.flow;
-import java.util.Set;
-
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpPrefix;
@@ -24,8 +22,12 @@ import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+
+import java.util.Set;
/**
* Abstraction of a slice of network traffic.
@@ -427,6 +429,15 @@ public interface TrafficSelector {
Builder matchArpOp(int arpOp);
/**
+ * Uses an extension selector.
+ *
+ * @param extensionSelector extension selector
+ * @param deviceId device ID
+ * @return a selection builder
+ */
+ Builder extension(ExtensionSelector extensionSelector, DeviceId deviceId);
+
+ /**
* Builds an immutable traffic selector.
*
* @return traffic selector
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
index 06b6ffa0..3e57925d 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
@@ -424,6 +424,30 @@ public interface TrafficTreatment {
Builder setUdpDst(TpPort port);
/**
+ * Sets the arp src ip address.
+ *
+ * @param addr an ip
+ * @return a treatment builder
+ */
+ Builder setArpSpa(IpAddress addr);
+
+ /**
+ * Sets the arp src mac address.
+ *
+ * @param addr a macaddress
+ * @return a treatment builder
+ */
+ Builder setArpSha(MacAddress addr);
+
+ /**
+ * Sets the arp operation.
+ *
+ * @param op the value of arp operation.
+ * @return a treatment builder.
+ */
+ Builder setArpOp(short op);
+
+ /**
* Uses an extension treatment.
*
* @param extension extension treatment
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
index a28a4ab9..c94b1e02 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
@@ -23,6 +23,7 @@ import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.IndexedLambda;
import org.onosproject.net.Lambda;
import org.onosproject.net.OchSignal;
@@ -579,6 +580,33 @@ public final class Criteria {
return new ArpOpCriterion(arpOp, Type.ARP_OP);
}
+ /**
+ * Creates a match on PBB I-SID field using the specific value.
+ *
+ * @param pbbIsid PBB I-SID
+ * @return match criterion
+ */
+ public static Criterion matchPbbIsid(int pbbIsid) {
+ return new PbbIsidCriterion(pbbIsid);
+ }
+
+ /**
+ * Creates an extension criterion for the specified extension selector.
+ *
+ * @param extensionSelector extension selector
+ * @param deviceId device ID
+ * @return match criterion
+ */
+ public static Criterion extension(ExtensionSelector extensionSelector,
+ DeviceId deviceId) {
+ return new ExtensionCriterion(extensionSelector, deviceId);
+ }
+
+ /**
+ * Creates a dummy criterion.
+ *
+ * @return match criterion
+ */
public static Criterion dummy() {
return new DummyCriterion();
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
index 26665246..17557b9d 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
@@ -177,6 +177,9 @@ public interface Criterion {
/** ODU (Optical channel Data Unit) signal type. */
ODU_SIGTYPE,
+ /** Extension criterion. */
+ EXTENSION,
+
/** An empty criterion. */
DUMMY
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionCriterion.java
new file mode 100644
index 00000000..646b4184
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionCriterion.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 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.onosproject.net.flow.criteria;
+
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Criterion for implementing selector extensions.
+ */
+public class ExtensionCriterion implements Criterion {
+
+ private final ExtensionSelector extensionSelector;
+ private final DeviceId deviceId;
+
+ /**
+ * Constructor.
+ *
+ * @param extensionSelector extension selector
+ */
+ public ExtensionCriterion(ExtensionSelector extensionSelector, DeviceId deviceId) {
+ this.extensionSelector = extensionSelector;
+ this.deviceId = deviceId;
+ }
+
+ /**
+ * Returns the extension selector.
+ *
+ * @return extension selector
+ */
+ public ExtensionSelector extensionSelector() {
+ return extensionSelector;
+ }
+
+ /**
+ * Returns the device ID.
+ *
+ * @return device ID
+ */
+ public DeviceId deviceId() {
+ return deviceId;
+ }
+
+ @Override
+ public Type type() {
+ return Type.EXTENSION;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("extensionSelector", extensionSelector.toString())
+ .add("deviceId", deviceId)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type().ordinal(), extensionSelector, deviceId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ExtensionCriterion) {
+ ExtensionCriterion that = (ExtensionCriterion) obj;
+ return Objects.equals(extensionSelector, that.extensionSelector) &&
+ Objects.equals(deviceId, that.deviceId) &&
+ Objects.equals(this.type(), that.type());
+ }
+ return false;
+ }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelector.java
new file mode 100644
index 00000000..d3cebb37
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelector.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 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.onosproject.net.flow.criteria;
+
+import org.onosproject.net.flow.Extension;
+
+/**
+ * An extension for the selector API.
+ */
+public interface ExtensionSelector extends Extension {
+
+ /**
+ * Gets the type of the extension selector.
+ *
+ * @return type
+ */
+ ExtensionSelectorType type();
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java
new file mode 100644
index 00000000..fa8f0923
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2015 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.onosproject.net.flow.criteria;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Type of selector extensions.
+ */
+@Beta
+public class ExtensionSelectorType {
+
+ /**
+ * A list of well-known named extension selector type codes.
+ * These numbers have no impact on the actual OF type id.
+ */
+ public enum ExtensionSelectorTypes {
+ NICIRA_MATCH_NSH_SPI(0),
+ NICIRA_MATCH_NSH_SI(1),
+ NICIRA_MATCH_NSH_CH1(2),
+ NICIRA_MATCH_NSH_CH2(3),
+ NICIRA_MATCH_NSH_CH3(4),
+ NICIRA_MATCH_NSH_CH4(5);
+
+
+ private ExtensionSelectorType type;
+
+ /**
+ * Creates a new named extension selector type.
+ *
+ * @param type type code
+ */
+ ExtensionSelectorTypes(int type) {
+ this.type = new ExtensionSelectorType(type);
+ }
+
+ /**
+ * Gets the extension type object for this named type code.
+ *
+ * @return extension type object
+ */
+ public ExtensionSelectorType type() {
+ return type;
+ }
+ }
+
+ private final int type;
+
+ /**
+ * Creates an extension type with the given int type code.
+ *
+ * @param type type code
+ */
+ public ExtensionSelectorType(int type) {
+ this.type = type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ExtensionSelectorType) {
+ final ExtensionSelectorType that = (ExtensionSelectorType) obj;
+ return this.type == that.type;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(ExtensionSelectorType.class)
+ .add("type", type)
+ .toString();
+ }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalIdCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalIdCriterion.java
index cb513397..21018544 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalIdCriterion.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalIdCriterion.java
@@ -74,7 +74,7 @@ public final class OduSignalIdCriterion implements Criterion {
@Override
public String toString() {
- return toStringHelper(type().toString())
+ return toStringHelper(this)
.add("oduSignalId", oduSignalId)
.toString();
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalTypeCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalTypeCriterion.java
index d92880db..f4854339 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalTypeCriterion.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OduSignalTypeCriterion.java
@@ -74,7 +74,7 @@ public final class OduSignalTypeCriterion implements Criterion {
@Override
public String toString() {
- return toStringHelper(type().toString())
+ return toStringHelper(this)
.add("signalType", signalType)
.toString();
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/PbbIsidCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/PbbIsidCriterion.java
new file mode 100644
index 00000000..979aa6bd
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/PbbIsidCriterion.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 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.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of PBB I-SID criterion (24 bits unsigned integer).
+ */
+public final class PbbIsidCriterion implements Criterion {
+ private static final int MASK = 0xfffff;
+ private final int pbbIsid; // PBB I-SID: 24 bits
+
+ /**
+ * Constructor.
+ *
+ * @param pbbIsid the PBB I-SID to match (24 bits)
+ */
+ PbbIsidCriterion(int pbbIsid) {
+ this.pbbIsid = pbbIsid & MASK;
+ }
+
+ @Override
+ public Criterion.Type type() {
+ return Criterion.Type.PBB_ISID;
+ }
+
+ /**
+ * Gets the PBB I-SID to match.
+ *
+ * @return the PBB I-SID to match (24 bits)
+ */
+ public int pbbIsid() {
+ return this.pbbIsid;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("pbbIsid", Long.toHexString(pbbIsid)).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type().ordinal(), pbbIsid);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof PbbIsidCriterion) {
+ PbbIsidCriterion that = (PbbIsidCriterion) obj;
+ return Objects.equals(pbbIsid, that.pbbIsid) &&
+ Objects.equals(this.type(), that.type());
+ }
+ return false;
+ }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java
index 0e8885ed..3df152e9 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java
@@ -16,63 +16,18 @@
package org.onosproject.net.flow.instructions;
-import java.util.List;
+import org.onosproject.net.flow.Extension;
/**
- * An extensible instruction type.
+ * An extension for the treatment API.
*/
-public interface ExtensionTreatment {
+public interface ExtensionTreatment extends Extension {
/**
- * Gets the type of the extension instruction.
+ * Gets the type of the treatment extension.
*
* @return type
*/
ExtensionTreatmentType type();
- /**
- * Sets a property on the extension instruction.
- *
- * @param key property key
- * @param value value to set for the given key
- * @param <T> class of the value
- * @throws ExtensionPropertyException if the given key is not a valid
- * property on this extension instruction
- */
- <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException;
-
- /**
- * Gets a property value of an extension instruction.
- *
- * @param key property key
- * @param <T> class of the value
- * @return value of the property
- * @throws ExtensionPropertyException if the given key is not a valid
- * property on this extension instruction
- */
- <T> T getPropertyValue(String key) throws ExtensionPropertyException;
-
- /**
- * Gets a list of all properties on the extension instruction.
- *
- * @return list of properties
- */
- List<String> getProperties();
-
- /**
- * Serialize the extension instruction to a byte array.
- *
- * @return byte array
- */
- byte[] serialize();
-
- /**
- * Deserialize the extension instruction from a byte array. The properties
- * of this object will be overwritten with the data in the byte array.
- *
- * @param data input byte array
- */
- void deserialize(byte[] data);
-
-
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java
index 38fbc279..f597a46c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java
@@ -22,7 +22,7 @@ import com.google.common.base.MoreObjects;
import java.util.Objects;
/**
- * Type of extension instructions.
+ * Type of treatment extensions.
*/
@Beta
public final class ExtensionTreatmentType {
@@ -32,15 +32,24 @@ public final class ExtensionTreatmentType {
* These numbers have no impact on the actual OF type id.
*/
public enum ExtensionTreatmentTypes {
- // TODO fix type numbers to include experimenter id
NICIRA_SET_TUNNEL_DST(0),
NICIRA_RESUBMIT(1),
- NICIRA_SET_NSH_SPI(32);
+ NICIRA_RESUBMIT_TABLE(14),
+ NICIRA_SET_NSH_SPI(32),
+ NICIRA_SET_NSH_SI(33),
+ NICIRA_SET_NSH_CH1(34),
+ NICIRA_SET_NSH_CH2(35),
+ NICIRA_SET_NSH_CH3(36),
+ NICIRA_SET_NSH_CH4(37),
+ NICIRA_MOV_ARP_SHA_TO_THA(2),
+ NICIRA_MOV_ARP_SPA_TO_TPA(3),
+ NICIRA_MOV_ETH_SRC_TO_DST(4),
+ NICIRA_MOV_IP_SRC_TO_DST(5);
private ExtensionTreatmentType type;
/**
- * Creates a new named extension instruction type.
+ * Creates a new named extension treatment type.
*
* @param type type code
*/
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
index 4643b315..8ed882c8 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
@@ -35,6 +35,9 @@ import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSig
import org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction.L4SubType;
@@ -299,6 +302,39 @@ public final class Instructions {
}
/**
+ * Creates a L3 ARP IP src modification.
+ *
+ * @param addr the ip address to modify to
+ * @return a L3 modification
+ */
+ public static L3ModificationInstruction modArpSpa(IpAddress addr) {
+ checkNotNull(addr, "Src l3 ARP IP address cannot be null");
+ return new ModArpIPInstruction(L3SubType.ARP_SPA, addr);
+ }
+
+ /**
+ * Creates a l3 ARP Ether src modification.
+ *
+ * @param addr the mac address to modify to
+ * @return a l3 modification
+ */
+ public static L3ModificationInstruction modArpSha(MacAddress addr) {
+ checkNotNull(addr, "Src l3 ARP address cannot be null");
+ return new ModArpEthInstruction(L3SubType.ARP_SHA, addr);
+ }
+
+ /**
+ * Creates a l3 ARP operation modification.
+ *
+ * @param op the ARP operation to modify to
+ * @return a l3 modification
+ */
+ public static L3ModificationInstruction modL3ArpOp(short op) {
+ checkNotNull(op, "Arp operation cannot be null");
+ return new ModArpOpInstruction(L3SubType.ARP_OP, op);
+ }
+
+ /**
* Creates a push MPLS header instruction.
*
* @return a L2 modification.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java
index 41819504..0efe9a77 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java
@@ -20,6 +20,7 @@ import static com.google.common.base.MoreObjects.toStringHelper;
import java.util.Objects;
import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
/**
* Abstraction of a single traffic treatment step.
@@ -68,7 +69,22 @@ public abstract class L3ModificationInstruction implements Instruction {
/**
* Copy TTL in.
*/
- TTL_IN
+ TTL_IN,
+
+ /**
+ * ARP IP src modification.
+ */
+ ARP_SPA,
+
+ /**
+ * ARP Ether src modification.
+ */
+ ARP_SHA,
+
+ /**
+ * Arp operation modification.
+ */
+ ARP_OP
//TODO: remaining types
}
@@ -133,6 +149,150 @@ public abstract class L3ModificationInstruction implements Instruction {
}
/**
+ * Represents a L3 ARP IP src/dst modification instruction.
+ */
+ public static final class ModArpIPInstruction extends L3ModificationInstruction {
+
+ private final L3SubType subtype;
+ private final IpAddress ip;
+
+ ModArpIPInstruction(L3SubType subType, IpAddress addr) {
+
+ this.subtype = subType;
+ this.ip = addr;
+ }
+
+ @Override
+ public L3SubType subtype() {
+ return this.subtype;
+ }
+
+ public IpAddress ip() {
+ return this.ip;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(subtype().toString())
+ .add("ip", ip).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type(), subtype(), ip);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ModArpIPInstruction) {
+ ModArpIPInstruction that = (ModArpIPInstruction) obj;
+ return Objects.equals(ip, that.ip) &&
+ Objects.equals(this.subtype(), that.subtype());
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Represents a L3 ARP Ether src/dst modification instruction.
+ */
+ public static final class ModArpEthInstruction extends L3ModificationInstruction {
+
+ private final L3SubType subtype;
+ private final MacAddress mac;
+
+ ModArpEthInstruction(L3SubType subType, MacAddress addr) {
+
+ this.subtype = subType;
+ this.mac = addr;
+ }
+
+ @Override
+ public L3SubType subtype() {
+ return this.subtype;
+ }
+
+ public MacAddress mac() {
+ return this.mac;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(subtype().toString())
+ .add("mac", mac).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type(), subtype(), mac);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ModArpEthInstruction) {
+ ModArpEthInstruction that = (ModArpEthInstruction) obj;
+ return Objects.equals(mac, that.mac) &&
+ Objects.equals(this.subtype(), that.subtype());
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Represents a L3 ARP operation modification instruction.
+ */
+ public static final class ModArpOpInstruction extends L3ModificationInstruction {
+
+ private final L3SubType subtype;
+ private final short op;
+
+ ModArpOpInstruction(L3SubType subType, short op) {
+
+ this.subtype = subType;
+ this.op = op;
+ }
+
+ @Override
+ public L3SubType subtype() {
+ return this.subtype;
+ }
+
+ public long op() {
+ return this.op;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(subtype().toString())
+ .add("op", op).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type(), subtype(), op);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ModArpOpInstruction) {
+ ModArpOpInstruction that = (ModArpOpInstruction) obj;
+ return Objects.equals(op, that.op) &&
+ Objects.equals(this.subtype(), that.subtype());
+ }
+ return false;
+ }
+ }
+
+ /**
* Represents a L3 IPv6 Flow Label (RFC 6437) modification instruction
* (20 bits unsigned integer).
*/
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java
index 06305bf7..4d9d7225 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java
@@ -196,7 +196,7 @@ public final class DefaultFilteringObjective implements FilteringObjective {
}
@Override
- public Builder setMeta(TrafficTreatment treatment) {
+ public Builder withMeta(TrafficTreatment treatment) {
this.meta = treatment;
return this;
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java
index 4701589f..bd580507 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java
@@ -181,7 +181,7 @@ public final class DefaultNextObjective implements NextObjective {
}
@Override
- public Builder setMeta(TrafficSelector meta) {
+ public Builder withMeta(TrafficSelector meta) {
this.meta = meta;
return this;
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java
index 29257c61..8ed793d0 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java
@@ -133,7 +133,7 @@ public interface FilteringObjective extends Objective {
* @param treatment traffic treatment to use
* @return a filtering builder
*/
- Builder setMeta(TrafficTreatment treatment);
+ Builder withMeta(TrafficTreatment treatment);
/**
* Assigns an application id.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java
index 08916eb2..36098d71 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java
@@ -147,7 +147,7 @@ public interface NextObjective extends Objective {
* @param selector match conditions
* @return an objective builder
*/
- Builder setMeta(TrafficSelector selector);
+ Builder withMeta(TrafficSelector selector);
/**
* Builds the next objective that will be added.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentUtils.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentUtils.java
new file mode 100644
index 00000000..f6e33b6b
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentUtils.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2015 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.onosproject.net.intent;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+
+/**
+ * Utilities for dealing with intents.
+ */
+public final class IntentUtils {
+
+ private static final Logger log = LoggerFactory.getLogger(IntentUtils.class);
+
+ private IntentUtils() {
+ }
+
+ /**
+ * Checks if two intents represent the same value.
+ *
+ * <p>({@link Intent#equals(Object)} only checks ID equality)</p>
+ *
+ * <p>Both intents must be of the same type.</p>
+ *
+ * @param one first intent
+ * @param two second intent
+ * @return true if the two intents represent the same value, otherwise false
+ */
+ public static boolean equals(Intent one, Intent two) {
+ if (one.getClass() != two.getClass()) {
+ return false;
+ }
+
+ if (!(Objects.equals(one.appId(), two.appId()) &&
+ Objects.equals(one.key(), two.key()))) {
+ return false;
+ }
+
+ if (one instanceof SinglePointToMultiPointIntent) {
+ SinglePointToMultiPointIntent intent1 = (SinglePointToMultiPointIntent) one;
+ SinglePointToMultiPointIntent intent2 = (SinglePointToMultiPointIntent) two;
+
+ return Objects.equals(intent1.selector(), intent2.selector()) &&
+ Objects.equals(intent1.treatment(), intent2.treatment()) &&
+ Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) &&
+ Objects.equals(intent1.egressPoints(), intent2.egressPoints());
+ } else if (one instanceof MultiPointToSinglePointIntent) {
+ MultiPointToSinglePointIntent intent1 = (MultiPointToSinglePointIntent) one;
+ MultiPointToSinglePointIntent intent2 = (MultiPointToSinglePointIntent) two;
+
+ return Objects.equals(intent1.selector(), intent2.selector()) &&
+ Objects.equals(intent1.treatment(), intent2.treatment()) &&
+ Objects.equals(intent1.ingressPoints(), intent2.ingressPoints()) &&
+ Objects.equals(intent1.egressPoint(), intent2.egressPoint());
+ } else if (one instanceof PointToPointIntent) {
+ PointToPointIntent intent1 = (PointToPointIntent) one;
+ PointToPointIntent intent2 = (PointToPointIntent) two;
+
+ return Objects.equals(intent1.selector(), intent2.selector()) &&
+ Objects.equals(intent1.treatment(), intent2.treatment()) &&
+ Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) &&
+ Objects.equals(intent1.egressPoint(), intent2.egressPoint());
+ } else {
+ log.error("Unimplemented intent type");
+ return false;
+ }
+ }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/mcast/MulticastRouteService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/mcast/MulticastRouteService.java
index 56e87c55..bf65033a 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/mcast/MulticastRouteService.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/mcast/MulticastRouteService.java
@@ -16,6 +16,7 @@
package org.onosproject.net.mcast;
import com.google.common.annotations.Beta;
+import org.onosproject.event.ListenerService;
import org.onosproject.net.ConnectPoint;
import java.util.List;
@@ -24,7 +25,8 @@ import java.util.List;
* A service interface for maintaining multicast information.
*/
@Beta
-public interface MulticastRouteService {
+public interface MulticastRouteService
+ extends ListenerService<McastEvent, McastListener> {
/**
* Adds a route to the information base.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
index c0c4e34f..72f8ac01 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
@@ -18,6 +18,8 @@ package org.onosproject.net.newresource;
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
import java.util.LinkedList;
import java.util.List;
@@ -41,8 +43,8 @@ import static com.google.common.base.Preconditions.checkState;
* A double value is associated with a continuous type value.
*
* Users of this class must keep the semantics of resources regarding the hierarchical structure.
- * For example, resource path, Link:1/VLAN ID:100, is valid, but resource path, VLAN ID:100/Link:1
- * is not valid because a link is not a sub-component of a VLAN ID.
+ * For example, resource path, Device:1/Port:1/VLAN ID:100, is valid, but resource path,
+ * VLAN ID:100/Device:1/Port:1 is not valid because a link is not a sub-component of a VLAN ID.
*/
@Beta
public abstract class ResourcePath {
@@ -52,29 +54,73 @@ public abstract class ResourcePath {
public static final Discrete ROOT = new Discrete();
+ public static ResourcePath discrete(DeviceId device) {
+ return new Discrete(ImmutableList.of(device));
+ }
+
/**
* Creates an resource path which represents a discrete-type resource from the specified components.
*
- * @param components components of the path. The order represents hierarchical structure of the resource.
+ * @param device device ID which is the first component of the path
+ * @param components following components of the path. The order represents hierarchical structure of the resource.
* @return resource path instance
*/
- public static ResourcePath discrete(Object... components) {
- if (components.length == 0) {
- return ROOT;
- } else {
- return new Discrete(ImmutableList.copyOf(components));
- }
+ public static ResourcePath discrete(DeviceId device, Object... components) {
+ return new Discrete(ImmutableList.builder()
+ .add(device)
+ .add(components)
+ .build());
+ }
+
+ /**
+ * Creates an resource path which represents a discrete-type resource from the specified components.
+ *
+ * @param device device ID which is the first component of the path
+ * @param port port number which is the second component of the path
+ * @param components following components of the path. The order represents hierarchical structure of the resource.
+ * @return resource path instance
+ */
+ public static ResourcePath discrete(DeviceId device, PortNumber port, Object... components) {
+ return new Discrete(ImmutableList.builder()
+ .add(device)
+ .add(port)
+ .add(components)
+ .build());
}
/**
* Creates an resource path which represents a continuous-type resource from the specified components.
*
* @param value amount of the resource
- * @param components components of the path. The order represents hierarchical structure of the resource.
+ * @param device device ID which is the first component of the path
+ * @param components following components of the path. The order represents hierarchical structure of the resource.
+ * @return resource path instance
+ */
+ public static ResourcePath continuous(double value, DeviceId device, Object... components) {
+ checkArgument(components.length > 0,
+ "Length of components must be greater thant 0, but " + components.length);
+
+ return new Continuous(ImmutableList.builder()
+ .add(device)
+ .add(components)
+ .build(), value);
+ }
+
+ /**
+ * Creates an resource path which represents a continuous-type resource from the specified components.
+ *
+ * @param value amount of the resource
+ * @param device device ID which is the first component of the path.
+ * @param port port number which is the second component of the path.
+ * @param components following components of the path. The order represents hierarchical structure of the resource.
* @return resource path instance
*/
- public static ResourcePath continuous(double value, Object... components) {
- return new Continuous(ImmutableList.copyOf(components), value);
+ public static ResourcePath continuous(double value, DeviceId device, PortNumber port, Object... components) {
+ return new Continuous(ImmutableList.builder()
+ .add(device)
+ .add(port)
+ .add(components)
+ .build(), value);
}
/**
@@ -82,7 +128,7 @@ public abstract class ResourcePath {
*
* @param components components of the path. The order represents hierarchical structure of the resource.
*/
- ResourcePath(List<Object> components) {
+ protected ResourcePath(List<Object> components) {
checkNotNull(components);
checkArgument(!components.isEmpty());
@@ -101,7 +147,7 @@ public abstract class ResourcePath {
* @param parent the parent of this resource
* @param last a child of the parent
*/
- ResourcePath(Discrete parent, Object last) {
+ protected ResourcePath(Discrete parent, Object last) {
checkNotNull(parent);
checkNotNull(last);
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/GeoDistanceLinkWeight.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/GeoDistanceLinkWeight.java
new file mode 100644
index 00000000..c966902e
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/GeoDistanceLinkWeight.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2014-2015 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.onosproject.net.topology;
+
+import org.onlab.util.GeoLocation;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+
+import static java.lang.Double.MAX_VALUE;
+
+/**
+ * Link weight for measuring link cost using the geo distance between link
+ * vertices as determined by the element longitude/latitude annotation.
+ */
+public class GeoDistanceLinkWeight implements LinkWeight {
+
+ private static final double MAX_KM = 40_075 / 2.0;
+
+ private final DeviceService deviceService;
+
+ /**
+ * Creates a new link-weight with access to the specified device service.
+ *
+ * @param deviceService device service reference
+ */
+ public GeoDistanceLinkWeight(DeviceService deviceService) {
+ this.deviceService = deviceService;
+ }
+
+ @Override
+ public double weight(TopologyEdge edge) {
+ GeoLocation src = getLocation(edge.link().src().deviceId());
+ GeoLocation dst = getLocation(edge.link().dst().deviceId());
+ return src != null && dst != null ? src.kilometersTo(dst) : MAX_KM;
+ }
+
+ private GeoLocation getLocation(DeviceId deviceId) {
+ Device d = deviceService.getDevice(deviceId);
+ Annotations a = d != null ? d.annotations() : null;
+ double latitude = getDouble(a, AnnotationKeys.LATITUDE);
+ double longitude = getDouble(a, AnnotationKeys.LONGITUDE);
+ return latitude == MAX_VALUE || longitude == MAX_VALUE ? null :
+ new GeoLocation(latitude, longitude);
+ }
+
+ private double getDouble(Annotations a, String key) {
+ String value = a != null ? a.value(key) : null;
+ try {
+ return value != null ? Double.parseDouble(value) : MAX_VALUE;
+ } catch (NumberFormatException e) {
+ return MAX_VALUE;
+ }
+ }
+}
+
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/HopCountLinkWeight.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/HopCountLinkWeight.java
new file mode 100644
index 00000000..c557016b
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/HopCountLinkWeight.java
@@ -0,0 +1,36 @@
+package org.onosproject.net.topology;
+
+import static org.onosproject.net.Link.State.ACTIVE;
+import static org.onosproject.net.Link.Type.INDIRECT;
+
+/**
+ * Link weight for measuring link cost as hop count with indirect links
+ * being as expensive as traversing the entire graph to assume the worst.
+ */
+public class HopCountLinkWeight implements LinkWeight {
+ private final int indirectLinkCost;
+
+ /**
+ * Creates a new hop-count weight.
+ */
+ public HopCountLinkWeight() {
+ this.indirectLinkCost = Short.MAX_VALUE;
+ }
+
+ /**
+ * Creates a new hop-count weight with the specified cost of indirect links.
+ */
+ public HopCountLinkWeight(int indirectLinkCost) {
+ this.indirectLinkCost = indirectLinkCost;
+ }
+
+ @Override
+ public double weight(TopologyEdge edge) {
+ // To force preference to use direct paths first, make indirect
+ // links as expensive as the linear vertex traversal.
+ return edge.link().state() ==
+ ACTIVE ? (edge.link().type() ==
+ INDIRECT ? indirectLinkCost : 1) : -1;
+ }
+}
+
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/MetricLinkWeight.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/MetricLinkWeight.java
new file mode 100644
index 00000000..8463e087
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/MetricLinkWeight.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014-2015 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.onosproject.net.topology;
+
+import org.onosproject.net.AnnotationKeys;
+
+/**
+ * Link weight for measuring link cost using the link metric annotation.
+ */
+public class MetricLinkWeight implements LinkWeight {
+
+ @Override
+ public double weight(TopologyEdge edge) {
+ String v = edge.link().annotations().value(AnnotationKeys.METRIC);
+ try {
+ return v != null ? Double.parseDouble(v) : 1;
+ } catch (NumberFormatException e) {
+ return 1;
+ }
+ }
+}
+
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathAdminService.java
new file mode 100644
index 00000000..9d077e1e
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathAdminService.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2014-2015 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.onosproject.net.topology;
+
+import org.onlab.graph.GraphPathSearch;
+
+/**
+ * Provides administrative abilities to tailor the path service behaviours.
+ */
+public interface PathAdminService {
+
+ /**
+ * Sets the specified link-weight function to be used as a default.
+ * If null is specified, the builtin default hop-count link-weight will be
+ * used.
+ *
+ * @param linkWeight default link-weight function
+ */
+ void setDefaultLinkWeight(LinkWeight linkWeight);
+
+ /**
+ * Sets the specified graph path search algorightm to be used as a default.
+ * If null is specified, the builtin default all-shortest-paths Dijkstra
+ * algorithm will be used.
+ *
+ * @param graphPathSearch default graph path search algorithm
+ */
+ void setDefaultGraphPathSearch(GraphPathSearch<TopologyVertex, TopologyEdge> graphPathSearch);
+
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathService.java
index 0bd4d75d..38954079 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathService.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathService.java
@@ -30,8 +30,9 @@ import java.util.Set;
public interface PathService {
/**
- * Returns the set of all shortest paths, precomputed in terms of hop-count,
- * between the specified source and destination elements.
+ * Returns the set of all shortest paths between the specified source and
+ * destination elements. The path is computed using the default edge-weight
+ * function, which by default is hop-count.
*
* @param src source element
* @param dst destination element
@@ -40,9 +41,9 @@ public interface PathService {
Set<Path> getPaths(ElementId src, ElementId dst);
/**
- * Returns the set of all shortest paths, computed using the supplied
- * edge-weight entity, between the specified source and destination
- * network elements.
+ * Returns the set of all shortest paths between the specified source and
+ * destination network elements. The path is computed using the supplied
+ * edge-weight function.
*
* @param src source element
* @param dst destination element
@@ -52,8 +53,9 @@ public interface PathService {
Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight);
/**
- * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count,
- * between the specified source and destination devices.
+ * Returns the set of all disjoint shortest path pairs between the
+ * specified source and destination elements. The path is computed using
+ * the default edge-weight function, which by default is hop-count.
*
* @param src source device
* @param dst destination device
@@ -62,8 +64,9 @@ public interface PathService {
Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst);
/**
- * Returns the set of all disjoint shortest path pairs, computed using the supplied
- * edge-weight entity, between the specified source and destination devices.
+ * Returns the set of all disjoint shortest path pairs between the
+ * specified source and destination elements. The path is computed using
+ * the supplied edge-weight function.
*
* @param src source device
* @param dst destination device
@@ -74,8 +77,10 @@ public interface PathService {
LinkWeight weight);
/**
- * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count,
- * between the specified source and destination devices.
+ * Returns the set of all disjoint shortest path pairs between the
+ * specified source and destination elements and taking into consideration
+ * the provided risk profile. The path is computed using the default
+ * edge-weight function, which by default is hop-count.
*
* @param src source device
* @param dst destination device
@@ -86,8 +91,10 @@ public interface PathService {
Map<Link, Object> riskProfile);
/**
- * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count,
- * between the specified source and destination devices.
+ * Returns the set of all disjoint shortest path pairs between the
+ * specified source and destination elements and taking into consideration
+ * the provided risk profile. The path is computed using the supplied
+ * edge-weight function.
*
* @param src source device
* @param dst destination device
@@ -96,6 +103,7 @@ public interface PathService {
* @return set of all shortest paths between the two devices
*/
Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst,
- LinkWeight weight, Map<Link, Object> riskProfile);
+ LinkWeight weight,
+ Map<Link, Object> riskProfile);
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java
index 4030abdc..efe69f5f 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java
@@ -131,6 +131,10 @@ public final class TopoJson {
if (hh.subdued()) {
n.put(SUBDUE, true);
}
+ NodeBadge badge = hh.badge();
+ if (badge != null) {
+ n.set(BADGE, json(badge));
+ }
return n;
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
index 56a6ff63..d113fb98 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
@@ -222,6 +222,12 @@ public class CriteriaTest {
Criterion sameAsMatchMpls1 = Criteria.matchMplsLabel(mpls1);
Criterion matchMpls2 = Criteria.matchMplsLabel(mpls2);
+ byte mplsTc1 = 1;
+ byte mplsTc2 = 2;
+ Criterion matchMplsTc1 = Criteria.matchMplsTc(mplsTc1);
+ Criterion sameAsMatchMplsTc1 = Criteria.matchMplsTc(mplsTc1);
+ Criterion matchMplsTc2 = Criteria.matchMplsTc(mplsTc2);
+
long tunnelId1 = 1;
long tunnelId2 = 2;
Criterion matchTunnelId1 = Criteria.matchTunnelId(tunnelId1);
@@ -273,6 +279,12 @@ public class CriteriaTest {
Criterion sameAsMatchOduSignalType1 = Criteria.matchOduSignalType(oduSigType1);
Criterion matchOduSignalType2 = Criteria.matchOduSignalType(oduSigType2);
+ int pbbIsid1 = 1;
+ int pbbIsid2 = 2;
+ Criterion matchPbbIsid1 = Criteria.matchPbbIsid(pbbIsid1);
+ Criterion sameAsMatchPbbIsid1 = Criteria.matchPbbIsid(pbbIsid1);
+ Criterion matchPbbIsid2 = Criteria.matchPbbIsid(pbbIsid2);
+
/**
* Checks that a Criterion object has the proper type, and then converts
* it to the proper type.
@@ -326,10 +338,12 @@ public class CriteriaTest {
assertThatClassIsImmutable(IPv6NDTargetAddressCriterion.class);
assertThatClassIsImmutable(IPv6NDLinkLayerAddressCriterion.class);
assertThatClassIsImmutable(MplsCriterion.class);
+ assertThatClassIsImmutable(MplsTcCriterion.class);
assertThatClassIsImmutable(IPv6ExthdrFlagsCriterion.class);
assertThatClassIsImmutable(LambdaCriterion.class);
assertThatClassIsImmutable(OduSignalIdCriterion.class);
assertThatClassIsImmutable(OduSignalTypeCriterion.class);
+ assertThatClassIsImmutable(PbbIsidCriterion.class);
}
// PortCriterion class
@@ -752,6 +766,19 @@ public class CriteriaTest {
// TcpFlagsCriterion class
/**
+ * Test the matchTcpFlags method.
+ */
+ @Test
+ public void testMatchTcpFlagsMethod() {
+ Criterion matchTcpFlag = Criteria.matchTcpFlags(tcpFlags1);
+ TcpFlagsCriterion tcpFlagsCriterion =
+ checkAndConvert(matchTcpFlag,
+ Criterion.Type.TCP_FLAGS,
+ TcpFlagsCriterion.class);
+ assertThat(tcpFlagsCriterion.flags(), is(equalTo(tcpFlags1)));
+ }
+
+ /**
* Test the equals() method of the TcpFlagsCriterion class.
*/
@Test
@@ -1037,6 +1064,32 @@ public class CriteriaTest {
.testEquals();
}
+ // MplsTcCriterion class
+
+ /**
+ * Test the matchMplsTc method.
+ */
+ @Test
+ public void testMatchMplsTcMethod() {
+ Criterion matchMplsTc = Criteria.matchMplsTc(mplsTc1);
+ MplsTcCriterion mplsTcCriterion =
+ checkAndConvert(matchMplsTc,
+ Criterion.Type.MPLS_TC,
+ MplsTcCriterion.class);
+ assertThat(mplsTcCriterion.tc(), is(equalTo(mplsTc1)));
+ }
+
+ /**
+ * Test the equals() method of the MplsTcCriterion class.
+ */
+ @Test
+ public void testMplsTcCriterionEquals() {
+ new EqualsTester()
+ .addEqualityGroup(matchMplsTc1, sameAsMatchMplsTc1)
+ .addEqualityGroup(matchMplsTc2)
+ .testEquals();
+ }
+
// TunnelIdCriterion class
/**
@@ -1172,4 +1225,30 @@ public class CriteriaTest {
.addEqualityGroup(matchOduSignalType2)
.testEquals();
}
+
+ // PbbIsidCriterion class
+
+ /**
+ * Test the matchPbbIsid method.
+ */
+ @Test
+ public void testMatchPbbIsidMethod() {
+ Criterion matchPbbIsid = Criteria.matchPbbIsid(pbbIsid1);
+ PbbIsidCriterion pbbIsidCriterion =
+ checkAndConvert(matchPbbIsid,
+ Criterion.Type.PBB_ISID,
+ PbbIsidCriterion.class);
+ assertThat(pbbIsidCriterion.pbbIsid(), is(equalTo(pbbIsid1)));
+ }
+
+ /**
+ * Test the equals() method of the PbbIsidCriterion class.
+ */
+ @Test
+ public void testPbbIsidCriterionEquals() {
+ new EqualsTester()
+ .addEqualityGroup(matchPbbIsid1, sameAsMatchPbbIsid1)
+ .addEqualityGroup(matchPbbIsid2)
+ .testEquals();
+ }
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java
index 5f448221..d21c4b1b 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java
@@ -18,9 +18,7 @@ package org.onosproject.net.newresource;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import org.onlab.packet.VlanId;
-import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
-import org.onosproject.net.LinkKey;
import org.onosproject.net.PortNumber;
import org.onosproject.net.intent.IntentId;
@@ -29,18 +27,14 @@ public class ResourceAllocationTest {
private static final DeviceId D1 = DeviceId.deviceId("of:001");
private static final DeviceId D2 = DeviceId.deviceId("of:002");
private static final PortNumber P1 = PortNumber.portNumber(1);
- private static final ConnectPoint CP1_1 = new ConnectPoint(D1, P1);
- private static final ConnectPoint CP2_1 = new ConnectPoint(D2, P1);
private static final VlanId VLAN1 = VlanId.vlanId((short) 100);
private static final IntentId IID1 = IntentId.valueOf(30);
- private static final LinkKey LK1 = LinkKey.linkKey(CP1_1, CP2_1);
- private static final LinkKey LK2 = LinkKey.linkKey(CP2_1, CP1_1);
@Test
public void testEquals() {
- ResourceAllocation alloc1 = new ResourceAllocation(ResourcePath.discrete(LK1, VLAN1), IID1);
- ResourceAllocation sameAsAlloc1 = new ResourceAllocation(ResourcePath.discrete(LK1, VLAN1), IID1);
- ResourceAllocation alloc2 = new ResourceAllocation(ResourcePath.discrete(LK2, VLAN1), IID1);
+ ResourceAllocation alloc1 = new ResourceAllocation(ResourcePath.discrete(D1, P1, VLAN1), IID1);
+ ResourceAllocation sameAsAlloc1 = new ResourceAllocation(ResourcePath.discrete(D1, P1, VLAN1), IID1);
+ ResourceAllocation alloc2 = new ResourceAllocation(ResourcePath.discrete(D2, P1, VLAN1), IID1);
new EqualsTester()
.addEqualityGroup(alloc1, sameAsAlloc1)
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java
index 35dcf1ec..4bbb458c 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java
@@ -19,9 +19,7 @@ import com.google.common.testing.EqualsTester;
import org.junit.Test;
import org.onlab.packet.VlanId;
import org.onlab.util.Bandwidth;
-import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
-import org.onosproject.net.LinkKey;
import org.onosproject.net.PortNumber;
import java.util.Optional;
@@ -35,19 +33,17 @@ public class ResourcePathTest {
private static final DeviceId D1 = DeviceId.deviceId("of:001");
private static final DeviceId D2 = DeviceId.deviceId("of:002");
private static final PortNumber P1 = PortNumber.portNumber(1);
- private static final ConnectPoint CP1_1 = new ConnectPoint(D1, P1);
- private static final ConnectPoint CP2_1 = new ConnectPoint(D2, P1);
private static final VlanId VLAN1 = VlanId.vlanId((short) 100);
private static final Bandwidth BW1 = Bandwidth.gbps(2);
private static final Bandwidth BW2 = Bandwidth.gbps(1);
@Test
public void testEquals() {
- ResourcePath resource1 = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
- ResourcePath sameAsResource1 = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
- ResourcePath resource2 = ResourcePath.discrete(LinkKey.linkKey(CP2_1, CP1_1), VLAN1);
- ResourcePath resource3 = ResourcePath.continuous(BW1.bps(), LinkKey.linkKey(CP1_1, CP2_1), BW1);
- ResourcePath sameAsResource3 = ResourcePath.continuous(BW2.bps(), LinkKey.linkKey(CP1_1, CP2_1), BW1);
+ ResourcePath resource1 = ResourcePath.discrete(D1, P1, VLAN1);
+ ResourcePath sameAsResource1 = ResourcePath.discrete(D1, P1, VLAN1);
+ ResourcePath resource2 = ResourcePath.discrete(D2, P1, VLAN1);
+ ResourcePath resource3 = ResourcePath.continuous(BW1.bps(), D1, P1, BW1);
+ ResourcePath sameAsResource3 = ResourcePath.continuous(BW2.bps(), D1, P1, BW1);
new EqualsTester()
.addEqualityGroup(resource1, sameAsResource1)
@@ -57,13 +53,6 @@ public class ResourcePathTest {
}
@Test
- public void testCreateWithZeroComponent() {
- ResourcePath path = ResourcePath.discrete();
-
- assertThat(path, is(ResourcePath.ROOT));
- }
-
- @Test
public void testComponents() {
ResourcePath port = ResourcePath.discrete(D1, P1);
@@ -72,25 +61,24 @@ public class ResourcePathTest {
@Test
public void testThereIsParent() {
- ResourcePath path = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
- ResourcePath parent = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1));
+ ResourcePath path = ResourcePath.discrete(D1, P1, VLAN1);
+ ResourcePath parent = ResourcePath.discrete(D1, P1);
assertThat(path.parent(), is(Optional.of(parent)));
}
@Test
public void testNoParent() {
- ResourcePath path = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1));
+ ResourcePath path = ResourcePath.discrete(D1);
assertThat(path.parent(), is(Optional.of(ResourcePath.ROOT)));
}
@Test
public void testBase() {
- LinkKey linkKey = LinkKey.linkKey(CP1_1, CP2_1);
- ResourcePath path = ResourcePath.discrete(linkKey);
+ ResourcePath path = ResourcePath.discrete(D1);
- LinkKey child = (LinkKey) path.last();
- assertThat(child, is(linkKey));
+ DeviceId child = (DeviceId) path.last();
+ assertThat(child, is(D1));
}
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/store/persistence/PersistenceServiceAdapter.java b/framework/src/onos/core/api/src/test/java/org/onosproject/store/persistence/PersistenceServiceAdapter.java
new file mode 100644
index 00000000..3edfcc73
--- /dev/null
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/store/persistence/PersistenceServiceAdapter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015 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.onosproject.store.persistence;
+
+import org.onosproject.persistence.PersistenceService;
+import org.onosproject.persistence.PersistentMapBuilder;
+import org.onosproject.persistence.PersistentSetBuilder;
+
+/**
+ * Adapter for PersistenceService.
+ */
+public class PersistenceServiceAdapter implements PersistenceService {
+
+ @Override
+ public <K, V> PersistentMapBuilder<K, V> persistentMapBuilder() {
+ return null;
+ }
+
+ @Override
+ public <E> PersistentSetBuilder<E> persistentSetBuilder() {
+ return null;
+ }
+}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/store/persistence/TestPersistenceService.java b/framework/src/onos/core/api/src/test/java/org/onosproject/store/persistence/TestPersistenceService.java
new file mode 100644
index 00000000..a6d97458
--- /dev/null
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/store/persistence/TestPersistenceService.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 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.onosproject.store.persistence;
+
+import java.util.Map;
+
+import org.onosproject.persistence.PersistentMapBuilder;
+import org.onosproject.persistence.PersistentSetBuilder;
+import org.onosproject.store.service.Serializer;
+
+import com.google.common.collect.Maps;
+
+/**
+ * PersistenceService that produces in memory maps for use in unit testing.
+ */
+public class TestPersistenceService extends PersistenceServiceAdapter {
+ @Override
+ public <K, V> PersistentMapBuilder<K, V> persistentMapBuilder() {
+ return new TestPersistentMapBuilder<K, V>();
+ }
+
+ @Override
+ public <E> PersistentSetBuilder<E> persistentSetBuilder() {
+ throw new UnsupportedOperationException();
+ }
+
+ private static class TestPersistentMapBuilder<K, V> implements PersistentMapBuilder<K, V> {
+
+ @Override
+ public PersistentMapBuilder<K, V> withName(String name) {
+ return this;
+ }
+
+ @Override
+ public PersistentMapBuilder<K, V> withSerializer(Serializer serializer) {
+ return this;
+ }
+
+ @Override
+ public Map<K, V> build() {
+ return Maps.newConcurrentMap();
+ }
+ }
+}
diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
index 33dd46a3..1852ee29 100644
--- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
+++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
@@ -127,6 +127,7 @@ public final class EncodeCriterionCodecHelper {
formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
+ formatMap.put(Criterion.Type.EXTENSION, new FormatUnknown());
}
private interface CriterionTypeFormatter {
diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java b/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java
index 84cde424..c5263ed7 100644
--- a/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java
+++ b/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java
@@ -43,12 +43,15 @@ import org.onosproject.net.topology.ClusterId;
import org.onosproject.net.topology.DefaultTopologyCluster;
import org.onosproject.net.topology.DefaultTopologyVertex;
import org.onosproject.net.topology.GraphDescription;
+import org.onosproject.net.topology.HopCountLinkWeight;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyCluster;
import org.onosproject.net.topology.TopologyEdge;
import org.onosproject.net.topology.TopologyGraph;
import org.onosproject.net.topology.TopologyVertex;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
@@ -61,7 +64,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
import static org.onlab.util.Tools.isNullOrEmpty;
import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
-import static org.onosproject.net.Link.State.ACTIVE;
import static org.onosproject.net.Link.State.INACTIVE;
import static org.onosproject.net.Link.Type.INDIRECT;
@@ -71,18 +73,22 @@ import static org.onosproject.net.Link.Type.INDIRECT;
*/
public class DefaultTopology extends AbstractModel implements Topology {
+ private static final Logger log = LoggerFactory.getLogger(DefaultTopology.class);
+
private static final DijkstraGraphSearch<TopologyVertex, TopologyEdge> DIJKSTRA = new DijkstraGraphSearch<>();
private static final TarjanGraphSearch<TopologyVertex, TopologyEdge> TARJAN = new TarjanGraphSearch<>();
- private static final SuurballeGraphSearch<TopologyVertex, TopologyEdge> SUURBALLE =
- new SuurballeGraphSearch<>();
+ private static final SuurballeGraphSearch<TopologyVertex, TopologyEdge> SUURBALLE = new SuurballeGraphSearch<>();
+ private static LinkWeight defaultLinkWeight = null;
+ private static GraphPathSearch<TopologyVertex, TopologyEdge> defaultGraphPathSearch = null;
private final long time;
private final long creationTime;
private final long computeCost;
private final TopologyGraph graph;
- private final LinkWeight weight;
+ private final LinkWeight hopCountWeight;
+
private final Supplier<SccResult<TopologyVertex, TopologyEdge>> clusterResults;
private final Supplier<ImmutableMap<ClusterId, TopologyCluster>> clusters;
private final Supplier<ImmutableSet<ConnectPoint>> infrastructurePoints;
@@ -91,6 +97,30 @@ public class DefaultTopology extends AbstractModel implements Topology {
private final Supplier<ClusterIndexes> clusterIndexes;
/**
+ * Sets the default link-weight to be used when computing paths. If null is
+ * specified, the builtin default link-weight measuring hop-counts will be
+ * used.
+ *
+ * @param linkWeight new default link-weight
+ */
+ public static void setDefaultLinkWeight(LinkWeight linkWeight) {
+ log.info("Setting new default link-weight function to {}", linkWeight);
+ defaultLinkWeight = linkWeight;
+ }
+
+ /**
+ * Sets the default lpath search algorighm to be used when computing paths.
+ * If null is specified, the builtin default Dijkstra will be used.
+ *
+ * @param graphPathSearch new default algorithm
+ */
+ public static void setDefaultGraphPathSearch(GraphPathSearch<TopologyVertex, TopologyEdge> graphPathSearch) {
+ log.info("Setting new default graph path algorithm to {}", graphPathSearch);
+ defaultGraphPathSearch = graphPathSearch;
+ }
+
+
+ /**
* Creates a topology descriptor attributed to the specified provider.
*
* @param providerId identity of the provider
@@ -113,7 +143,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
this.clusterIndexes = Suppliers.memoize(() -> buildIndexes());
- this.weight = new HopCountLinkWeight(graph.getVertexes().size());
+ this.hopCountWeight = new HopCountLinkWeight(graph.getVertexes().size());
this.broadcastSets = Suppliers.memoize(() -> buildBroadcastSets());
this.infrastructurePoints = Suppliers.memoize(() -> findInfrastructurePoints());
this.computeCost = Math.max(0, System.nanoTime() - time);
@@ -294,7 +324,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
* @return set of shortest paths
*/
public Set<Path> getPaths(DeviceId src, DeviceId dst) {
- return getPaths(src, dst, null);
+ return getPaths(src, dst, linkWeight());
}
/**
@@ -307,8 +337,8 @@ public class DefaultTopology extends AbstractModel implements Topology {
* @return set of shortest paths
*/
public Set<Path> getPaths(DeviceId src, DeviceId dst, LinkWeight weight) {
- final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
- final DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
+ DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
+ DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
Set<TopologyVertex> vertices = graph.getVertexes();
if (!vertices.contains(srcV) || !vertices.contains(dstV)) {
// src or dst not part of the current graph
@@ -316,7 +346,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
}
GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
- DIJKSTRA.search(graph, srcV, dstV, weight, ALL_PATHS);
+ graphPathSearch().search(graph, srcV, dstV, weight, ALL_PATHS);
ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
builder.add(networkPath(path));
@@ -334,7 +364,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
* @return set of shortest disjoint path pairs
*/
public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst) {
- return getDisjointPaths(src, dst, (LinkWeight) null);
+ return getDisjointPaths(src, dst, linkWeight());
}
/**
@@ -347,8 +377,8 @@ public class DefaultTopology extends AbstractModel implements Topology {
* @return set of disjoint shortest path pairs
*/
public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight) {
- final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
- final DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
+ DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
+ DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
Set<TopologyVertex> vertices = graph.getVertexes();
if (!vertices.contains(srcV) || !vertices.contains(dstV)) {
// src or dst not part of the current graph
@@ -375,7 +405,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
* @return set of shortest disjoint paths
*/
private Set<DisjointPath> disjointPaths(DeviceId src, DeviceId dst, LinkWeight weight,
- Map<TopologyEdge, Object> riskProfile) {
+ Map<TopologyEdge, Object> riskProfile) {
DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
@@ -438,7 +468,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
* @return set of shortest disjoint paths
*/
public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, Map<Link, Object> riskProfile) {
- return getDisjointPaths(src, dst, null, riskProfile);
+ return getDisjointPaths(src, dst, linkWeight(), riskProfile);
}
// Converts graph path to a network path with the same cost.
@@ -499,8 +529,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
// Processes a map of broadcast sets for each cluster.
private ImmutableSetMultimap<ClusterId, ConnectPoint> buildBroadcastSets() {
- Builder<ClusterId, ConnectPoint> builder = ImmutableSetMultimap
- .builder();
+ Builder<ClusterId, ConnectPoint> builder = ImmutableSetMultimap.builder();
for (TopologyCluster cluster : clusters.get().values()) {
addClusterBroadcastSet(cluster, builder);
}
@@ -512,7 +541,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
// all other devices within the cluster.
private void addClusterBroadcastSet(TopologyCluster cluster, Builder<ClusterId, ConnectPoint> builder) {
// Use the graph root search results to build the broadcast set.
- Result<TopologyVertex, TopologyEdge> result = DIJKSTRA.search(graph, cluster.root(), null, weight, 1);
+ Result<TopologyVertex, TopologyEdge> result = DIJKSTRA.search(graph, cluster.root(), null, hopCountWeight, 1);
for (Map.Entry<TopologyVertex, Set<TopologyEdge>> entry : result.parents().entrySet()) {
TopologyVertex vertex = entry.getKey();
@@ -577,23 +606,12 @@ public class DefaultTopology extends AbstractModel implements Topology {
linksBuilder.build());
}
- // Link weight for measuring link cost as hop count with indirect links
- // being as expensive as traversing the entire graph to assume the worst.
- private static class HopCountLinkWeight implements LinkWeight {
- private final int indirectLinkCost;
-
- HopCountLinkWeight(int indirectLinkCost) {
- this.indirectLinkCost = indirectLinkCost;
- }
+ private GraphPathSearch<TopologyVertex, TopologyEdge> graphPathSearch() {
+ return defaultGraphPathSearch != null ? defaultGraphPathSearch : DIJKSTRA;
+ }
- @Override
- public double weight(TopologyEdge edge) {
- // To force preference to use direct paths first, make indirect
- // links as expensive as the linear vertex traversal.
- return edge.link().state() ==
- ACTIVE ? (edge.link().type() ==
- INDIRECT ? indirectLinkCost : 1) : -1;
- }
+ private LinkWeight linkWeight() {
+ return defaultLinkWeight != null ? defaultLinkWeight : hopCountWeight;
}
// Link weight for preventing traversal over indirect links.
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/edgeservice/impl/EdgeManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/edgeservice/impl/EdgeManager.java
index e992f7a4..cd7335d6 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/edgeservice/impl/EdgeManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/edgeservice/impl/EdgeManager.java
@@ -27,10 +27,10 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.event.AbstractListenerManager;
-import org.onosproject.event.Event;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.edge.EdgePortEvent;
import org.onosproject.net.edge.EdgePortListener;
@@ -38,17 +38,16 @@ import org.onosproject.net.edge.EdgePortService;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkService;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.topology.Topology;
-import org.onosproject.net.topology.TopologyEvent;
-import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyService;
import org.slf4j.Logger;
import java.nio.ByteBuffer;
-import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -73,7 +72,9 @@ public class EdgeManager
private final Map<DeviceId, Set<ConnectPoint>> connectionPoints = Maps.newConcurrentMap();
- private final TopologyListener topologyListener = new InnerTopologyListener();
+ private final LinkListener linkListener = new InnerLinkListener();
+
+ private final DeviceListener deviceListener = new InnerDeviceListener();
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
@@ -84,17 +85,23 @@ public class EdgeManager
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TopologyService topologyService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkService linkService;
+
@Activate
public void activate() {
eventDispatcher.addSink(EdgePortEvent.class, listenerRegistry);
- topologyService.addListener(topologyListener);
+ deviceService.addListener(deviceListener);
+ linkService.addListener(linkListener);
+ loadAllEdgePorts();
log.info("Started");
}
@Deactivate
public void deactivate() {
eventDispatcher.removeSink(EdgePortEvent.class);
- topologyService.removeListener(topologyListener);
+ deviceService.removeListener(deviceListener);
+ linkService.removeListener(linkListener);
log.info("Stopped");
}
@@ -142,31 +149,27 @@ public class EdgeManager
return new DefaultOutboundPacket(point.deviceId(), builder.build(), data);
}
- // Internal listener for topo events used to keep our edge-port cache
- // up to date.
- private class InnerTopologyListener implements TopologyListener {
+ private class InnerLinkListener implements LinkListener {
+
@Override
- public void event(TopologyEvent event) {
- topology = event.subject();
- List<Event> triggers = event.reasons();
- if (triggers != null) {
- triggers.forEach(reason -> {
- if (reason instanceof DeviceEvent) {
- processDeviceEvent((DeviceEvent) reason);
- } else if (reason instanceof LinkEvent) {
- processLinkEvent((LinkEvent) reason);
- }
- });
- } else {
- //FIXME special case of preexisting edgeport & no triggerless events could cause this to never hit and
- //never discover an edgeport that should have been discovered.
- loadAllEdgePorts();
- }
+ public void event(LinkEvent event) {
+ topology = topologyService.currentTopology();
+ processLinkEvent(event);
+ }
+ }
+
+ private class InnerDeviceListener implements DeviceListener {
+
+ @Override
+ public void event(DeviceEvent event) {
+ topology = topologyService.currentTopology();
+ processDeviceEvent(event);
}
}
// Initial loading of the edge port cache.
private void loadAllEdgePorts() {
+ topology = topologyService.currentTopology();
deviceService.getAvailableDevices().forEach(d -> deviceService.getPorts(d.id())
.forEach(p -> addEdgePort(new ConnectPoint(d.id(), p.number()))));
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
index 5958d1f5..63ee03ec 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
@@ -436,7 +436,7 @@ public class FlowRuleManager
log.debug("Adding rule in store, but not on switch {}", rule);
flowMissing(rule);
} catch (Exception e) {
- log.debug("Can't add missing flow rule {}", e.getMessage());
+ log.debug("Can't add missing flow rule:", e);
continue;
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
index 5ecdc7a2..33200b1a 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
@@ -16,7 +16,6 @@
package org.onosproject.net.flowobjective.impl;
import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -53,9 +52,11 @@ import org.onosproject.net.group.GroupService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -228,8 +229,10 @@ public class FlowObjectiveManager implements FlowObjectiveService {
flowObjectiveStore.getNextGroup(fwd.nextId()) == null) {
log.trace("Queuing forwarding objective for nextId {}", fwd.nextId());
// TODO: change to computeIfAbsent
- Set<PendingNext> pnext = pendingForwards.putIfAbsent(fwd.nextId(),
- Sets.newHashSet(new PendingNext(deviceId, fwd)));
+ Set<PendingNext> newset = Collections.newSetFromMap(
+ new ConcurrentHashMap<PendingNext, Boolean>());
+ newset.add(new PendingNext(deviceId, fwd));
+ Set<PendingNext> pnext = pendingForwards.putIfAbsent(fwd.nextId(), newset);
if (pnext != null) {
pnext.add(new PendingNext(deviceId, fwd));
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
index ebf681a2..ff711a02 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
@@ -34,6 +34,7 @@ import org.onosproject.net.HostId;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.net.NetworkResource;
+import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
@@ -302,11 +303,11 @@ public class ObjectiveTracker implements ObjectiveTrackerService {
private class InternalResourceListener implements ResourceListener {
@Override
public void event(ResourceEvent event) {
- Optional<Class<?>> linkEvent = event.subject().components().stream()
+ Optional<Class<?>> deviceEvent = event.subject().components().stream()
.map(Object::getClass)
- .filter(x -> x == LinkKey.class)
+ .filter(x -> x == PortNumber.class)
.findFirst();
- if (linkEvent.isPresent()) {
+ if (deviceEvent.isPresent()) {
executorService.execute(() -> {
if (delegate == null) {
return;
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
index 718c7bbf..5549918c 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.net.intent.impl.compiler;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
@@ -59,9 +60,9 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.LinkKey.linkKey;
@@ -120,11 +121,16 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> {
return Collections.emptyMap();
}
- List<ResourcePath> resources = labels.entrySet().stream()
- .map(x -> ResourcePath.discrete(linkKey(x.getKey().src(), x.getKey().src()), x.getValue()))
- .collect(Collectors.toList());
+ // for short term solution: same label is used for both directions
+ // TODO: introduce the concept of Tx and Rx resources of a port
+ Set<ResourcePath> resources = labels.entrySet().stream()
+ .flatMap(x -> Stream.of(
+ ResourcePath.discrete(x.getKey().src().deviceId(), x.getKey().src().port(), x.getValue()),
+ ResourcePath.discrete(x.getKey().dst().deviceId(), x.getKey().dst().port(), x.getValue())
+ ))
+ .collect(Collectors.toSet());
List<org.onosproject.net.newresource.ResourceAllocation> allocations =
- resourceService.allocate(intent.id(), resources);
+ resourceService.allocate(intent.id(), ImmutableList.copyOf(resources));
if (allocations.isEmpty()) {
Collections.emptyMap();
}
@@ -135,20 +141,23 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> {
private Map<LinkKey, MplsLabel> findMplsLabels(Set<LinkKey> links) {
Map<LinkKey, MplsLabel> labels = new HashMap<>();
for (LinkKey link : links) {
- Optional<MplsLabel> label = findMplsLabel(link);
- if (label.isPresent()) {
- labels.put(link, label.get());
+ Set<MplsLabel> forward = findMplsLabel(link.src());
+ Set<MplsLabel> backward = findMplsLabel(link.dst());
+ Set<MplsLabel> common = Sets.intersection(forward, backward);
+ if (common.isEmpty()) {
+ continue;
}
+ labels.put(link, common.iterator().next());
}
return labels;
}
- private Optional<MplsLabel> findMplsLabel(LinkKey link) {
- return resourceService.getAvailableResources(ResourcePath.discrete(link)).stream()
+ private Set<MplsLabel> findMplsLabel(ConnectPoint cp) {
+ return resourceService.getAvailableResources(ResourcePath.discrete(cp.deviceId(), cp.port())).stream()
.filter(x -> x.last() instanceof MplsLabel)
.map(x -> (MplsLabel) x.last())
- .findFirst();
+ .collect(Collectors.toSet());
}
private MplsLabel getMplsLabel(Map<LinkKey, MplsLabel> labels, LinkKey link) {
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
index 2941ddba..e017ac58 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
@@ -57,9 +57,9 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkArgument;
-import static org.onosproject.net.LinkKey.linkKey;
/**
* An intent compiler for {@link org.onosproject.net.intent.OpticalConnectivityIntent}.
@@ -182,7 +182,10 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
IndexedLambda minLambda = findFirstLambda(lambdas);
List<ResourcePath> lambdaResources = path.links().stream()
- .map(x -> ResourcePath.discrete(linkKey(x.src(), x.dst())))
+ .flatMap(x -> Stream.of(
+ ResourcePath.discrete(x.src().deviceId(), x.src().port()),
+ ResourcePath.discrete(x.dst().deviceId(), x.dst().port())
+ ))
.map(x -> x.child(minLambda))
.collect(Collectors.toList());
@@ -197,7 +200,10 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
private Set<IndexedLambda> findCommonLambdasOverLinks(List<Link> links) {
return links.stream()
- .map(x -> ResourcePath.discrete(linkKey(x.src(), x.dst())))
+ .flatMap(x -> Stream.of(
+ ResourcePath.discrete(x.src().deviceId(), x.src().port()),
+ ResourcePath.discrete(x.dst().deviceId(), x.dst().port())
+ ))
.map(resourceService::getAvailableResources)
.map(x -> Iterables.filter(x, r -> r.last() instanceof IndexedLambda))
.map(x -> Iterables.transform(x, r -> (IndexedLambda) r.last()))
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/link/impl/BasicLinkOperator.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/link/impl/BasicLinkOperator.java
index 801092f4..ff74dbde 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/link/impl/BasicLinkOperator.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/link/impl/BasicLinkOperator.java
@@ -38,6 +38,7 @@ import org.slf4j.Logger;
public final class BasicLinkOperator implements ConfigOperator {
private static final long DEF_BANDWIDTH = -1L;
+ private static final double DEF_METRIC = -1;
private static final Duration DEF_DURATION = Duration.ofNanos(-1L);
private static final Logger log = getLogger(BasicLinkOperator.class);
@@ -77,6 +78,9 @@ public final class BasicLinkOperator implements ConfigOperator {
*/
public static SparseAnnotations combine(BasicLinkConfig cfg, SparseAnnotations an) {
DefaultAnnotations.Builder b = DefaultAnnotations.builder();
+ if (cfg.metric() != DEF_METRIC) {
+ b.set(AnnotationKeys.METRIC, String.valueOf(cfg.metric()));
+ }
if (cfg.latency() != DEF_DURATION) {
b.set(AnnotationKeys.LATENCY, cfg.latency().toString());
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java
index 4fb0d7ba..bfc6a995 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java
@@ -16,19 +16,32 @@
package org.onosproject.net.newresource.impl;
import com.google.common.collect.Lists;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onlab.util.ItemNotFoundException;
import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.OchPort;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.PortNumber;
import org.onosproject.net.TributarySlot;
import org.onosproject.net.OduSignalType;
+import org.onosproject.net.behaviour.LambdaQuery;
+import org.onosproject.net.behaviour.MplsQuery;
+import org.onosproject.net.behaviour.VlanQuery;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
import org.onosproject.net.newresource.ResourceAdminService;
import org.onosproject.net.newresource.ResourcePath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Collections;
import java.util.List;
+import java.util.SortedSet;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -42,12 +55,19 @@ final class ResourceDeviceListener implements DeviceListener {
private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class);
+ private static final int MAX_VLAN_ID = VlanId.MAX_VLAN;
+ private static final List<VlanId> ENTIRE_VLAN_IDS = getEntireVlans();
+
+ private static final int MAX_MPLS_LABEL = 1048576;
+ private static final List<MplsLabel> ENTIRE_MPLS_LABELS = getEntireMplsLabels();
+
private static final int TOTAL_ODU2_TRIBUTARY_SLOTS = 8;
private static final int TOTAL_ODU4_TRIBUTARY_SLOTS = 80;
private static final List<TributarySlot> ENTIRE_ODU2_TRIBUTARY_SLOTS = getEntireOdu2TributarySlots();
private static final List<TributarySlot> ENTIRE_ODU4_TRIBUTARY_SLOTS = getEntireOdu4TributarySlots();
private final ResourceAdminService adminService;
+ private final DriverService driverService;
private final ExecutorService executor;
/**
@@ -56,8 +76,10 @@ final class ResourceDeviceListener implements DeviceListener {
* @param adminService instance invoked to register resources
* @param executor executor used for processing resource registration
*/
- ResourceDeviceListener(ResourceAdminService adminService, ExecutorService executor) {
+ ResourceDeviceListener(ResourceAdminService adminService, DriverService driverService,
+ ExecutorService executor) {
this.adminService = checkNotNull(adminService);
+ this.driverService = checkNotNull(driverService);
this.executor = checkNotNull(executor);
}
@@ -95,6 +117,26 @@ final class ResourceDeviceListener implements DeviceListener {
executor.submit(() -> {
adminService.registerResources(portPath);
+ // for VLAN IDs
+ if (isVlanEnabled(device.id(), port.number())) {
+ adminService.registerResources(Lists.transform(ENTIRE_VLAN_IDS, portPath::child));
+ }
+
+ // for MPLS labels
+ if (isMplsEnabled(device.id(), port.number())) {
+ adminService.registerResources(Lists.transform(ENTIRE_MPLS_LABELS, portPath::child));
+ }
+
+ // for Lambdas
+ SortedSet<OchSignal> lambdas = queryLambdas(device.id(), port.number());
+ if (!lambdas.isEmpty()) {
+ adminService.registerResources(lambdas.stream()
+ .map(portPath::child)
+ .collect(Collectors.toList()));
+ }
+
+ // for Tributary slots
+ // TODO: need to define Behaviour to make a query about OCh port
switch (port.type()) {
case OCH:
// register ODU TributarySlots against the OCH port
@@ -124,15 +166,68 @@ final class ResourceDeviceListener implements DeviceListener {
executor.submit(() -> adminService.unregisterResources(resource));
}
+ private SortedSet<OchSignal> queryLambdas(DeviceId did, PortNumber port) {
+ try {
+ DriverHandler handler = driverService.createHandler(did);
+ if (handler == null) {
+ return Collections.emptySortedSet();
+ }
+ LambdaQuery query = handler.behaviour(LambdaQuery.class);
+ return query.queryLambdas(port);
+ } catch (ItemNotFoundException e) {
+ return Collections.emptySortedSet();
+ }
+ }
+
+ private boolean isVlanEnabled(DeviceId device, PortNumber port) {
+ try {
+ DriverHandler handler = driverService.createHandler(device);
+ if (handler == null) {
+ return false;
+ }
+
+ VlanQuery query = handler.behaviour(VlanQuery.class);
+ return query != null && query.isEnabled(port);
+ } catch (ItemNotFoundException e) {
+ return false;
+ }
+ }
+
+ private boolean isMplsEnabled(DeviceId device, PortNumber port) {
+ try {
+ DriverHandler handler = driverService.createHandler(device);
+ if (handler == null) {
+ return false;
+ }
+
+ MplsQuery query = handler.behaviour(MplsQuery.class);
+ return query != null && query.isEnabled(port);
+ } catch (ItemNotFoundException e) {
+ return false;
+ }
+ }
+
+ private static List<VlanId> getEntireVlans() {
+ return IntStream.range(0, MAX_VLAN_ID)
+ .mapToObj(x -> VlanId.vlanId((short) x))
+ .collect(Collectors.toList());
+ }
+
+ private static List<MplsLabel> getEntireMplsLabels() {
+ // potentially many objects are created
+ return IntStream.range(0, MAX_MPLS_LABEL)
+ .mapToObj(MplsLabel::mplsLabel)
+ .collect(Collectors.toList());
+ }
+
private static List<TributarySlot> getEntireOdu2TributarySlots() {
return IntStream.rangeClosed(1, TOTAL_ODU2_TRIBUTARY_SLOTS)
- .mapToObj(x -> TributarySlot.of(x))
+ .mapToObj(TributarySlot::of)
.collect(Collectors.toList());
}
private static List<TributarySlot> getEntireOdu4TributarySlots() {
return IntStream.rangeClosed(1, TOTAL_ODU4_TRIBUTARY_SLOTS)
- .mapToObj(x -> TributarySlot.of(x))
+ .mapToObj(TributarySlot::of)
.collect(Collectors.toList());
}
-
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java
deleted file mode 100644
index 9d2e06f5..00000000
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright 2015 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.onosproject.net.newresource.impl;
-
-import com.google.common.collect.Lists;
-import org.onlab.packet.MplsLabel;
-import org.onlab.packet.VlanId;
-import org.onlab.util.ItemNotFoundException;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Link;
-import org.onosproject.net.LinkKey;
-import org.onosproject.net.behaviour.MplsQuery;
-import org.onosproject.net.behaviour.VlanQuery;
-import org.onosproject.net.driver.DriverHandler;
-import org.onosproject.net.driver.DriverService;
-import org.onosproject.net.link.LinkEvent;
-import org.onosproject.net.link.LinkListener;
-import org.onosproject.net.newresource.ResourceAdminService;
-import org.onosproject.net.newresource.ResourcePath;
-
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * An implementation of LinkListener registering links as resources.
- */
-final class ResourceLinkListener implements LinkListener {
-
- private static final int TOTAL_VLANS = 1024;
- private static final List<VlanId> ENTIRE_VLAN_IDS = getEntireVlans();
-
- private static final int TOTAL_MPLS_LABELS = 1048576;
- private static final List<MplsLabel> ENTIRE_MPLS_LABELS = getEntireMplsLabels();
-
- private final ResourceAdminService adminService;
- private final DriverService driverService;
- private final ExecutorService executor;
-
- /**
- * Creates an instance with the specified ResourceAdminService and ExecutorService.
- *
- * @param adminService instance invoked to register resources
- * @param driverService driver service instance
- * @param executor executor used for processing resource registration
- */
- ResourceLinkListener(ResourceAdminService adminService, DriverService driverService, ExecutorService executor) {
- this.adminService = checkNotNull(adminService);
- this.driverService = checkNotNull(driverService);
- this.executor = checkNotNull(executor);
- }
-
- @Override
- public void event(LinkEvent event) {
- Link link = event.subject();
- switch (event.type()) {
- case LINK_ADDED:
- registerLinkResource(link);
- break;
- case LINK_REMOVED:
- unregisterLinkResource(link);
- break;
- default:
- break;
- }
- }
-
- private void registerLinkResource(Link link) {
- executor.submit(() -> {
- // register the link
- LinkKey linkKey = LinkKey.linkKey(link);
- adminService.registerResources(ResourcePath.discrete(linkKey));
-
- ResourcePath linkPath = ResourcePath.discrete(linkKey);
- // register VLAN IDs against the link
- if (isEnabled(link, this::isVlanEnabled)) {
- adminService.registerResources(Lists.transform(ENTIRE_VLAN_IDS, linkPath::child));
- }
-
- // register MPLS labels against the link
- if (isEnabled(link, this::isMplsEnabled)) {
- adminService.registerResources(Lists.transform(ENTIRE_MPLS_LABELS, linkPath::child));
- }
- });
- }
-
- private void unregisterLinkResource(Link link) {
- LinkKey linkKey = LinkKey.linkKey(link);
- executor.submit(() -> adminService.unregisterResources(ResourcePath.discrete(linkKey)));
- }
-
- private boolean isEnabled(Link link, Predicate<ConnectPoint> predicate) {
- return predicate.test(link.src()) && predicate.test(link.dst());
- }
-
- private boolean isVlanEnabled(ConnectPoint cp) {
- try {
- DriverHandler handler = driverService.createHandler(cp.deviceId());
- if (handler == null) {
- return false;
- }
-
- VlanQuery query = handler.behaviour(VlanQuery.class);
- return query != null && query.isEnabled(cp.port());
- } catch (ItemNotFoundException e) {
- return false;
- }
- }
-
- private boolean isMplsEnabled(ConnectPoint cp) {
- try {
- DriverHandler handler = driverService.createHandler(cp.deviceId());
- if (handler == null) {
- return false;
- }
-
- MplsQuery query = handler.behaviour(MplsQuery.class);
- return query != null && query.isEnabled(cp.port());
- } catch (ItemNotFoundException e) {
- return false;
- }
- }
-
- private static List<VlanId> getEntireVlans() {
- return IntStream.range(0, TOTAL_VLANS)
- .mapToObj(x -> VlanId.vlanId((short) x))
- .collect(Collectors.toList());
- }
-
- private static List<MplsLabel> getEntireMplsLabels() {
- // potentially many objects are created
- return IntStream.range(0, TOTAL_MPLS_LABELS)
- .mapToObj(MplsLabel::mplsLabel)
- .collect(Collectors.toList());
- }
-}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java
index 143f8c2b..e8042661 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java
@@ -24,8 +24,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.DriverService;
-import org.onosproject.net.link.LinkListener;
-import org.onosproject.net.link.LinkService;
import org.onosproject.net.newresource.ResourceAdminService;
import java.util.concurrent.ExecutorService;
@@ -49,25 +47,18 @@ public final class ResourceRegistrar {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected LinkService linkService;
-
private DeviceListener deviceListener;
- private LinkListener linkListener;
private final ExecutorService executor =
Executors.newSingleThreadExecutor(groupedThreads("onos/resource", "registrar"));
@Activate
public void activate() {
- deviceListener = new ResourceDeviceListener(adminService, executor);
+ deviceListener = new ResourceDeviceListener(adminService, driverService, executor);
deviceService.addListener(deviceListener);
- linkListener = new ResourceLinkListener(adminService, driverService, executor);
- linkService.addListener(linkListener);
}
@Deactivate
public void deactivate() {
deviceService.removeListener(deviceListener);
- linkService.removeListener(linkListener);
}
}
diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/edgeservice/impl/EdgeManagerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/edgeservice/impl/EdgeManagerTest.java
index 319412fe..70be5deb 100644
--- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/edgeservice/impl/EdgeManagerTest.java
+++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/edgeservice/impl/EdgeManagerTest.java
@@ -22,7 +22,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.common.event.impl.TestEventDispatcher;
-import org.onosproject.event.Event;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
@@ -31,15 +30,17 @@ import org.onosproject.net.NetTestTools;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.edge.EdgePortEvent;
import org.onosproject.net.edge.EdgePortListener;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkServiceAdapter;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketServiceAdapter;
import org.onosproject.net.topology.Topology;
-import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyServiceAdapter;
@@ -58,7 +59,6 @@ import static org.onosproject.net.edge.EdgePortEvent.Type.EDGE_PORT_ADDED;
import static org.onosproject.net.edge.EdgePortEvent.Type.EDGE_PORT_REMOVED;
import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED;
-import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED;
/**
* Test of the edge port manager. Each device has ports '0' through 'numPorts - 1'
@@ -74,6 +74,8 @@ public class EdgeManagerTest {
private final Map<DeviceId, Device> devices = Maps.newConcurrentMap();
private Set<OutboundPacket> packets = Sets.newConcurrentHashSet();
private final EdgePortListener testListener = new TestListener(events);
+ private TestLinkManager testLinkManager;
+ private TestDeviceManager testDeviceManager;
private TestTopologyManager testTopologyManager;
@Before
@@ -82,8 +84,11 @@ public class EdgeManagerTest {
injectEventDispatcher(mgr, new TestEventDispatcher());
testTopologyManager = new TestTopologyManager(infrastructurePorts);
mgr.topologyService = testTopologyManager;
- mgr.deviceService = new TestDeviceManager(devices);
+ testDeviceManager = new TestDeviceManager(devices);
+ mgr.deviceService = testDeviceManager;
mgr.packetService = new TestPacketManager();
+ testLinkManager = new TestLinkManager();
+ mgr.linkService = testLinkManager;
mgr.activate();
mgr.addListener(testListener);
@@ -108,11 +113,11 @@ public class EdgeManagerTest {
assertFalse("no ports expected", mgr.getEdgePoints().iterator().hasNext());
assertFalse("Expected isEdge to return false",
- mgr.isEdgePoint(NetTestTools.connectPoint(Integer.toString(1), 1)));
+ mgr.isEdgePoint(NetTestTools.connectPoint(Integer.toString(1), 1)));
removeInfraPort(NetTestTools.connectPoint(Integer.toString(1), 1));
assertTrue("Expected isEdge to return false",
- mgr.isEdgePoint(NetTestTools.connectPoint(Integer.toString(1), 1)));
+ mgr.isEdgePoint(NetTestTools.connectPoint(Integer.toString(1), 1)));
}
@Test
@@ -121,69 +126,57 @@ public class EdgeManagerTest {
ConnectPoint testPoint, referencePoint;
//Testing link removal
- List<Event> eventsToAdd = Lists.newArrayList();
- eventsToAdd.add(new LinkEvent(LINK_REMOVED, NetTestTools.link("a", 1, "b", 2)));
- TopologyEvent event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
- testTopologyManager.listener.event(event);
+ testLinkManager.listener.event(new LinkEvent(LINK_REMOVED, NetTestTools.link("a", 1, "b", 2)));
assertTrue("The list contained an unexpected number of events", events.size() == 2);
assertTrue("The first element is of the wrong type.",
- events.get(0).type() == EDGE_PORT_ADDED);
- assertTrue("The second element is of the wrong type.",
- events.get(1).type() == EDGE_PORT_ADDED);
+ events.get(0).type() == EDGE_PORT_ADDED);
testPoint = events.get(0).subject();
referencePoint = NetTestTools.connectPoint("a", 1);
assertTrue("The port numbers of the first element are incorrect",
- testPoint.port().toLong() == referencePoint.port().toLong());
+ testPoint.port().toLong() == referencePoint.port().toLong());
assertTrue("The device id of the first element is incorrect.",
- testPoint.deviceId().equals(referencePoint.deviceId()));
+ testPoint.deviceId().equals(referencePoint.deviceId()));
testPoint = events.get(1).subject();
referencePoint = NetTestTools.connectPoint("b", 2);
assertTrue("The port numbers of the second element are incorrect",
- testPoint.port().toLong() == referencePoint.port().toLong());
+ testPoint.port().toLong() == referencePoint.port().toLong());
assertTrue("The device id of the second element is incorrect.",
- testPoint.deviceId().equals(referencePoint.deviceId()));
+ testPoint.deviceId().equals(referencePoint.deviceId()));
//Rebroadcast event to ensure it results in no additional events
- testTopologyManager.listener.event(event);
+ testLinkManager.listener.event(new LinkEvent(LINK_REMOVED, NetTestTools.link("a", 1, "b", 2)));
assertTrue("The list contained an unexpected number of events", events.size() == 2);
//Testing link adding when links to remove exist
- eventsToAdd.clear();
events.clear();
- eventsToAdd.add(new LinkEvent(LINK_ADDED, NetTestTools.link("a", 1, "b", 2)));
- event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
- testTopologyManager.listener.event(event);
+ testLinkManager.listener.event(new LinkEvent(LINK_ADDED, NetTestTools.link("a", 1, "b", 2)));
assertTrue("The list contained an unexpected number of events", events.size() == 2);
assertTrue("The first element is of the wrong type.",
- events.get(0).type() == EDGE_PORT_REMOVED);
+ events.get(0).type() == EDGE_PORT_REMOVED);
assertTrue("The second element is of the wrong type.",
- events.get(1).type() == EDGE_PORT_REMOVED);
+ events.get(1).type() == EDGE_PORT_REMOVED);
testPoint = events.get(0).subject();
referencePoint = NetTestTools.connectPoint("a", 1);
assertTrue("The port numbers of the first element are incorrect",
- testPoint.port().toLong() == referencePoint.port().toLong());
+ testPoint.port().toLong() == referencePoint.port().toLong());
assertTrue("The device id of the first element is incorrect.",
- testPoint.deviceId().equals(referencePoint.deviceId()));
+ testPoint.deviceId().equals(referencePoint.deviceId()));
testPoint = events.get(1).subject();
referencePoint = NetTestTools.connectPoint("b", 2);
assertTrue("The port numbers of the second element are incorrect",
- testPoint.port().toLong() == referencePoint.port().toLong());
+ testPoint.port().toLong() == referencePoint.port().toLong());
assertTrue("The device id of the second element is incorrect.",
- testPoint.deviceId().equals(referencePoint.deviceId()));
+ testPoint.deviceId().equals(referencePoint.deviceId()));
//Apparent duplicate of previous method tests removal when the elements have already been removed
- eventsToAdd.clear();
events.clear();
- eventsToAdd.add(new LinkEvent(LINK_ADDED, NetTestTools.link("a", 1, "b", 2)));
- event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
- testTopologyManager.listener.event(event);
-
+ testLinkManager.listener.event(new LinkEvent(LINK_ADDED, NetTestTools.link("a", 1, "b", 2)));
assertTrue("The list should contain no events, the removed elements don't exist.", events.size() == 0);
}
@@ -192,8 +185,7 @@ public class EdgeManagerTest {
//Setup
Device referenceDevice;
- TopologyEvent event;
- List<Event> eventsToAdd = Lists.newArrayList();
+ DeviceEvent event;
int numDevices = 10;
int numInfraPorts = 5;
totalPorts = 10;
@@ -201,14 +193,13 @@ public class EdgeManagerTest {
//Test response to device added events
referenceDevice = NetTestTools.device("1");
- eventsToAdd.add(new DeviceEvent(DEVICE_ADDED, referenceDevice,
- new DefaultPort(referenceDevice, PortNumber.portNumber(1), true)));
- event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
- testTopologyManager.listener.event(event);
+ event = new DeviceEvent(DEVICE_ADDED, referenceDevice,
+ new DefaultPort(referenceDevice, PortNumber.portNumber(1), true));
+ testDeviceManager.listener.event(event);
//Check that ports were populated correctly
assertTrue("Unexpected number of new ports added",
- mgr.deviceService.getPorts(NetTestTools.did("1")).size() == 10);
+ mgr.deviceService.getPorts(NetTestTools.did("1")).size() == 10);
//Check that of the ten ports the half that are infrastructure ports aren't added
assertEquals("Unexpected number of new edge ports added", (totalPorts - numInfraPorts), events.size());
@@ -219,15 +210,15 @@ public class EdgeManagerTest {
//Names here are irrelevant, the first 5 ports are populated as infrastructure, 6-10 are edge
for (int index = 0; index < events.size(); index++) {
assertEquals("Port added had unexpected port number.",
- events.get(index).subject().port(),
- NetTestTools.connectPoint("a", index + numInfraPorts + 1).port());
+ events.get(index).subject().port(),
+ NetTestTools.connectPoint("a", index + numInfraPorts + 1).port());
}
events.clear();
//Repost the event to test repeated posts
- testTopologyManager.listener.event(event);
+ testDeviceManager.listener.event(event);
assertEquals("The redundant notification should not have created additional notifications.",
- 0, events.size());
+ 0, events.size());
//Calculate the size of the returned iterable of edge points.
Iterable<ConnectPoint> pts = mgr.getEdgePoints();
Iterator pointIterator = pts.iterator();
@@ -238,45 +229,41 @@ public class EdgeManagerTest {
assertEquals("Unexpected number of edge points", totalPorts - numInfraPorts, count);
//Testing device removal
events.clear();
- eventsToAdd.clear();
- eventsToAdd.add(new DeviceEvent(DEVICE_REMOVED, referenceDevice,
- new DefaultPort(referenceDevice, PortNumber.portNumber(1), true)));
- event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
- testTopologyManager.listener.event(event);
+ event = (new DeviceEvent(DEVICE_REMOVED, referenceDevice,
+ new DefaultPort(referenceDevice, PortNumber.portNumber(1), true)));
+ testDeviceManager.listener.event(event);
assertEquals("There should be five new events from removal of edge points",
- totalPorts - numInfraPorts, events.size());
+ totalPorts - numInfraPorts, events.size());
for (int index = 0; index < events.size(); index++) {
//Assert that the correct port numbers were removed in the correct order
assertEquals("Port removed had unexpected port number.",
- events.get(index).subject().port(),
- (NetTestTools.connectPoint("a", index + numInfraPorts + 1).port()));
+ events.get(index).subject().port(),
+ (NetTestTools.connectPoint("a", index + numInfraPorts + 1).port()));
//Assert that the events are of the correct type
assertEquals("Unexpected type of event", events.get(index).type(), EDGE_PORT_REMOVED);
}
events.clear();
//Rebroadcast event to check that it triggers no new behavior
- testTopologyManager.listener.event(event);
+ testDeviceManager.listener.event(event);
assertEquals("Rebroadcast of removal event should not produce additional events",
- 0, events.size());
+ 0, events.size());
//Testing device status change, changed from unavailable to available
events.clear();
- eventsToAdd.clear();
//Make sure that the devicemanager shows the device as available.
addDevice(referenceDevice, "1", 5);
devices.put(referenceDevice.id(), referenceDevice);
- eventsToAdd.add(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, referenceDevice));
- event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
- testTopologyManager.listener.event(event);
+ event = new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, referenceDevice);
+ testDeviceManager.listener.event(event);
//An earlier setup set half of the reference device ports to infrastructure
assertEquals("An unexpected number of events were generated.", totalPorts - numInfraPorts, events.size());
for (int i = 0; i < 5; i++) {
assertEquals("The event was not of the right type", events.get(i).type(), EDGE_PORT_ADDED);
}
events.clear();
- testTopologyManager.listener.event(event);
+ testDeviceManager.listener.event(event);
assertEquals("No events should have been generated for a set of existing ports.", 0, events.size());
//Test removal when state changes when the device becomes unavailable
@@ -288,21 +275,20 @@ public class EdgeManagerTest {
no events will be generated since no ports will be provided in getPorts() to EdgeManager.
*/
alwaysReturnPorts = true;
- testTopologyManager.listener.event(event);
+ testDeviceManager.listener.event(event);
alwaysReturnPorts = false;
assertEquals("An unexpected number of events were created.", totalPorts - numInfraPorts, events.size());
for (int i = 0; i < 5; i++) {
EdgePortEvent edgeEvent = events.get(i);
assertEquals("The event is of an unexpected type.",
- EdgePortEvent.Type.EDGE_PORT_REMOVED, edgeEvent.type());
+ EdgePortEvent.Type.EDGE_PORT_REMOVED, edgeEvent.type());
assertEquals("The event pertains to an unexpected port", PortNumber.portNumber(i + numInfraPorts + 1),
- edgeEvent.subject().port());
+ edgeEvent.subject().port());
}
}
@Test
public void testInternalCache() {
- List<Event> eventsToAdd = Lists.newArrayList();
int numDevices = 10;
//Number of infrastructure ports per device
int numPorts = 5;
@@ -312,11 +298,8 @@ public class EdgeManagerTest {
for (int i = 0; i < numDevices; i++) {
Device newDevice = NetTestTools.device(Integer.toString(i));
devices.put(newDevice.id(), newDevice);
- eventsToAdd.add(new DeviceEvent(DEVICE_ADDED, newDevice));
+ testDeviceManager.listener.event(new DeviceEvent(DEVICE_ADDED, newDevice));
}
- TopologyEvent event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
- testTopologyManager.listener.event(event);
-
//Check all ports have correct designations
ConnectPoint testPoint;
for (int deviceNum = 0; deviceNum < numDevices; deviceNum++) {
@@ -334,7 +317,7 @@ public class EdgeManagerTest {
count++;
}
assertEquals("There are an unexpeceted number of edge points returned.",
- (totalPorts - numPorts) * numDevices, count);
+ (totalPorts - numPorts) * numDevices, count);
for (int deviceNumber = 0; deviceNumber < numDevices; deviceNumber++) {
count = 0;
for (ConnectPoint ignored : mgr.getEdgePoints(NetTestTools.did("1"))) {
@@ -349,8 +332,7 @@ public class EdgeManagerTest {
public void testEmit() {
byte[] arr = new byte[10];
Device referenceDevice;
- TopologyEvent event;
- List<Event> eventsToAdd = Lists.newArrayList();
+ DeviceEvent event;
int numDevices = 10;
int numInfraPorts = 5;
totalPorts = 10;
@@ -360,16 +342,16 @@ public class EdgeManagerTest {
}
for (int i = 0; i < numDevices; i++) {
referenceDevice = NetTestTools.device(Integer.toString(i));
- eventsToAdd.add(new DeviceEvent(DEVICE_ADDED, referenceDevice,
- new DefaultPort(referenceDevice, PortNumber.portNumber(1), true)));
+ testDeviceManager.listener.event(new DeviceEvent(DEVICE_ADDED, referenceDevice,
+ new DefaultPort(referenceDevice,
+ PortNumber.portNumber(1),
+ true)));
}
- event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
- testTopologyManager.listener.event(event);
mgr.emitPacket(ByteBuffer.wrap(arr), Optional.<TrafficTreatment>empty());
assertEquals("There were an unexpected number of emitted packets",
- (totalPorts - numInfraPorts) * numDevices, packets.size());
+ (totalPorts - numInfraPorts) * numDevices, packets.size());
Iterator<OutboundPacket> packetIter = packets.iterator();
OutboundPacket packet;
while (packetIter.hasNext()) {
@@ -381,7 +363,7 @@ public class EdgeManagerTest {
mgr.emitPacket(NetTestTools.did(Integer.toString(1)), ByteBuffer.wrap(arr), Optional.<TrafficTreatment>empty());
assertEquals("Unexpected number of outbound packets were emitted.",
- totalPorts - numInfraPorts, packets.size());
+ totalPorts - numInfraPorts, packets.size());
packetIter = packets.iterator();
while (packetIter.hasNext()) {
packet = packetIter.next();
@@ -455,6 +437,7 @@ public class EdgeManagerTest {
}
private class TestDeviceManager extends DeviceServiceAdapter {
+ private DeviceListener listener;
private Map<DeviceId, Device> devices;
@@ -490,6 +473,17 @@ public class EdgeManagerTest {
public Iterable<Device> getAvailableDevices() {
return devices.values();
}
+
+
+ @Override
+ public void addListener(DeviceListener listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ public void removeListener(DeviceListener listener) {
+ this.listener = null;
+ }
}
private class TestPacketManager extends PacketServiceAdapter {
@@ -499,6 +493,15 @@ public class EdgeManagerTest {
}
}
+ private class TestLinkManager extends LinkServiceAdapter {
+ private LinkListener listener;
+
+ @Override
+ public void addListener(LinkListener listener) {
+ this.listener = listener;
+ }
+ }
+
private class TestListener implements EdgePortListener {
private List<EdgePortEvent> events;
diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java
index eb7f2ccd..7cee0d0e 100644
--- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java
+++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java
@@ -29,8 +29,10 @@ import org.onlab.junit.TestUtils.TestUtilsException;
import org.onosproject.core.IdGenerator;
import org.onosproject.event.Event;
import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.NetworkResource;
+import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.intent.Intent;
@@ -52,7 +54,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
-import static org.onosproject.net.LinkKey.linkKey;
import static org.onosproject.net.newresource.ResourceEvent.Type.*;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.device;
@@ -231,7 +232,7 @@ public class ObjectiveTrackerTest {
@Test
public void testResourceEvent() throws Exception {
ResourceEvent event = new ResourceEvent(RESOURCE_ADDED,
- ResourcePath.discrete(linkKey(link("a", 1, "b", 1))));
+ ResourcePath.discrete(DeviceId.deviceId("a"), PortNumber.portNumber(1)));
resourceListener.event(event);
assertThat(
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
index c6d300c9..af2bb74d 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
@@ -20,6 +20,7 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Maps;
+
import org.onlab.util.HexString;
import org.onlab.util.SharedExecutors;
import org.onlab.util.Tools;
@@ -33,6 +34,7 @@ import org.onosproject.store.service.Versioned;
import org.slf4j.Logger;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
@@ -92,18 +94,25 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
private static final String ERROR_NULL_KEY = "Key cannot be null";
private static final String ERROR_NULL_VALUE = "Null values are not allowed";
- private final LoadingCache<K, String> keyCache = CacheBuilder.newBuilder()
+ // String representation of serialized byte[] -> original key Object
+ private final LoadingCache<String, K> keyCache = CacheBuilder.newBuilder()
.softValues()
- .build(new CacheLoader<K, String>() {
+ .build(new CacheLoader<String, K>() {
@Override
- public String load(K key) {
- return HexString.toHexString(serializer.encode(key));
+ public K load(String key) {
+ return serializer.decode(HexString.fromHexString(key));
}
});
+ protected String sK(K key) {
+ String s = HexString.toHexString(serializer.encode(key));
+ keyCache.put(s, key);
+ return s;
+ }
+
protected K dK(String key) {
- return serializer.decode(HexString.fromHexString(key));
+ return keyCache.getUnchecked(key);
}
public DefaultAsyncConsistentMap(String name,
@@ -207,7 +216,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
public CompletableFuture<Boolean> containsKey(K key) {
checkNotNull(key, ERROR_NULL_KEY);
final MeteringAgent.Context timer = monitor.startTimer(CONTAINS_KEY);
- return database.mapContainsKey(name, keyCache.getUnchecked(key))
+ return database.mapContainsKey(name, sK(key))
.whenComplete((r, e) -> timer.stop(e));
}
@@ -223,7 +232,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
public CompletableFuture<Versioned<V>> get(K key) {
checkNotNull(key, ERROR_NULL_KEY);
final MeteringAgent.Context timer = monitor.startTimer(GET);
- return database.mapGet(name, keyCache.getUnchecked(key))
+ return database.mapGet(name, sK(key))
.whenComplete((r, e) -> timer.stop(e))
.thenApply(v -> v != null ? v.map(serializer::decode) : null);
}
@@ -328,10 +337,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
public CompletableFuture<Set<K>> keySet() {
final MeteringAgent.Context timer = monitor.startTimer(KEY_SET);
return database.mapKeySet(name)
- .thenApply(s -> s
- .stream()
- .map(this::dK)
- .collect(Collectors.toSet()))
+ .thenApply(s -> newMappingKeySet(s))
.whenComplete((r, e) -> timer.stop(e));
}
@@ -351,10 +357,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
final MeteringAgent.Context timer = monitor.startTimer(ENTRY_SET);
return database.mapEntrySet(name)
.whenComplete((r, e) -> timer.stop(e))
- .thenApply(s -> s
- .stream()
- .map(this::mapRawEntry)
- .collect(Collectors.toSet()));
+ .thenApply(s -> newMappingEntrySet(s));
}
@Override
@@ -413,17 +416,31 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
checkIfUnmodifiable();
}
+ private Set<K> newMappingKeySet(Set<String> s) {
+ return new MappingSet<>(s, Collections::unmodifiableSet,
+ this::sK, this::dK);
+ }
+
+ private Set<Entry<K, Versioned<V>>> newMappingEntrySet(Set<Entry<String, Versioned<byte[]>>> s) {
+ return new MappingSet<>(s, Collections::unmodifiableSet,
+ this::reverseMapRawEntry, this::mapRawEntry);
+ }
+
private Map.Entry<K, Versioned<V>> mapRawEntry(Map.Entry<String, Versioned<byte[]>> e) {
return Maps.immutableEntry(dK(e.getKey()), e.getValue().<V>map(serializer::decode));
}
+ private Map.Entry<String, Versioned<byte[]>> reverseMapRawEntry(Map.Entry<K, Versioned<V>> e) {
+ return Maps.immutableEntry(sK(e.getKey()), e.getValue().map(serializer::encode));
+ }
+
private CompletableFuture<UpdateResult<K, V>> updateAndGet(K key,
Match<V> oldValueMatch,
Match<Long> oldVersionMatch,
V value) {
beforeUpdate(key);
return database.mapUpdate(name,
- keyCache.getUnchecked(key),
+ sK(key),
oldValueMatch.map(serializer::encode),
oldVersionMatch,
value == null ? null : serializer.encode(value))
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/MappingSet.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/MappingSet.java
new file mode 100644
index 00000000..9bf80a73
--- /dev/null
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/MappingSet.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2015 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.onosproject.store.consistent.impl;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import com.google.common.collect.Iterators;
+
+/**
+ * Set view backed by Set with element type {@code <BACK>} but returns
+ * element as {@code <OUT>} for convenience.
+ *
+ * @param <BACK> Backing {@link Set} element type.
+ * MappingSet will follow this type's equality behavior.
+ * @param <OUT> external facing element type.
+ * MappingSet will ignores equality defined by this type.
+ */
+class MappingSet<BACK, OUT> implements Set<OUT> {
+
+ private final Set<BACK> backedSet;
+ private final Function<OUT, BACK> toBack;
+ private final Function<BACK, OUT> toOut;
+
+ public MappingSet(Set<BACK> backedSet,
+ Function<Set<BACK>, Set<BACK>> supplier,
+ Function<OUT, BACK> toBack, Function<BACK, OUT> toOut) {
+ this.backedSet = supplier.apply(backedSet);
+ this.toBack = toBack;
+ this.toOut = toOut;
+ }
+
+ @Override
+ public int size() {
+ return backedSet.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return backedSet.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return backedSet.contains(toBack.apply((OUT) o));
+ }
+
+ @Override
+ public Iterator<OUT> iterator() {
+ return Iterators.transform(backedSet.iterator(), toOut::apply);
+ }
+
+ @Override
+ public Object[] toArray() {
+ return backedSet.stream()
+ .map(toOut)
+ .toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ return backedSet.stream()
+ .map(toOut)
+ .toArray(size -> {
+ if (size < a.length) {
+ return (T[]) new Object[size];
+ } else {
+ Arrays.fill(a, null);
+ return a;
+ }
+ });
+ }
+
+ @Override
+ public boolean add(OUT e) {
+ return backedSet.add(toBack.apply(e));
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ return backedSet.remove(toBack.apply((OUT) o));
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ return c.stream()
+ .map(e -> toBack.apply((OUT) e))
+ .allMatch(backedSet::contains);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends OUT> c) {
+ return backedSet.addAll(c.stream().map(toBack).collect(Collectors.toList()));
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ return backedSet.retainAll(c.stream()
+ .map(x -> toBack.apply((OUT) x))
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ return backedSet.removeAll(c.stream()
+ .map(x -> toBack.apply((OUT) x))
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public void clear() {
+ backedSet.clear();
+ }
+}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java
index 83319c3e..cc32a735 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java
@@ -350,7 +350,7 @@ public class DistributedGroupStore
// Check if a group is existing with the same key
Group existingGroup = getGroup(groupDesc.deviceId(), groupDesc.appCookie());
if (existingGroup != null) {
- log.warn("Group already exists with the same key {} in dev:{} with id:{}",
+ log.warn("Group already exists with the same key {} in dev:{} with id:0x{}",
groupDesc.appCookie(), groupDesc.deviceId(),
Integer.toHexString(existingGroup.id().id()));
return;
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java
index 20124576..836a3c22 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java
@@ -15,26 +15,8 @@
*/
package org.onosproject.store.host.impl;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static org.onosproject.net.DefaultAnnotations.merge;
-import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
-import static org.onosproject.net.host.HostEvent.Type.HOST_MOVED;
-import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
-import static org.onosproject.net.host.HostEvent.Type.HOST_UPDATED;
-import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
-import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -60,22 +42,34 @@ import org.onosproject.net.host.HostStoreDelegate;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.store.AbstractStore;
import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.EventuallyConsistentMap;
-import org.onosproject.store.service.EventuallyConsistentMapEvent;
-import org.onosproject.store.service.EventuallyConsistentMapListener;
-import org.onosproject.store.service.LogicalClockService;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.slf4j.Logger;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.onosproject.net.DefaultAnnotations.merge;
+import static org.onosproject.net.host.HostEvent.Type.*;
+import static org.slf4j.LoggerFactory.getLogger;
/**
* Manages the inventory of hosts using a {@code EventuallyConsistentMap}.
*/
@Component(immediate = true)
@Service
-public class ECHostStore
+public class DistributedHostStore
extends AbstractStore<HostEvent, HostStoreDelegate>
implements HostStore {
@@ -84,15 +78,13 @@ public class ECHostStore
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected LogicalClockService clockService;
-
- private EventuallyConsistentMap<HostId, DefaultHost> hosts;
+ private ConsistentMap<HostId, DefaultHost> host;
+ private Map<HostId, DefaultHost> hosts;
private final ConcurrentHashMap<HostId, DefaultHost> prevHosts =
new ConcurrentHashMap<>();
- private EventuallyConsistentMapListener<HostId, DefaultHost> hostLocationTracker =
+ private MapEventListener<HostId, DefaultHost> hostLocationTracker =
new HostLocationTracker();
@Activate
@@ -100,21 +92,22 @@ public class ECHostStore
KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API);
- hosts = storageService.<HostId, DefaultHost>eventuallyConsistentMapBuilder()
+ host = storageService.<HostId, DefaultHost>consistentMapBuilder()
.withName("onos-hosts")
- .withSerializer(hostSerializer)
- .withTimestampProvider((k, v) -> clockService.getTimestamp())
+ .withRelaxedReadConsistency()
+ .withSerializer(Serializer.using(hostSerializer.build()))
.build();
- hosts.addListener(hostLocationTracker);
+ hosts = host.asJavaMap();
+
+ host.addListener(hostLocationTracker);
log.info("Started");
}
@Deactivate
public void deactivate() {
- hosts.removeListener(hostLocationTracker);
- hosts.destroy();
+ host.removeListener(hostLocationTracker);
prevHosts.clear();
log.info("Stopped");
@@ -249,11 +242,11 @@ public class ECHostStore
return collection.stream().filter(predicate).collect(Collectors.toSet());
}
- private class HostLocationTracker implements EventuallyConsistentMapListener<HostId, DefaultHost> {
+ private class HostLocationTracker implements MapEventListener<HostId, DefaultHost> {
@Override
- public void event(EventuallyConsistentMapEvent<HostId, DefaultHost> event) {
- DefaultHost host = checkNotNull(event.value());
- if (event.type() == PUT) {
+ public void event(MapEvent<HostId, DefaultHost> event) {
+ DefaultHost host = checkNotNull(event.value().value());
+ if (event.type() == MapEvent.Type.INSERT) {
Host prevHost = prevHosts.put(host.id(), host);
if (prevHost == null) {
notifyDelegate(new HostEvent(HOST_ADDED, host));
@@ -262,7 +255,7 @@ public class ECHostStore
} else if (!Objects.equals(prevHost, host)) {
notifyDelegate(new HostEvent(HOST_UPDATED, host, prevHost));
}
- } else if (event.type() == REMOVE) {
+ } else if (event.type() == MapEvent.Type.REMOVE) {
if (prevHosts.remove(host.id()) != null) {
notifyDelegate(new HostEvent(HOST_REMOVED, host));
}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/proxyarp/impl/DistributedProxyArpStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/proxyarp/impl/DistributedProxyArpStore.java
index 851185b5..4d7e7f33 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/proxyarp/impl/DistributedProxyArpStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/proxyarp/impl/DistributedProxyArpStore.java
@@ -113,7 +113,7 @@ public class DistributedProxyArpStore implements ProxyArpStore {
@Override
public void forward(ConnectPoint outPort, Host subject, ByteBuffer packet) {
- NodeId nodeId = mastershipService.getMasterFor(outPort.deviceId());
+ /*NodeId nodeId = mastershipService.getMasterFor(outPort.deviceId());
if (nodeId.equals(localNodeId)) {
if (delegate != null) {
delegate.emitResponse(outPort, packet);
@@ -122,7 +122,10 @@ public class DistributedProxyArpStore implements ProxyArpStore {
log.info("Forwarding ARP response from {} to {}", subject.id(), outPort);
commService.unicast(new ArpResponseMessage(outPort, subject, packet.array()),
ARP_RESPONSE_MESSAGE, serializer::encode, nodeId);
- }
+ }*/
+ //FIXME: Code above may be unnecessary and therefore cluster messaging
+ // and pendingMessages could be pruned as well.
+ delegate.emitResponse(outPort, packet);
}
@Override
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/topology/impl/DistributedTopologyStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/topology/impl/DistributedTopologyStore.java
index da4e3cc4..2641635d 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/topology/impl/DistributedTopologyStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/topology/impl/DistributedTopologyStore.java
@@ -15,44 +15,43 @@
*/
package org.onosproject.store.topology.impl;
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.onlab.util.Tools.isNullOrEmpty;
-import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
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.Modified;
+import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.graph.GraphPathSearch;
import org.onlab.util.KryoNamespace;
+import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.common.DefaultTopology;
import org.onosproject.event.Event;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
-import org.onosproject.net.DisjointPath;
+import org.onosproject.net.device.DeviceService;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.topology.ClusterId;
import org.onosproject.net.topology.DefaultGraphDescription;
+import org.onosproject.net.topology.GeoDistanceLinkWeight;
import org.onosproject.net.topology.GraphDescription;
import org.onosproject.net.topology.LinkWeight;
+import org.onosproject.net.topology.MetricLinkWeight;
+import org.onosproject.net.topology.PathAdminService;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyCluster;
+import org.onosproject.net.topology.TopologyEdge;
import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyGraph;
import org.onosproject.net.topology.TopologyStore;
import org.onosproject.net.topology.TopologyStoreDelegate;
+import org.onosproject.net.topology.TopologyVertex;
import org.onosproject.store.AbstractStore;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
@@ -60,8 +59,23 @@ import org.onosproject.store.service.EventuallyConsistentMapEvent;
import org.onosproject.store.service.EventuallyConsistentMapListener;
import org.onosproject.store.service.LogicalClockService;
import org.onosproject.store.service.StorageService;
+import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.onlab.util.Tools.get;
+import static org.onlab.util.Tools.isNullOrEmpty;
+import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED;
+import static org.slf4j.LoggerFactory.getLogger;
+
/**
* Manages inventory of topology snapshots using trivial in-memory
* structures implementation.
@@ -73,9 +87,12 @@ import org.slf4j.Logger;
@Service
public class DistributedTopologyStore
extends AbstractStore<TopologyEvent, TopologyStoreDelegate>
- implements TopologyStore {
+ implements TopologyStore, PathAdminService {
private final Logger log = getLogger(getClass());
+
+ private static final String FORMAT = "Settings: linkWeightFunction={}";
+
private volatile DefaultTopology current =
new DefaultTopology(ProviderId.NONE,
new DefaultGraphDescription(0L, System.currentTimeMillis(),
@@ -91,6 +108,21 @@ public class DistributedTopologyStore
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MastershipService mastershipService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ComponentConfigService configService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ private static final String HOP_COUNT = "hopCount";
+ private static final String LINK_METRIC = "linkMetric";
+ private static final String GEO_DISTANCE = "geoDistance";
+
+ private static final String DEFAULT_LINK_WEIGHT_FUNCTION = "hopCount";
+ @Property(name = "linkWeightFunction", value = DEFAULT_LINK_WEIGHT_FUNCTION,
+ label = "Default link-weight function: hopCount, linkMetric, geoDistance")
+ private String linkWeightFunction = DEFAULT_LINK_WEIGHT_FUNCTION;
+
// Cluster root to broadcast points bindings to allow convergence to
// a shared broadcast tree; node that is the master of the cluster root
// is the primary.
@@ -100,7 +132,8 @@ public class DistributedTopologyStore
new InternalBroadcastPointListener();
@Activate
- public void activate() {
+ protected void activate() {
+ configService.registerProperties(getClass());
KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API);
@@ -114,12 +147,30 @@ public class DistributedTopologyStore
}
@Deactivate
- public void deactivate() {
+ protected void deactivate() {
+ configService.unregisterProperties(getClass(), false);
broadcastPoints.removeListener(listener);
broadcastPoints.destroy();
log.info("Stopped");
}
+ @Modified
+ protected void modified(ComponentContext context) {
+ Dictionary<?, ?> properties = context.getProperties();
+
+ String newLinkWeightFunction = get(properties, "linkWeightFunction");
+ if (newLinkWeightFunction != null &&
+ !Objects.equals(newLinkWeightFunction, linkWeightFunction)) {
+ linkWeightFunction = newLinkWeightFunction;
+ LinkWeight weight = linkWeightFunction.equals(LINK_METRIC) ?
+ new MetricLinkWeight() :
+ linkWeightFunction.equals(GEO_DISTANCE) ?
+ new GeoDistanceLinkWeight(deviceService) : null;
+ setDefaultLinkWeight(weight);
+ }
+ log.info(FORMAT, linkWeightFunction);
+ }
+
@Override
public Topology currentTopology() {
return current;
@@ -263,6 +314,16 @@ public class DistributedTopologyStore
return (DefaultTopology) topology;
}
+ @Override
+ public void setDefaultLinkWeight(LinkWeight linkWeight) {
+ DefaultTopology.setDefaultLinkWeight(linkWeight);
+ }
+
+ @Override
+ public void setDefaultGraphPathSearch(GraphPathSearch<TopologyVertex, TopologyEdge> graphPathSearch) {
+ DefaultTopology.setDefaultGraphPathSearch(graphPathSearch);
+ }
+
private class InternalBroadcastPointListener
implements EventuallyConsistentMapListener<DeviceId, Set<ConnectPoint>> {
@Override
diff --git a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMapTest.java b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMapTest.java
new file mode 100644
index 00000000..3f6402c5
--- /dev/null
+++ b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMapTest.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2015 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.onosproject.store.consistent.impl;
+
+import static java.util.Collections.unmodifiableCollection;
+import static java.util.Collections.unmodifiableSet;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.Transaction;
+import org.onosproject.store.service.Versioned;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import net.kuujo.copycat.Task;
+import net.kuujo.copycat.cluster.Cluster;
+import net.kuujo.copycat.resource.ResourceState;
+
+/**
+ *
+ */
+public class DefaultAsyncConsistentMapTest {
+
+ private static final ApplicationId APP_ID = new DefaultApplicationId(42, "what");
+
+ private static final TestData KEY1A = new TestData("One", "a");
+ private static final TestData KEY1B = new TestData("One", "b");
+
+ private static final TestData VALUE2A = new TestData("Two", "a");
+ private static final TestData VALUE2B = new TestData("Two", "b");
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testKeySet() throws Exception {
+ DefaultAsyncConsistentMap<TestData, TestData> map;
+ String name = "map_name";
+ Database database = new TestDatabase();
+ Serializer serializer = Serializer.forTypes(TestData.class);
+
+ map = new DefaultAsyncConsistentMap<>(name, APP_ID, database, serializer,
+ false, false, false);
+ map.put(KEY1A, VALUE2A);
+ map.put(KEY1B, VALUE2A);
+
+ Set<TestData> set = map.keySet().get();
+ assertEquals("Should contain 2 keys",
+ 2, set.size());
+ assertThat(set.contains(KEY1A), is(true));
+ assertThat(set.contains(KEY1B), is(true));
+ assertThat(set.contains(new TestData("One", "a")), is(true));
+ }
+
+ @Test
+ public void testEntrySet() throws Exception {
+ DefaultAsyncConsistentMap<TestData, TestData> map;
+ String name = "map_name";
+ Database database = new TestDatabase();
+ Serializer serializer = Serializer.forTypes(TestData.class);
+
+ map = new DefaultAsyncConsistentMap<>(name, APP_ID, database, serializer,
+ false, false, false);
+ map.put(KEY1A, VALUE2A);
+ map.put(KEY1B, VALUE2A);
+
+ assertEquals("Should contain 2 entry",
+ 2,
+ map.entrySet().get().size());
+ }
+
+ /**
+ * Object to be used as a test data.
+ *
+ * {@link Object#equals(Object)} use only part of it's fields.
+ *
+ * As a result there can be 2 instances which the
+ * serialized bytes are not-equal but
+ * {@link Object#equals(Object)}-wise they are equal.
+ */
+ public static class TestData {
+
+ private final String theKey;
+
+ @SuppressWarnings("unused")
+ private final String notUsedForEquals;
+
+ public TestData(String theKey, String notUsedForEquals) {
+ this.theKey = theKey;
+ this.notUsedForEquals = notUsedForEquals;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(theKey);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof TestData) {
+ TestData that = (TestData) obj;
+ return Objects.equals(this.theKey, that.theKey);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("theKey", theKey)
+ .add("notUsedForEquals", notUsedForEquals)
+ .toString();
+ }
+ }
+
+ /**
+ * {@link Database} implementation for testing.
+ *
+ * There is only 1 backing Map, {@code mapName} will be ignored.
+ */
+ public class TestDatabase implements Database {
+
+ Map<String, Versioned<byte[]>> map = new ConcurrentHashMap<>();
+
+ @Override
+ public CompletableFuture<Set<String>> maps() {
+ return CompletableFuture.completedFuture(ImmutableSet.of());
+ }
+
+ @Override
+ public CompletableFuture<Map<String, Long>> counters() {
+ return CompletableFuture.completedFuture(ImmutableMap.of());
+ }
+
+ @Override
+ public CompletableFuture<Integer> mapSize(String mapName) {
+ return CompletableFuture.completedFuture(map.size());
+ }
+
+ @Override
+ public CompletableFuture<Boolean> mapIsEmpty(String mapName) {
+ return CompletableFuture.completedFuture(map.isEmpty());
+ }
+
+ @Override
+ public CompletableFuture<Boolean> mapContainsKey(String mapName,
+ String key) {
+ return CompletableFuture.completedFuture(map.containsKey(key));
+ }
+
+ @Override
+ public CompletableFuture<Boolean> mapContainsValue(String mapName,
+ byte[] value) {
+ return CompletableFuture.completedFuture(map.containsValue(value));
+ }
+
+ @Override
+ public CompletableFuture<Versioned<byte[]>> mapGet(String mapName,
+ String key) {
+ return CompletableFuture.completedFuture(map.get(key));
+ }
+
+ @Override
+ public synchronized CompletableFuture<Result<UpdateResult<String, byte[]>>> mapUpdate(String mapName,
+ String key,
+ Match<byte[]> valueMatch,
+ Match<Long> versionMatch,
+ byte[] value) {
+
+ boolean updated = false;
+ final Versioned<byte[]> oldValue;
+ final Versioned<byte[]> newValue;
+
+ Versioned<byte[]> old = map.getOrDefault(key, new Versioned<byte[]>(null, 0));
+ if (valueMatch.matches(old.value()) && versionMatch.matches(old.version())) {
+ updated = true;
+ oldValue = old;
+ newValue = new Versioned<>(value, old.version() + 1);
+ map.put(key, newValue);
+ } else {
+ updated = false;
+ oldValue = old;
+ newValue = old;
+ }
+ return CompletableFuture.completedFuture(
+ Result.ok(new UpdateResult<String, byte[]>(updated,
+ mapName, key, oldValue, newValue)));
+ }
+
+ @Override
+ public CompletableFuture<Result<Void>> mapClear(String mapName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Set<String>> mapKeySet(String mapName) {
+ return CompletableFuture.completedFuture(unmodifiableSet(map.keySet()));
+ }
+
+ @Override
+ public CompletableFuture<Collection<Versioned<byte[]>>> mapValues(String mapName) {
+ return CompletableFuture.completedFuture(unmodifiableCollection(map.values()));
+ }
+
+ @Override
+ public CompletableFuture<Set<Entry<String, Versioned<byte[]>>>> mapEntrySet(String mapName) {
+ return CompletableFuture.completedFuture(unmodifiableSet(map.entrySet()));
+ }
+
+ @Override
+ public CompletableFuture<Long> counterAddAndGet(String counterName,
+ long delta) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Long> counterGetAndAdd(String counterName,
+ long delta) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Void> counterSet(String counterName,
+ long value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Boolean> counterCompareAndSet(String counterName,
+ long expectedValue,
+ long update) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Long> counterGet(String counterName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Long> queueSize(String queueName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Void> queuePush(String queueName,
+ byte[] entry) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<byte[]> queuePop(String queueName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<byte[]> queuePeek(String queueName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<CommitResponse> prepareAndCommit(Transaction transaction) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Boolean> prepare(Transaction transaction) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<CommitResponse> commit(Transaction transaction) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Boolean> rollback(Transaction transaction) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String name() {
+ return "name";
+ }
+
+ @Override
+ public ResourceState state() {
+ return ResourceState.HEALTHY;
+ }
+
+ @Override
+ public Cluster cluster() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Database addStartupTask(Task<CompletableFuture<Void>> task) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Database addShutdownTask(Task<CompletableFuture<Void>> task) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CompletableFuture<Database> open() {
+ return CompletableFuture.completedFuture(this);
+ }
+
+ @Override
+ public boolean isOpen() {
+ return true;
+ }
+
+ @Override
+ public CompletableFuture<Void> close() {
+ return CompletableFuture.completedFuture(null);
+ }
+
+ @Override
+ public boolean isClosed() {
+ return false;
+ }
+
+ @Override
+ public void registerConsumer(Consumer<StateMachineUpdate> consumer) {
+ }
+
+ @Override
+ public void unregisterConsumer(Consumer<StateMachineUpdate> consumer) {
+ }
+ }
+
+}
diff --git a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java
index ef8d9924..b74aa370 100644
--- a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java
+++ b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java
@@ -42,12 +42,13 @@ import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.event.AbstractEvent;
-import org.onosproject.persistence.impl.PersistenceManager;
+import org.onosproject.persistence.PersistenceService;
import org.onosproject.store.Timestamp;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
import org.onosproject.store.cluster.messaging.MessageSubject;
import org.onosproject.store.impl.LogicalTimestamp;
+import org.onosproject.store.persistence.TestPersistenceService;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.serializers.KryoSerializer;
import org.onosproject.store.service.EventuallyConsistentMap;
@@ -82,7 +83,7 @@ public class EventuallyConsistentMapImplTest {
private EventuallyConsistentMap<String, String> ecMap;
- private PersistenceManager persistenceService;
+ private PersistenceService persistenceService;
private ClusterService clusterService;
private ClusterCommunicationService clusterCommunicator;
private SequentialClockService<String, String> clockService;
@@ -138,8 +139,7 @@ public class EventuallyConsistentMapImplTest {
clusterCommunicator = createMock(ClusterCommunicationService.class);
- persistenceService = new PersistenceManager();
- persistenceService.activate();
+ persistenceService = new TestPersistenceService();
// Add expectation for adding cluster message subscribers which
// delegate to our ClusterCommunicationService implementation. This
// allows us to get a reference to the map's internal cluster message
diff --git a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/host/impl/ECHostStoreTest.java b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/host/impl/DistributedHostStoreTest.java
index a7077a81..0732126d 100644
--- a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/host/impl/ECHostStoreTest.java
+++ b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/host/impl/DistributedHostStoreTest.java
@@ -27,8 +27,6 @@ import org.onosproject.net.HostLocation;
import org.onosproject.net.host.DefaultHostDescription;
import org.onosproject.net.host.HostDescription;
import org.onosproject.net.provider.ProviderId;
-import org.onosproject.store.Timestamp;
-import org.onosproject.store.service.LogicalClockService;
import org.onosproject.store.service.TestStorageService;
import java.util.HashSet;
@@ -37,9 +35,9 @@ import java.util.Set;
/**
* Tests for the ECHostStore.
*/
-public class ECHostStoreTest extends TestCase {
+public class DistributedHostStoreTest extends TestCase {
- private ECHostStore ecXHostStore;
+ private DistributedHostStore ecXHostStore;
private static final HostId HOSTID = HostId.hostId(MacAddress.valueOf("1a:1a:1a:1a:1a:1a"));
@@ -50,10 +48,9 @@ public class ECHostStoreTest extends TestCase {
@Before
public void setUp() {
- ecXHostStore = new ECHostStore();
+ ecXHostStore = new DistributedHostStore();
ecXHostStore.storageService = new TestStorageService();
- ecXHostStore.clockService = new TestLogicalClockService();
ecXHostStore.activate();
}
@@ -83,13 +80,4 @@ public class ECHostStoreTest extends TestCase {
assertTrue(host.ipAddresses().contains(IP2));
}
- /**
- * Mocks the LogicalClockService class.
- */
- class TestLogicalClockService implements LogicalClockService {
- @Override
- public Timestamp getTimestamp() {
- return null;
- }
- }
} \ No newline at end of file
diff --git a/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java b/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java
index 3428bce1..05c577c0 100644
--- a/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java
+++ b/framework/src/onos/core/store/persistence/src/main/java/org/onosproject/persistence/impl/PersistenceManager.java
@@ -47,7 +47,6 @@ import static org.slf4j.LoggerFactory.getLogger;
public class PersistenceManager implements PersistenceService {
private static final String DATABASE_PATH = "../data/localDB";
-
private static final String ENCLOSING_FOLDER = "../data";
static final String MAP_PREFIX = "map:";
diff --git a/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java b/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java
index 45b4da1a..7df518e2 100644
--- a/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java
+++ b/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java
@@ -374,13 +374,13 @@ public class KryoSerializerTest {
@Test
public void testResourcePath() {
- testSerializedEquals(ResourcePath.discrete(LinkKey.linkKey(CP1, CP2), VLAN1));
+ testSerializedEquals(ResourcePath.discrete(DID1, P1, VLAN1));
}
@Test
public void testResourceAllocation() {
testSerializedEquals(new org.onosproject.net.newresource.ResourceAllocation(
- ResourcePath.discrete(LinkKey.linkKey(CP1, CP2), VLAN1),
+ ResourcePath.discrete(DID1, P1, VLAN1),
IntentId.valueOf(30)));
}