ELAN FT Support for BE
[vpnservice.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / vpnservice / mdsalutil / MDSALUtil.java
index fea7e624f69b7a55f19556fc85371f114b0a9737..27afd5c35c72ff6987db65c35aa625dd207fa231 100644 (file)
@@ -1,10 +1,9 @@
 /*
- * Copyright (c) 2013 Ericsson AB.  All rights reserved.
+ * Copyright (c) 2015 - 2016 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
- *
  */
 
 package org.opendaylight.vpnservice.mdsalutil;
@@ -15,8 +14,17 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.LinkedBlockingQueue;
 
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
@@ -28,7 +36,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.I
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
@@ -50,12 +68,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
-
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.controller.liblldp.HexEncode;
 import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
 import com.google.common.primitives.Bytes;
 import com.google.common.primitives.Ints;
+import com.google.common.util.concurrent.CheckedFuture;
 
 public class MDSALUtil {
 
@@ -65,8 +95,9 @@ public class MDSALUtil {
     private static final Instructions EMPTY_Instructions = new InstructionsBuilder().setInstruction(
             new ArrayList<Instruction>()).build();
     private static final Match EMPTY_Matches = new MatchBuilder().build();
+    private static final Logger logger = LoggerFactory.getLogger(MDSALUtil.class);
 
-    public static FlowEntity buildFlowEntity(long dpnId, short tableId, String flowId, int priority, String flowName,
+    public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId, int priority, String flowName,
             int idleTimeOut, int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
             List<InstructionInfo> listInstructionInfo) {
 
@@ -103,7 +134,24 @@ public class MDSALUtil {
                 .setCookie(new FlowCookie(cookie)).build();
     }
 
-    public static GroupEntity buildGroupEntity(long dpnId, long groupId, String groupName, GroupTypes groupType,
+    public static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
+                                 int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo, List<Instruction> listInstructionInfo) {
+        return MDSALUtil.buildFlowNew(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie,
+                listMatchInfo, listInstructionInfo, true);
+    }
+
+    private static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
+                                  int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
+                                  List<Instruction> listInstructionInfo, boolean isStrict) {
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        return new FlowBuilder().setMatch(buildMatches(listMatchInfo)).setKey(key)
+                .setPriority(Integer.valueOf(priority)).setInstructions(new InstructionsBuilder().setInstruction(listInstructionInfo).build())
+                .setBarrier(false).setInstallHw(true).setHardTimeout(hardTimeOut).setIdleTimeout(idleTimeOut)
+                .setFlowName(flowName).setTableId(Short.valueOf(tableId)).setStrict(isStrict)
+                .setCookie(new FlowCookie(cookie)).build();
+    }
+
+    public static GroupEntity buildGroupEntity(BigInteger dpnId, long groupId, String groupName, GroupTypes groupType,
             List<BucketInfo> listBucketInfo) {
 
         GroupEntity groupEntity = new GroupEntity(dpnId);
@@ -116,7 +164,7 @@ public class MDSALUtil {
         return groupEntity;
     }
 
-    public static TransmitPacketInput getPacketOutDefault(List<ActionInfo> actionInfos, byte[] payload, long dpnId) {
+    public static TransmitPacketInput getPacketOutDefault(List<ActionInfo> actionInfos, byte[] payload, BigInteger dpnId) {
         return new TransmitPacketInputBuilder()
                 .setAction(buildActions(actionInfos))
                 .setPayload(payload)
@@ -198,7 +246,7 @@ public class MDSALUtil {
         return EMPTY_Instructions;
     }
 
-    protected static Match buildMatches(List<MatchInfo> listMatchInfo) {
+    public static Match buildMatches(List<MatchInfo> listMatchInfo) {
         if (listMatchInfo != null) {
             MatchBuilder matchBuilder = new MatchBuilder();
             Map<Class<?>, Object> mapMatchBuilder = new HashMap<Class<?>, Object>();
@@ -218,11 +266,11 @@ public class MDSALUtil {
     }
 
     // TODO: Check the port const
-    public static NodeConnectorRef getDefaultNodeConnRef(long nDpId) {
+    public static NodeConnectorRef getDefaultNodeConnRef(BigInteger nDpId) {
         return getNodeConnRef(NODE_PREFIX + SEPARATOR + nDpId, "0xfffffffd");
     }
 
-    public static NodeConnectorRef getNodeConnRef(long nDpId, String port) {
+    public static NodeConnectorRef getNodeConnRef(BigInteger nDpId, String port) {
         return getNodeConnRef(NODE_PREFIX + SEPARATOR + nDpId, port);
     }
 
@@ -261,21 +309,185 @@ public class MDSALUtil {
         return nodeConnectorRef;
     }
 
-    public static long getDpnIdFromNodeName(NodeId nodeId) {
+    public static BigInteger getDpnIdFromNodeName(NodeId nodeId) {
         return getDpnIdFromNodeName(nodeId.getValue());
     }
 
-    public static long getDpnIdFromNodeName(String sMdsalNodeName) {
+    public static BigInteger getDpnIdFromNodeName(String sMdsalNodeName) {
         String sDpId = sMdsalNodeName.substring(sMdsalNodeName.lastIndexOf(":") + 1);
-        return Long.parseLong(sDpId);
+        return new BigInteger(sDpId);
     }
 
     public static long getOfPortNumberFromPortName(NodeConnectorId nodeConnectorId) {
         return getOfPortNumberFromPortName(nodeConnectorId.getValue());
     }
 
+    public static long getDpnIdFromPortName(NodeConnectorId nodeConnectorId) {
+        String ofPortName = nodeConnectorId.getValue();
+        return Long.parseLong(ofPortName.substring(ofPortName.indexOf(":")+1, 
+                ofPortName.lastIndexOf(":")));
+    }
+
     public static long getOfPortNumberFromPortName(String sMdsalPortName) {
         String sPortNumber = sMdsalPortName.substring(sMdsalPortName.lastIndexOf(":") + 1);
         return Long.parseLong(sPortNumber);
     }
+
+    public static TransmitPacketInput getPacketOut(List<ActionInfo> actionInfos, byte[] payload, BigInteger dpnId,
+                    NodeConnectorRef nodeConnRef) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public static Instruction buildAndGetPopVlanActionInstruction(int actionKey, int instructionKey) {
+        Action popVlanAction = new ActionBuilder().setAction(
+                new PopVlanActionCaseBuilder().setPopVlanAction(new PopVlanActionBuilder().build()).build())
+                .setKey(new ActionKey(actionKey)).build();
+        List<Action> listAction = new ArrayList<Action> ();
+        listAction.add(popVlanAction);
+        ApplyActions applyActions = new ApplyActionsBuilder().setAction(listAction).build();
+        ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();
+        InstructionBuilder instructionBuilder = new InstructionBuilder();
+
+        instructionBuilder.setInstruction(applyActionsCase);
+        instructionBuilder.setKey(new InstructionKey(instructionKey));
+        return instructionBuilder.build();
+    }
+
+    public static Instruction buildAndGetWriteMetadaInstruction(BigInteger metadata,
+                                                                BigInteger mask, int instructionKey) {
+        return new InstructionBuilder()
+                .setInstruction(
+                        new WriteMetadataCaseBuilder().setWriteMetadata(
+                                new WriteMetadataBuilder().setMetadata(metadata).setMetadataMask(mask).build())
+                                .build()).setKey(new InstructionKey(instructionKey)).build();
+    }
+
+    public static Instruction buildAndGetGotoTableInstruction(short tableId, int instructionKey) {
+        return new InstructionBuilder()
+            .setInstruction(
+                new GoToTableCaseBuilder().setGoToTable(
+                    new GoToTableBuilder().setTableId(tableId).build()).build())
+            .setKey(new InstructionKey(instructionKey)).build();
+    }
+
+    public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+                                                          InstanceIdentifier<T> path, DataBroker broker) {
+
+        ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+        Optional<T> result = Optional.absent();
+        try {
+            result = tx.read(datastoreType, path).get();
+        } catch (Exception e) {
+            logger.error("An error occured while reading data from the path {} with the exception {}", path, e);
+        }
+        return result;
+    }
+
+    public static <T extends DataObject> Optional<T> read(DataBroker broker,
+                                                          LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
+
+        ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+        Optional<T> result = Optional.absent();
+        try {
+            result = tx.read(datastoreType, path).get();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return result;
+    }
+
+    public static <T extends DataObject> void syncWrite(DataBroker broker,
+                                                        LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
+                                                        T data) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.put(datastoreType, path, data, true);
+        CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
+        try {
+            futures.get();
+        } catch (InterruptedException | ExecutionException e) {
+            logger.error("Error writing to datastore (path, data) : ({}, {})", path, data);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    public static <T extends DataObject> void syncUpdate(DataBroker broker,
+                                                         LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
+                                                         T data) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.merge(datastoreType, path, data, true);
+        CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
+        try {
+            futures.get();
+        } catch (InterruptedException | ExecutionException e) {
+            logger.error("Error writing to datastore (path, data) : ({}, {})", path, data);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    public static <T extends DataObject> void syncDelete(DataBroker broker,
+                                                         LogicalDatastoreType datastoreType, InstanceIdentifier<T> obj) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.delete(datastoreType, obj);
+        CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
+        try {
+            futures.get();
+        } catch (InterruptedException | ExecutionException e) {
+            logger.error("Error deleting from datastore (path) : ({})", obj);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    public static byte[] getMacAddressForNodeConnector(DataBroker broker,
+            InstanceIdentifier<NodeConnector> nodeConnectorId)  {
+        Optional<NodeConnector> optNc = MDSALDataStoreUtils.read(broker,
+                LogicalDatastoreType.OPERATIONAL, nodeConnectorId);
+        if(optNc.isPresent()) {
+            NodeConnector nc = optNc.get();
+            FlowCapableNodeConnector fcnc = nc.getAugmentation(FlowCapableNodeConnector.class);
+            MacAddress macAddress = fcnc.getHardwareAddress();
+            return HexEncode.bytesFromHexString(macAddress.getValue());
+        }
+        return null;
+    }
+
+    public static NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
+        return new NodeId(ncId.getValue().substring(0,
+                ncId.getValue().lastIndexOf(":")));
+    }
+
+    public static String getInterfaceName(NodeConnectorRef ref, DataBroker dataBroker) {
+        NodeConnectorId nodeConnectorId = getNodeConnectorId(dataBroker, ref);
+        NodeId nodeId = getNodeIdFromNodeConnectorId(nodeConnectorId);
+        InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier
+                .builder(Nodes.class)
+                .child(Node.class, new NodeKey(nodeId))
+                .child(NodeConnector.class,
+                        new NodeConnectorKey(nodeConnectorId)).build();
+
+        Optional<NodeConnector> nodeConnectorOptional = read(
+                dataBroker,
+                LogicalDatastoreType.OPERATIONAL, ncIdentifier);
+        if (!nodeConnectorOptional.isPresent()) {
+            return null;
+        }
+        NodeConnector nc = nodeConnectorOptional.get();
+        FlowCapableNodeConnector fc = nc
+                .getAugmentation(FlowCapableNodeConnector.class);
+        return fc.getName();
+    }
+
+    public static NodeConnectorId getNodeConnectorId(DataBroker dataBroker,
+            NodeConnectorRef ref) {
+        Optional<NodeConnector> nc = (Optional<NodeConnector>) read(
+                dataBroker,
+                LogicalDatastoreType.OPERATIONAL, ref.getValue());
+        if(nc.isPresent()){
+            return nc.get().getId();
+        }
+        return null;
+    }
+
 }