ONOS-7050 Refactored PI translation service and store
The translation store is now able to maintain mappings between
translated entities and specific instances of a PI entry in the network
(i.e. applied to a device).
The translation service has been refactored to allow users to
learn and forget translated entities.
The refactoring of the P4Runtime driver using this service will be
submitted separatelly.
Change-Id: Iaafd87d90232514853ca0dea0115dbae4f6e7886
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractPiTranslatorImpl.java b/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractPiTranslatorImpl.java
new file mode 100644
index 0000000..5d7178c
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/AbstractPiTranslatorImpl.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pi.impl;
+
+import org.onosproject.net.pi.runtime.PiEntity;
+import org.onosproject.net.pi.runtime.PiHandle;
+import org.onosproject.net.pi.service.PiTranslatable;
+import org.onosproject.net.pi.service.PiTranslatedEntity;
+import org.onosproject.net.pi.service.PiTranslationStore;
+import org.onosproject.net.pi.service.PiTranslator;
+
+import java.util.Optional;
+
+/**
+ * Abstract implementation of a PI translator backed by a PI translation store.
+ *
+ * @param <T> PD entity class
+ * @param <E> PI entity class
+ */
+public abstract class AbstractPiTranslatorImpl
+ <T extends PiTranslatable, E extends PiEntity>
+ implements PiTranslator<T, E> {
+
+ private final PiTranslationStore<T, E> store;
+
+ AbstractPiTranslatorImpl(PiTranslationStore<T, E> store) {
+ this.store = store;
+ }
+
+ @Override
+ public void learn(PiHandle<E> handle, PiTranslatedEntity<T, E> entity) {
+ store.addOrUpdate(handle, entity);
+ }
+
+ @Override
+ public Optional<PiTranslatedEntity<T, E>> lookup(PiHandle<E> handle) {
+ return Optional.ofNullable(store.get(handle));
+ }
+
+ @Override
+ public void forget(PiHandle<E> handle) {
+ store.remove(handle);
+ }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/CriterionTranslatorHelper.java b/core/net/src/main/java/org/onosproject/net/pi/impl/CriterionTranslatorHelper.java
index 22d53fd..7f43e22 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/CriterionTranslatorHelper.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/CriterionTranslatorHelper.java
@@ -86,13 +86,13 @@
import org.onosproject.net.pi.runtime.PiFieldMatch;
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
+import org.onosproject.net.pi.service.PiTranslationException;
import java.util.Map;
import static java.lang.String.format;
import static org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException;
import static org.onosproject.net.pi.impl.CriterionTranslator.CriterionTranslatorException;
-import static org.onosproject.net.pi.service.PiTranslationService.PiTranslationException;
/**
* Helper class to translate criterion instances to PI field matches.
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslator.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorImpl.java
similarity index 98%
rename from core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslator.java
rename to core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorImpl.java
index d856fd3..f04e7b0 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslator.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiFlowRuleTranslatorImpl.java
@@ -46,6 +46,7 @@
import org.onosproject.net.pi.runtime.PiTableAction;
import org.onosproject.net.pi.runtime.PiTableEntry;
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
+import org.onosproject.net.pi.service.PiTranslationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,17 +63,16 @@
import static org.onosproject.net.pi.impl.CriterionTranslatorHelper.translateCriterion;
import static org.onosproject.net.pi.impl.PiUtils.getInterpreterOrNull;
import static org.onosproject.net.pi.impl.PiUtils.translateTableId;
-import static org.onosproject.net.pi.service.PiTranslationService.PiTranslationException;
/**
* Implementation of flow rule translation logic.
*/
-final class PiFlowRuleTranslator {
+final class PiFlowRuleTranslatorImpl {
public static final int MAX_PI_PRIORITY = (int) Math.pow(2, 24);
- private static final Logger log = LoggerFactory.getLogger(PiFlowRuleTranslator.class);
+ private static final Logger log = LoggerFactory.getLogger(PiFlowRuleTranslatorImpl.class);
- private PiFlowRuleTranslator() {
+ private PiFlowRuleTranslatorImpl() {
// Hide constructor.
}
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslator.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslatorImpl.java
similarity index 95%
rename from core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslator.java
rename to core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslatorImpl.java
index 255ccb9..eeabebc 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslator.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiGroupTranslatorImpl.java
@@ -29,21 +29,21 @@
import org.onosproject.net.pi.runtime.PiActionGroupMemberId;
import org.onosproject.net.pi.runtime.PiGroupKey;
import org.onosproject.net.pi.runtime.PiTableAction;
-import org.onosproject.net.pi.service.PiTranslationService.PiTranslationException;
+import org.onosproject.net.pi.service.PiTranslationException;
import java.nio.ByteBuffer;
import static java.lang.String.format;
-import static org.onosproject.net.pi.impl.PiFlowRuleTranslator.translateTreatment;
+import static org.onosproject.net.pi.impl.PiFlowRuleTranslatorImpl.translateTreatment;
import static org.onosproject.net.pi.impl.PiUtils.getInterpreterOrNull;
import static org.onosproject.net.pi.runtime.PiTableAction.Type.ACTION;
/**
* Implementation of group translation logic.
*/
-final class PiGroupTranslator {
+final class PiGroupTranslatorImpl {
- private PiGroupTranslator() {
+ private PiGroupTranslatorImpl() {
// Hides constructor.
}
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiTranslationServiceImpl.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiTranslationServiceImpl.java
index b6d90f0..9780fac 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiTranslationServiceImpl.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiTranslationServiceImpl.java
@@ -28,19 +28,19 @@
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.group.Group;
import org.onosproject.net.pi.model.PiPipeconf;
-import org.onosproject.net.pi.model.PiPipeconfId;
import org.onosproject.net.pi.runtime.PiActionGroup;
import org.onosproject.net.pi.runtime.PiTableEntry;
-import org.onosproject.net.pi.service.PiTranslatable;
+import org.onosproject.net.pi.service.PiFlowRuleTranslationStore;
+import org.onosproject.net.pi.service.PiFlowRuleTranslator;
+import org.onosproject.net.pi.service.PiGroupTranslationStore;
+import org.onosproject.net.pi.service.PiGroupTranslator;
+import org.onosproject.net.pi.service.PiTranslationException;
import org.onosproject.net.pi.service.PiTranslationService;
-import org.onosproject.net.pi.service.PiTranslationStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Optional;
-
/**
- * Implementation of the protocol-independent translation service.
+ * Implementation of the PI translation service.
*/
@Component(immediate = true)
@Service
@@ -54,58 +54,76 @@
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- private PiTranslationStore translationStore;
+ private PiFlowRuleTranslationStore flowRuleTranslationStore;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ private PiGroupTranslationStore groupTranslationStore;
+
+ private PiFlowRuleTranslator flowRuleTranslator;
+ private PiGroupTranslator groupTranslator;
@Activate
public void activate() {
+ flowRuleTranslator = new InternalFlowRuleTranslator(flowRuleTranslationStore);
+ groupTranslator = new InternalGroupTranslator(groupTranslationStore);
log.info("Started");
}
@Deactivate
public void deactivate() {
+ flowRuleTranslator = null;
+ groupTranslator = null;
log.info("Stopped");
}
@Override
- public PiTableEntry translate(FlowRule rule, PiPipeconf pipeconf)
- throws PiTranslationException {
- final PiTableEntry piTableEntry = PiFlowRuleTranslator
- .translate(rule, pipeconf, getDevice(rule.deviceId()));
- translationStore.addOrUpdate(rule, piTableEntry, pipeconf.id());
- return piTableEntry;
+ public PiFlowRuleTranslator flowRuleTranslator() {
+ return flowRuleTranslator;
}
@Override
- public Optional<FlowRule> lookup(PiTableEntry piTableEntry,
- PiPipeconfId pipeconfId) {
- final PiTranslatable original = translationStore
- .lookup(piTableEntry, pipeconfId);
- return original == null
- ? Optional.empty()
- : Optional.of((FlowRule) original);
- }
-
- @Override
- public PiActionGroup translate(Group group, PiPipeconf pipeconf)
- throws PiTranslationException {
- return PiGroupTranslator.translate(group, pipeconf,
- getDevice(group.deviceId()));
- }
-
- @Override
- public Optional<Group> lookup(PiActionGroup piActionGroup,
- PiPipeconfId pipeconfId) {
- // TODO: implement learning and lookup of groups
- return Optional.empty();
+ public PiGroupTranslator groupTranslator() {
+ return groupTranslator;
}
private Device getDevice(DeviceId deviceId) throws PiTranslationException {
final Device device = deviceService.getDevice(deviceId);
if (device == null) {
- throw new PiTranslationException(
- "Unable to get device " + deviceId);
+ throw new PiTranslationException("Unable to get device " + deviceId);
}
return device;
}
+
+ private final class InternalFlowRuleTranslator
+ extends AbstractPiTranslatorImpl<FlowRule, PiTableEntry>
+ implements PiFlowRuleTranslator {
+
+ private InternalFlowRuleTranslator(PiFlowRuleTranslationStore store) {
+ super(store);
+ }
+
+ @Override
+ public PiTableEntry translate(FlowRule original, PiPipeconf pipeconf)
+ throws PiTranslationException {
+ return PiFlowRuleTranslatorImpl
+ .translate(original, pipeconf, getDevice(original.deviceId()));
+ }
+ }
+
+ private final class InternalGroupTranslator
+ extends AbstractPiTranslatorImpl<Group, PiActionGroup>
+ implements PiGroupTranslator {
+
+ private InternalGroupTranslator(PiGroupTranslationStore store) {
+ super(store);
+ }
+
+ @Override
+ public PiActionGroup translate(Group original, PiPipeconf pipeconf)
+ throws PiTranslationException {
+ return PiGroupTranslatorImpl
+ .translate(original, pipeconf, getDevice(original.deviceId()));
+ }
+ }
}
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiUtils.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiUtils.java
index 6e93d67..78bca5f 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiUtils.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiUtils.java
@@ -22,7 +22,7 @@
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiPipelineInterpreter;
import org.onosproject.net.pi.model.PiTableId;
-import org.onosproject.net.pi.service.PiTranslationService;
+import org.onosproject.net.pi.service.PiTranslationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,23 +60,23 @@
}
static PiTableId translateTableId(TableId tableId, PiPipelineInterpreter interpreter)
- throws PiTranslationService.PiTranslationException {
+ throws PiTranslationException {
switch (tableId.type()) {
case PIPELINE_INDEPENDENT:
return (PiTableId) tableId;
case INDEX:
IndexTableId indexId = (IndexTableId) tableId;
if (interpreter == null) {
- throw new PiTranslationService.PiTranslationException(format(
+ throw new PiTranslationException(format(
"Unable to map table ID '%d' from index to PI: missing interpreter", indexId.id()));
} else if (!interpreter.mapFlowRuleTableId(indexId.id()).isPresent()) {
- throw new PiTranslationService.PiTranslationException(format(
+ throw new PiTranslationException(format(
"Unable to map table ID '%d' from index to PI: missing ID in interpreter", indexId.id()));
} else {
return interpreter.mapFlowRuleTableId(indexId.id()).get();
}
default:
- throw new PiTranslationService.PiTranslationException(format(
+ throw new PiTranslationException(format(
"Unrecognized table ID type %s", tableId.type().name()));
}
}