/*
- * 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;
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.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
+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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
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.group.statistics.rev131111.GetGroupStatisticsInput;
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsInputBuilder;
+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;
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 {
public static final String NODE_PREFIX = "openflow";
- public static final String SEPARATOR = ":"; // TODO name separtor correctly
-
+ public static final String SEPARATOR = ":";
private static final Buckets EMPTY_Buckets = new BucketsBuilder().build();
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 Map<Long, SyncStatus> syncStatusMap = new
- // ConcurrentHashMap<Long, SyncStatus>();
- public static Map<Long, LinkedBlockingQueue<Object>> lportMap = new ConcurrentHashMap<Long, LinkedBlockingQueue<Object>>();
- public static Map<Long, LinkedBlockingQueue<Object>> lportDownMap = new ConcurrentHashMap<Long, LinkedBlockingQueue<Object>>();
- // public static Map<String, Boolean> ofRefMap = new
- // ConcurrentHashMap<String, Boolean>();
- public static Map<Long, Map<String, Boolean>> ofRefMapDpn = new ConcurrentHashMap<Long, Map<String, Boolean>>();
- public static Map<Long, Map<Integer, String>> ofRefGroupMapDpn = new ConcurrentHashMap<Long, Map<Integer, String>>();
- public static Map<Long, Map<String, String>> ofRefFlowMapDpn = new ConcurrentHashMap<Long, Map<String, String>>();
-
- 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) {
return flowEntity;
}
- // TODO FIX ME
- /*
- public static Flow buildResyncFlow(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
- int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
- List<InstructionInfo> listInstructionInfo, boolean isStrict, boolean isResync) {
- FlowKey key = new FlowKey(new FlowId(flowId));
- return new FlowBuilder().setMatch(buildMatches(listMatchInfo)).setKey(key)
- .setPriority(Integer.valueOf(priority)).setInstructions(buildInstructions(listInstructionInfo))
- .setBarrier(false).setInstallHw(true).setHardTimeout(hardTimeOut).setIdleTimeout(idleTimeOut)
- .setFlowName(flowName).setTableId(Short.valueOf(tableId)).setStrict(isStrict)
- .setCookie(new FlowCookie(cookie)).setResyncFlag(isResync).build();
- }
- */
// TODO: CHECK IF THIS IS USED
public static Flow buildFlow(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo, List<InstructionInfo> listInstructionInfo) {
.setCookie(new FlowCookie(cookie)).build();
}
- // TODO FIX ME
- /*
- public static Flow buildResyncFlow(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
- int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
- List<InstructionInfo> listInstructionInfo, boolean isStrict, boolean isResync, boolean isSendFlowRem) {
+ 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(buildInstructions(listInstructionInfo))
+ .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))
- .setFlags(new FlowModFlags(false, false, false, false, isSendFlowRem)).setResyncFlag(isResync).build();
-
- }
- */
-/*
- public static Flow buildFlow(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
- int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
- List<InstructionInfo> listInstructionInfo, boolean isStrict, boolean isSendFlowRem) {
- return buildResyncFlow(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie, listMatchInfo,
- listInstructionInfo, isStrict, false, isSendFlowRem);
-
+ .setCookie(new FlowCookie(cookie)).build();
}
-*/
-
- public static GroupEntity buildGroupEntity(long dpnId, long groupId, String groupName, GroupTypes groupType,
+ public static GroupEntity buildGroupEntity(BigInteger dpnId, long groupId, String groupName, GroupTypes groupType,
List<BucketInfo> listBucketInfo) {
GroupEntity groupEntity = new GroupEntity(dpnId);
return groupEntity;
}
- // FIXME -- AS ReSync is not required for ODL VPN Service
- /*
- public static Group buildGroup(long groupId, String groupName, GroupTypes groupType, List<BucketInfo> listBucketInfo) {
- return buildGroup(groupId, groupName, groupType, listBucketInfo, false);
- }
-
- public static Group buildGroup(long groupId, String groupName, GroupTypes groupType,
- List<BucketInfo> listBucketInfo, boolean isResync) {
- return new GroupBuilder().setBuckets(buildBuckets(listBucketInfo)).setKey(new GroupKey(new GroupId(groupId)))
- .setBarrier(false).setGroupId(new GroupId(Long.valueOf(groupId))).setGroupType(groupType)
- .setGroupName(groupName).setResyncFlag(isResync).build();
- }
-*/
- // Removing --Missing Constraint
- /*
- public static GetFlowStatisticsFromFlowTableInput buildGetFlowStatisticsFromFlowTableInput(short tableId,
- List<MatchInfo> listMatchInfo, long dpnId) {
- return new GetFlowStatisticsFromFlowTableInputBuilder()
- .setTableId(Short.valueOf(tableId))
- .setMatch(buildMatches(listMatchInfo))
- .setNode(
- new NodeRef(InstanceIdentifier.builder(Nodes.class)
- .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance())).build();
-
- }
-
- public static GetGroupStatisticsInput buildGetGroupStatistics(long groupId, long dpnId) {
- return new GetGroupStatisticsInputBuilder()
- .setGroupId(new GroupId(Long.valueOf(groupId)))
- .setNode(
- new NodeRef(InstanceIdentifier.builder(Nodes.class)
- .child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance())).build();
- }
- */
-
- 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)
}
// 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);
}
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.CONFIGURATION, ref.getValue());
+ return nc.get().getId();
+ }
+
}