[ONOS-4258] Initial implementation of supporting extension in REST
- Support Nicira extension
Change-Id: I62bf4417e43459727ce7d4b1ac929c6cf0b7826f
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/DecodeInstructionCodecHelper.java b/core/common/src/main/java/org/onosproject/codec/impl/DecodeInstructionCodecHelper.java
index 03dd496..b70a684 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/DecodeInstructionCodecHelper.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/DecodeInstructionCodecHelper.java
@@ -15,20 +15,28 @@
*/
package org.onosproject.codec.impl;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onlab.util.HexString;
+import org.onosproject.codec.ExtensionTreatmentCodec;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.core.GroupId;
import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.GridType;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalId;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
@@ -37,13 +45,16 @@
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction;
import org.onosproject.net.meter.MeterId;
+import org.slf4j.Logger;
import static org.onlab.util.Tools.nullIsIllegal;
+import static org.slf4j.LoggerFactory.getLogger;
/**
* Decoding portion of the instruction codec.
*/
public final class DecodeInstructionCodecHelper {
+ protected static final Logger log = getLogger(DecodeInstructionCodecHelper.class);
private final ObjectNode json;
/**
@@ -227,6 +238,45 @@
}
/**
+ * Decodes a extension instruction.
+ *
+ * @return extension treatment
+ */
+ private Instruction decodeExtension() {
+ ObjectNode node = (ObjectNode) json.get(InstructionCodec.EXTENSION);
+ if (node != null) {
+ DeviceId deviceId = getDeviceId();
+
+ ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+ DeviceService deviceService = serviceDirectory.get(DeviceService.class);
+ Device device = deviceService.getDevice(deviceId);
+
+ if (device.is(ExtensionTreatmentCodec.class)) {
+ ExtensionTreatmentCodec treatmentCodec = device.as(ExtensionTreatmentCodec.class);
+ ExtensionTreatment treatment = treatmentCodec.decode(node, null);
+ return Instructions.extension(treatment, deviceId);
+ } else {
+ log.warn("There is no codec to decode extension for device {}", deviceId.toString());
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns device identifier.
+ *
+ * @return device identifier
+ * @throws IllegalArgumentException if the JSON is invalid
+ */
+ private DeviceId getDeviceId() {
+ JsonNode deviceIdNode = json.get(InstructionCodec.DEVICE_ID);
+ if (deviceIdNode != null) {
+ return DeviceId.deviceId(deviceIdNode.asText());
+ }
+ throw new IllegalArgumentException("Empty device identifier");
+ }
+
+ /**
* Extracts port number of the given json node.
*
* @param jsonNode json node
@@ -290,6 +340,8 @@
return decodeL3();
} else if (type.equals(Instruction.Type.L4MODIFICATION.name())) {
return decodeL4();
+ } else if (type.equals(Instruction.Type.EXTENSION.name())) {
+ return decodeExtension();
}
throw new IllegalArgumentException("Instruction type "
+ type + " is not supported");
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java b/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java
index b108f7e..3d1ed2f 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java
@@ -16,10 +16,16 @@
package org.onosproject.codec.impl;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
import org.onlab.util.HexString;
import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.ExtensionTreatmentCodec;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalId;
+import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
@@ -28,13 +34,14 @@
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import static org.slf4j.LoggerFactory.getLogger;
/**
* JSON encoding of Instructions.
*/
public final class EncodeInstructionCodecHelper {
- protected static final Logger log = LoggerFactory.getLogger(EncodeInstructionCodecHelper.class);
+ protected static final Logger log = getLogger(EncodeInstructionCodecHelper.class);
private final Instruction instruction;
private final CodecContext context;
@@ -219,14 +226,29 @@
}
}
+
/**
- * Encode a extension instruction.
+ * Encodes a extension instruction.
*
* @param result json node that the instruction attributes are added to
*/
private void encodeExtension(ObjectNode result) {
- // TODO Support extension in REST API
- log.info("Cannot convert instruction type of EXTENSION");
+ final Instructions.ExtensionInstructionWrapper extensionInstruction =
+ (Instructions.ExtensionInstructionWrapper) instruction;
+
+ DeviceId deviceId = extensionInstruction.deviceId();
+
+ ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+ DeviceService deviceService = serviceDirectory.get(DeviceService.class);
+ Device device = deviceService.getDevice(deviceId);
+
+ if (device.is(ExtensionTreatmentCodec.class)) {
+ ExtensionTreatmentCodec treatmentCodec = device.as(ExtensionTreatmentCodec.class);
+ ObjectNode node = treatmentCodec.encode(extensionInstruction.extensionInstruction(), context);
+ result.set(InstructionCodec.EXTENSION, node);
+ } else {
+ log.warn("There is no codec to encode extension for device {}", deviceId.toString());
+ }
}
/**
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/InstructionCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
index 3616e54..da41e25 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/InstructionCodec.java
@@ -57,6 +57,8 @@
protected static final String TRIBUTARY_PORT_NUMBER = "tributaryPortNumber";
protected static final String TRIBUTARY_SLOT_LEN = "tributarySlotLength";
protected static final String TRIBUTARY_SLOT_BITMAP = "tributarySlotBitmap";
+ protected static final String EXTENSION = "extension";
+ protected static final String DEVICE_ID = "deviceId";
protected static final String MISSING_MEMBER_MESSAGE =
" member is required in Instruction";