Bug 5540 - PacketOutConvertor 86/40986/19
authorTomas Slusny <tomas.slusny@pantheon.sk>
Wed, 29 Jun 2016 06:54:36 +0000 (08:54 +0200)
committerTomas Slusny <tomas.slusny@pantheon.sk>
Wed, 3 Aug 2016 17:01:22 +0000 (17:01 +0000)
- Reworked PacketOutConvertor to use new ConvertorManager design
- Updated tests and usage of PacketOutConvertor accordingly

Change-Id: I9df612a7d9c3b9604c8119f86d2266723066e68a
Signed-off-by: Tomas Slusny <tomas.slusny@pantheon.sk>
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/PacketProcessingServiceImpl.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/ModelDrivenSwitchImpl.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/ConvertorManager.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/PacketOutConvertor.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/data/PacketOutConvertorData.java [new file with mode: 0644]
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/PacketOutConvertorTest.java

index 85e198ef24c6fd8c53ce1ec88e882451927be904..348495c44a39792262a32696a78c3a7d17c40764 100644 (file)
@@ -7,12 +7,16 @@
  */
 package org.opendaylight.openflowplugin.impl.services;
 
+import java.util.Optional;
 import java.util.concurrent.Future;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
 import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.PacketOutConvertorData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -30,6 +34,11 @@ public final class PacketProcessingServiceImpl extends AbstractVoidService<Trans
 
     @Override
     protected OfHeader buildRequest(final Xid xid, final TransmitPacketInput input) {
-        return PacketOutConvertor.toPacketOutInput(input, getVersion(), xid.getValue(), getDatapathId());
+        final PacketOutConvertorData data = new PacketOutConvertorData(getVersion());
+        data.setDatapathId(getDatapathId());
+        data.setXid(xid.getValue());
+
+        final Optional<PacketOutInput> result = ConvertorManager.getInstance().convert(input, data);
+        return result.orElse(PacketOutConvertor.defaultResult(getVersion()));
     }
 }
index aee9dffc1e2f408bac254a6b4d5a47562c48501b..40c845c7e0dc0fd16af70c21a9c090ca371da7d8 100644 (file)
@@ -8,21 +8,21 @@
 package org.opendaylight.openflowplugin.openflow.md.core.sal;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
-
 import java.math.BigInteger;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor;
 import org.opendaylight.openflowplugin.api.openflow.md.core.session.IMessageDispatchService;
-import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.PacketOutConvertorData;
+import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
@@ -219,8 +219,11 @@ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
     public Future<RpcResult<Void>> transmitPacket(final TransmitPacketInput input) {
         LOG.debug("TransmitPacket - {}", input);
         // Convert TransmitPacket to PacketOutInput
-        PacketOutInput message = PacketOutConvertor.toPacketOutInput(input, version, sessionContext.getNextXid(),
-                sessionContext.getFeatures().getDatapathId());
+        final PacketOutConvertorData data = new PacketOutConvertorData(version);
+        data.setDatapathId(sessionContext.getFeatures().getDatapathId());
+        data.setXid(sessionContext.getNextXid());
+
+        final java.util.Optional<PacketOutInput> message = ConvertorManager.getInstance().convert(input, data);
 
         SwitchConnectionDistinguisher cookie = null;
         ConnectionCookie connectionCookie = input.getConnectionCookie();
@@ -229,7 +232,8 @@ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch {
         }
 
         LOG.debug("Calling the transmitPacket RPC method");
-        return messageService.packetOut(message, cookie);
+        return messageService.packetOut(message
+                .orElse(PacketOutConvertor.defaultResult(version)), cookie);
     }
 
     @Override
index 3d26f331f19b329c8564fae0bf334ad07d245727..d8cf176b201922a1fd9cbd474798b9dc3488dbb5 100644 (file)
@@ -50,6 +50,7 @@ public class ConvertorManager {
         INSTANCE.registerConvertor(new GroupConvertor());
         INSTANCE.registerConvertor(new GroupDescStatsResponseConvertor());
         INSTANCE.registerConvertor(new GroupStatsResponseConvertor());
+        INSTANCE.registerConvertor(new PacketOutConvertor());
     }
 
     // Actual convertor keys
index 50f834a46d523e514a74aa1f84b9fadfab32f9f2..3db52261d80b3ad97fc3f147d4376afe17ef5ec6 100644 (file)
@@ -1,14 +1,14 @@
-/**
+/*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
+
 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
 
 import com.google.common.collect.Iterables;
-import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -17,6 +17,8 @@ import org.opendaylight.controller.sal.common.util.Arguments;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.data.ActionConvertorData;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.ParametrizedConvertor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.PacketOutConvertorData;
 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
@@ -33,62 +35,93 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public final class PacketOutConvertor {
+/**
+ * Converts a MD-SAL packet out data into the OF library packet out input.
+ *
+ * Example usage:
+ * <pre>
+ * {@code
+ * PacketOutConvertorData data = new PacketOutConvertorData(version);
+ * data.setDatapathId(datapathId);
+ * data.setXid(xid);
+ * Optional<PacketOutInput> ofPacketInput = ConvertorManager.getInstance().convert(salPacket, data);
+ * }
+ * </pre>
+ */
+public class PacketOutConvertor implements ParametrizedConvertor<TransmitPacketInput, PacketOutInput, PacketOutConvertorData> {
     private static final Logger LOG = LoggerFactory.getLogger(PacketOutConvertor.class);
 
-    private PacketOutConvertor() {
-
+    /**
+     * Create default empty meter mot input builder.
+     * Use this method, if result from convertor is empty.
+     *
+     * @param version Openflow version
+     * @return default empty meter mod input builder
+     */
+    public static PacketOutInput defaultResult(short version) {
+        return new PacketOutInputBuilder()
+                .setVersion(version)
+                .build();
     }
 
-    // Get all the data for the PacketOut from the Yang/SAL-Layer
+    private static PortNumber getPortNumber(final PathArgument pathArgument, final Short ofVersion) {
+        // FIXME VD P! find InstanceIdentifier helper
+        InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
+                InstanceIdentifier.IdentifiableItem.class);
+        NodeConnectorKey key = Arguments.checkInstanceOf(item.getKey(), NodeConnectorKey.class);
+        Long port = InventoryDataServiceUtil.portNumberfromNodeConnectorId(
+                OpenflowVersion.get(ofVersion), key.getId());
+        return new PortNumber(port);
+    }
 
-    /**
-     * @param version openflow version
-     * @param inputPacket input packet
-     * @param datapathid  datapath id
-     * @param xid tx id
-     * @return PacketOutInput required by OF Library
-     */
-    public static PacketOutInput toPacketOutInput(final TransmitPacketInput inputPacket, final short version, final Long xid,
-                                                  final BigInteger datapathid) {
+    @Override
+    public Class<?> getType() {
+        return TransmitPacketInput.class;
+    }
 
-        LOG.trace("toPacketOutInput for datapathId:{}, xid:{}", datapathid, xid);
+    @Override
+    public PacketOutInput convert(TransmitPacketInput source, PacketOutConvertorData data) {
+        LOG.trace("toPacketOutInput for datapathId:{}, xid:{}", data.getDatapathId(), data.getXid());
         // Build Port ID from TransmitPacketInput.Ingress
-        PortNumber inPortNr = null;
+        PortNumber inPortNr;
         Long bufferId = OFConstants.OFP_NO_BUFFER;
         Iterable<PathArgument> inArgs = null;
         PacketOutInputBuilder builder = new PacketOutInputBuilder();
-        if (inputPacket.getIngress() != null) {
-            inArgs = inputPacket.getIngress().getValue().getPathArguments();
+
+        if (source.getIngress() != null) {
+            inArgs = source.getIngress().getValue().getPathArguments();
         }
+
         if (inArgs != null && Iterables.size(inArgs) >= 3) {
-            inPortNr = getPortNumber(Iterables.get(inArgs, 2), version);
+            inPortNr = getPortNumber(Iterables.get(inArgs, 2), data.getVersion());
         } else {
             // The packetOut originated from the controller
             inPortNr = new PortNumber(0xfffffffdL);
         }
 
         // Build Buffer ID to be NO_OFP_NO_BUFFER
-        if (inputPacket.getBufferId() != null) {
-            bufferId = inputPacket.getBufferId();
+        if (source.getBufferId() != null) {
+            bufferId = source.getBufferId();
         }
 
         PortNumber outPort = null;
-        NodeConnectorRef outRef = inputPacket.getEgress();
+        NodeConnectorRef outRef = source.getEgress();
         Iterable<PathArgument> outArgs = outRef.getValue().getPathArguments();
+
         if (Iterables.size(outArgs) >= 3) {
-            outPort = getPortNumber(Iterables.get(outArgs, 2), version);
+            outPort = getPortNumber(Iterables.get(outArgs, 2), data.getVersion());
         } else {
             // TODO : P4 search for some normal exception
-            new Exception("PORT NR not exist in Egress");
+            // new Exception("PORT NR not exist in Egress");
+            LOG.error("PORT NR not exist in Egress");
         }
 
-        List<Action> actions = null;
-        List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> inputActions =
-                inputPacket.getAction();
+        List<Action> actions = new ArrayList<>();
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> inputActions = source.getAction();
+
         if (inputActions != null) {
-            final ActionConvertorData actionConvertorData = new ActionConvertorData(version);
-            actionConvertorData.setDatapathId(datapathid);
+            final ActionConvertorData actionConvertorData = new ActionConvertorData(data.getVersion());
+            actionConvertorData.setDatapathId(data.getDatapathId());
 
             final Optional<List<Action>> convertedActions = ConvertorManager.getInstance().convert(
                     inputActions, actionConvertorData);
@@ -96,44 +129,24 @@ public final class PacketOutConvertor {
             actions = convertedActions.orElse(Collections.emptyList());
 
         } else {
-            actions = new ArrayList<>();
             // TODO VD P! wait for way to move Actions (e.g. augmentation)
             ActionBuilder aBuild = new ActionBuilder();
-
-            OutputActionCaseBuilder outputActionCaseBuilder =
-                    new OutputActionCaseBuilder();
-
-            OutputActionBuilder outputActionBuilder =
-                    new OutputActionBuilder();
-
+            OutputActionCaseBuilder outputActionCaseBuilder = new OutputActionCaseBuilder();
+            OutputActionBuilder outputActionBuilder = new OutputActionBuilder();
             outputActionBuilder.setPort(outPort);
             outputActionBuilder.setMaxLength(OFConstants.OFPCML_NO_BUFFER);
-
             outputActionCaseBuilder.setOutputAction(outputActionBuilder.build());
-
             aBuild.setActionChoice(outputActionCaseBuilder.build());
-
             actions.add(aBuild.build());
         }
 
         builder.setAction(actions);
-        builder.setData(inputPacket.getPayload());
-        builder.setVersion(version);
-        builder.setXid(xid);
+        builder.setData(source.getPayload());
+        builder.setVersion(data.getVersion());
+        builder.setXid(data.getXid());
         builder.setInPort(inPortNr);
         builder.setBufferId(bufferId);
-        // --------------------------------------------------------
 
         return builder.build();
     }
-
-    private static PortNumber getPortNumber(final PathArgument pathArgument, final Short ofVersion) {
-        // FIXME VD P! find InstanceIdentifier helper
-        InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
-                InstanceIdentifier.IdentifiableItem.class);
-        NodeConnectorKey key = Arguments.checkInstanceOf(item.getKey(), NodeConnectorKey.class);
-        Long port =  InventoryDataServiceUtil.portNumberfromNodeConnectorId(
-                OpenflowVersion.get(ofVersion), key.getId());
-        return new PortNumber(port);
-    }
-}
+}
\ No newline at end of file
diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/data/PacketOutConvertorData.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/data/PacketOutConvertorData.java
new file mode 100644 (file)
index 0000000..1ae204a
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data;
+
+/**
+ * Convertor data used in {@link org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor}
+ * containing Openflow version and XID
+ */
+public class PacketOutConvertorData extends VersionDatapathIdConvertorData {
+    private Long xid;
+
+    /**
+     * Instantiates a new Packet out convertor data.
+     *
+     * @param version the version
+     */
+    public PacketOutConvertorData(short version) {
+        super(version);
+    }
+
+    /**
+     * Gets xid.
+     *
+     * @return the xid
+     */
+    public Long getXid() {
+        return xid;
+    }
+
+    /**
+     * Sets xid.
+     *
+     * @param xid the xid
+     */
+    public void setXid(Long xid) {
+        this.xid = xid;
+    }
+}
\ No newline at end of file
index c5ef62043e25cad4625febab95428e0de91f79c3..cce8c34e94fc046b575d20986d58bdd77347ecbc 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
 import org.opendaylight.openflowplugin.api.OFConstants;\r
 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;\r
 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.data.ActionConvertorData;\r
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.PacketOutConvertorData;\r
 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;\r
 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;\r
@@ -86,13 +87,12 @@ public class PacketOutConvertorTest {
 \r
         Short version = (short) 0x04;\r
         Long xid = null;\r
-        PacketOutInput message = PacketOutConvertor.toPacketOutInput(\r
-                transmitPacketInput, version, null, null);\r
+        PacketOutConvertorData data = new PacketOutConvertorData(version);\r
+        PacketOutInput message = convert(transmitPacketInput, data);\r
 \r
         //FIXME : this has to be fixed along with actions changed in openflowjava\r
 \r
-        Assert.assertEquals(PacketOutConvertorTest.buildActionForNullTransmitPacketInputAction(nodeConnKey,\r
-                version), message.getAction());\r
+        Assert.assertEquals(buildActionForNullTransmitPacketInputAction(nodeConnKey, version), message.getAction());\r
 \r
         Assert.assertEquals(OFConstants.OFP_NO_BUFFER, message.getBufferId());\r
         Assert.assertEquals(new PortNumber(0xfffffffdL), message.getInPort());\r
@@ -166,8 +166,10 @@ public class PacketOutConvertorTest {
 \r
         OpenflowPortsUtil.init();\r
 \r
-        PacketOutInput message = PacketOutConvertor.toPacketOutInput(\r
-                transmitPacketInput, version, xid, datapathId);\r
+        PacketOutConvertorData data = new PacketOutConvertorData(version);\r
+        data.setXid(xid);\r
+        data.setDatapathId(datapathId);\r
+        PacketOutInput message = convert(transmitPacketInput, data);\r
 \r
         Assert.assertEquals(transmitPacketInput.getBufferId(),\r
                 message.getBufferId());\r
@@ -176,6 +178,7 @@ public class PacketOutConvertorTest {
         Assert.assertEquals((Object) version,\r
                 Short.valueOf(message.getVersion()));\r
         Assert.assertEquals(xid, message.getXid());\r
+\r
         ActionConvertorData actionConvertorData = new ActionConvertorData(version);\r
         actionConvertorData.setDatapathId(datapathId);\r
 \r
@@ -277,4 +280,9 @@ public class PacketOutConvertorTest {
                 .<Node, NodeKey>child(Node.class, key).build();\r
         return new NodeRef(path);\r
     }\r
+\r
+    private PacketOutInput convert(TransmitPacketInput transmitPacketInput, PacketOutConvertorData data) {\r
+        Optional<PacketOutInput> messageOptional = ConvertorManager.getInstance().convert(transmitPacketInput, data);\r
+        return messageOptional.orElse(PacketOutConvertor.defaultResult(data.getVersion()));\r
+    }\r
 }\r