Bug 5540 - ConvertorManager optimization, concurrency
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / PortConvertor.java
index e11eb8dca66c1cd7e7e4a93d37b47a72cf6618af..e644a090fb21eb70b7b94371e061239977825040 100644 (file)
@@ -1,83 +1,76 @@
-/**
+/*
  * Copyright (c) 2014 Ericsson India Global Services Pvt Ltd. 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
- *
- * Contributor: usha.m.s@ericsson.com
  */
+
 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
 
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import com.google.common.annotations.VisibleForTesting;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.ParametrizedConvertor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
+import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.Ports;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.PortsBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
- * @author esssuuu This convertor class is used for Port Mod,port status and
- *         port description messages,decodes SAL and encodes to OF Data
+ * Converts port mod, port status and port description MD-SAL messages to OF library data
  *
+ * Example usage:
+ * <pre>
+ * {@code
+ * VersionConvertorData data = new VersionConvertorData(version);
+ * Optional<PortModInput> ofPort = ConvertorManager.getInstance().convert(salPort, data);
+ * }
+ * </pre>
  */
-public final class PortConvertor {
-    private static final Logger log = LoggerFactory.getLogger(PortConvertor.class);
-
-    private PortConvertor() {
-
-    }
+public class PortConvertor implements ParametrizedConvertor<Port, PortModInput, VersionConvertorData> {
 
     /**
-     * This method is used by PORT_MOD_MESSAGE
+     * Create default empty port mod input
+     * Use this method, if result from convertor is empty.
      *
-     * @param source
-     * @return
+     * @param version Openflow version
+     * @return default empty port mod input
      */
+    public static PortModInput defaultResult(short version) {
+        return new PortModInputBuilder()
+                .setVersion(version)
+                .build();
+    }
 
-    public static PortModInput toPortModInput(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port source,
-            short version) {
-
-
-        PortConfig config = null;
+    private static PortConfig maskPortConfigFields(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig configData) {
+        Boolean portDown = configData.isPORTDOWN();
+        Boolean noRecv = configData.isNORECV();
+        Boolean noFwd = configData.isNOFWD();
+        Boolean noPacketIn = configData.isNOPACKETIN();
 
-        PortModInputBuilder portModInputBuilder = new PortModInputBuilder();
-        portModInputBuilder.setAdvertise(getPortFeatures(source.getAdvertisedFeatures()));
-        portModInputBuilder.setPortNo(new PortNumber(source.getPortNumber()));
-        maskPortConfigFields(source.getConfiguration(), config);
-        portModInputBuilder.setConfig(config);
-        portModInputBuilder.setHwAddress(new MacAddress(source.getHardwareAddress()));
-        config = null;
-        maskPortConfigFields(source.getMask(), config);
-        portModInputBuilder.setMask(config);
-        portModInputBuilder.setVersion(version);
-        return portModInputBuilder.build();
+        return new PortConfig(noFwd, noPacketIn, noRecv, portDown);
 
     }
 
-    private static void maskPortConfigFields(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig configData,
-            PortConfig config) {
-        Boolean portDown = false;
-        Boolean noRecv = false;
-        Boolean noFwd = false;
-        Boolean noPacketIn = false;
-        if (configData.isNOFWD())
-            noFwd = true;
-        if (configData.isNOPACKETIN())
-            noPacketIn = true;
-        if (configData.isNORECV())
-            noRecv = true;
-        if (configData.isPORTDOWN())
-            portDown = true;
-
-        config = new PortConfig(noFwd, noPacketIn, noRecv, portDown);
+    private static PortConfigV10 maskPortConfigV10Fields(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig configData) {
+        Boolean portDown = configData.isPORTDOWN();
+        Boolean noRecv = configData.isNORECV();
+        Boolean noFwd = configData.isNOFWD();
+        Boolean noPacketIn = configData.isNOPACKETIN();
+
+        return new PortConfigV10(false, noFwd, noPacketIn, noRecv, true, true, portDown);
 
     }
 
@@ -92,62 +85,89 @@ public final class PortConvertor {
                 salPortFeatures.isPause(), salPortFeatures.isPauseAsym());
     }
 
-    /*
+    private static PortFeaturesV10 getPortFeaturesV10(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures salPortFeatures) {
+
+        return new PortFeaturesV10(salPortFeatures.isHundredMbFd(), salPortFeatures.isHundredMbHd(), salPortFeatures.isTenGbFd(), salPortFeatures.isTenMbFd(), salPortFeatures.isTenMbHd(),
+                salPortFeatures.isOneGbFd(), salPortFeatures.isOneGbHd(), salPortFeatures.isAutoeng(), salPortFeatures.isCopper(), salPortFeatures.isFiber(),
+                salPortFeatures.isPause(), salPortFeatures.isPauseAsym());
+    }
+
+    /**
      * This method is called as a reply to OFPMP_PORT_DESCRIPTION
      * message(OF1.3.1)
-     */
-    /**
-     * @param source
-     *            :SAL FlowCapablePort
+     *
+     * @param source  FlowCapablePort
+     * @param version openflow version
      * @return OF:Ports
      */
-    public static Ports toPortDesc(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.FlowCapablePort source) {
+    @VisibleForTesting
+    static Ports toPortDesc(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.FlowCapablePort source,
+            short version) {
+
+        PortsBuilder oFPortDescDataBuilder = new PortsBuilder();
 
-        PortConfig config = null;
-        PortState portState = null;
+        oFPortDescDataBuilder.setPortNo(
+                OpenflowPortsUtil.getProtocolPortNumber(OpenflowVersion.get(version), source.getPortNumber())); // portNO
 
-        PortsBuilder OFPortDescDataBuilder = new PortsBuilder();
-        OFPortDescDataBuilder.setPortNo(source.getPortNumber()); // portNO
+        oFPortDescDataBuilder.setHwAddr(source.getHardwareAddress());
+        oFPortDescDataBuilder.setName(source.getName());
 
-        OFPortDescDataBuilder.setHwAddr(source.getHardwareAddress());
-        OFPortDescDataBuilder.setName(source.getName());
+        PortConfig config = maskPortConfigFields(source.getConfiguration());
 
-        maskPortConfigFields(source.getConfiguration(), config);
+        oFPortDescDataBuilder.setConfig(config);
 
-        OFPortDescDataBuilder.setConfig(config);
+        PortState portState = getPortState(source.getState());
 
-        getPortState(source.getState(), portState);
-        OFPortDescDataBuilder.setState(portState);
-        OFPortDescDataBuilder.setCurrentFeatures(getPortFeatures(source.getCurrentFeature()));
-        OFPortDescDataBuilder.setAdvertisedFeatures(getPortFeatures(source.getAdvertisedFeatures()));
-        OFPortDescDataBuilder.setSupportedFeatures(getPortFeatures(source.getSupported()));
-        OFPortDescDataBuilder.setPeerFeatures(getPortFeatures(source.getPeerFeatures()));
-        OFPortDescDataBuilder.setCurrSpeed(source.getCurrentSpeed());
-        OFPortDescDataBuilder.setMaxSpeed(source.getMaximumSpeed());
+        oFPortDescDataBuilder.setState(portState);
+        oFPortDescDataBuilder.setCurrentFeatures(getPortFeatures(source.getCurrentFeature()));
+        oFPortDescDataBuilder.setAdvertisedFeatures(getPortFeatures(source.getAdvertisedFeatures()));
+        oFPortDescDataBuilder.setSupportedFeatures(getPortFeatures(source.getSupported()));
+        oFPortDescDataBuilder.setPeerFeatures(getPortFeatures(source.getPeerFeatures()));
+        oFPortDescDataBuilder.setCurrSpeed(source.getCurrentSpeed());
+        oFPortDescDataBuilder.setMaxSpeed(source.getMaximumSpeed());
 
-        return OFPortDescDataBuilder.build();
+        return oFPortDescDataBuilder.build();
 
     }
 
-    private static void getPortState(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState state, PortState portState) {
+    private static PortState getPortState(
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState state) {
 
-        boolean isLinkDown = false;// (0),
-        boolean isBlocked = false; // (1),
-        boolean isLive = false; // (2);
+        boolean isLinkDown = state.isLinkDown();
+        boolean isBlocked = state.isBlocked();
+        boolean isLive = state.isLive();
 
-        if (state.isLinkDown()) {
-            isLinkDown = true;
-        } else if (state.isBlocked()) {
-            isBlocked = true;
-        } else if (state.isLive()) {
-            isLive = true;
-        }
-        portState = new PortState(isLinkDown, isBlocked, isLive);
+        return new PortState(isLinkDown, isBlocked, isLive);
+
+    }
 
+    @Override
+    public Class<?> getType() {
+        return Port.class;
     }
 
+    @Override
+    public PortModInput convert(Port source, VersionConvertorData data) {
+        PortConfig config = maskPortConfigFields(source.getConfiguration());
+        PortConfigV10 configV10 = maskPortConfigV10Fields(source.getConfiguration());
 
+        PortModInputBuilder portModInputBuilder = new PortModInputBuilder();
+        portModInputBuilder.setAdvertise(getPortFeatures(source.getAdvertisedFeatures()));
+        portModInputBuilder.setPortNo(new PortNumber(
+                OpenflowPortsUtil.getProtocolPortNumber(OpenflowVersion.get(data.getVersion()), source.getPortNumber())));
+
+        portModInputBuilder.setConfig(config);
+        portModInputBuilder.setMask(config);
 
-}
+        portModInputBuilder.setHwAddress(new MacAddress(source.getHardwareAddress()));
+
+        portModInputBuilder.setVersion(data.getVersion());
+
+        portModInputBuilder.setConfigV10(configV10);
+        portModInputBuilder.setMaskV10(configV10);
+        portModInputBuilder.setAdvertiseV10(getPortFeaturesV10(source.getAdvertisedFeatures()));
+        return portModInputBuilder.build();
+    }
+}
\ No newline at end of file