X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=interfacemanager%2Finterfacemanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fgenius%2Finterfacemanager%2FIfmUtil.java;h=92d2ce123d11db13f36b183b6416799d08c7c7d6;hb=35a126394b12b72f918b5f272e1d067a1745f5e6;hp=fca4f0fdb187ee6041acdb6e4c234422d4464eec;hpb=57d6ab32a22f0d4a6f82caaf38734f35e8f36aba;p=genius.git diff --git a/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/IfmUtil.java b/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/IfmUtil.java index fca4f0fdb..92d2ce123 100755 --- a/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/IfmUtil.java +++ b/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/IfmUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * Copyright (c) 2016, 2017 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, @@ -7,7 +7,11 @@ */ package org.opendaylight.genius.interfacemanager; +import static java.util.Collections.emptyList; +import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS; +import static org.opendaylight.genius.infra.Datastore.CONFIGURATION; import static org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceType.GRE_TRUNK_INTERFACE; +import static org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceType.LOGICAL_GROUP_INTERFACE; import static org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceType.MPLS_OVER_GRE; import static org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceType.VLAN_INTERFACE; import static org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE; @@ -15,25 +19,31 @@ import static org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.Int import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.ListenableFuture; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.apache.commons.lang3.BooleanUtils; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator; +import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; +import org.opendaylight.genius.infra.Datastore.Configuration; +import org.opendaylight.genius.infra.ManagedNewTransactionRunner; +import org.opendaylight.genius.infra.TypedWriteTransaction; import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils; import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo; import org.opendaylight.genius.interfacemanager.globals.VlanInterfaceInfo; -import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils; import org.opendaylight.genius.mdsalutil.ActionInfo; import org.opendaylight.genius.mdsalutil.MDSALUtil; import org.opendaylight.genius.mdsalutil.MetaDataUtil; import org.opendaylight.genius.mdsalutil.NwConstants; +import org.opendaylight.genius.mdsalutil.actions.ActionGroup; import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit; import org.opendaylight.genius.mdsalutil.actions.ActionOutput; import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan; @@ -42,13 +52,13 @@ import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId; import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid; import org.opendaylight.genius.mdsalutil.actions.ActionSetTunnelDestinationIp; import org.opendaylight.genius.mdsalutil.actions.ActionSetTunnelSourceIp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel; +import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; @@ -63,6 +73,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406. import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdPools; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan; @@ -72,6 +83,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlanGpe; @@ -83,11 +95,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.ser import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId; import org.opendaylight.yangtools.yang.binding.DataObject; @@ -97,46 +104,42 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class IfmUtil { +public final class IfmUtil { + private static final Logger LOG = LoggerFactory.getLogger(IfmUtil.class); private static final int INVALID_ID = 0; - private static final ImmutableMap, InterfaceInfo.InterfaceType> TUNNEL_TYPE_MAP = - new ImmutableMap.Builder, InterfaceInfo.InterfaceType>() - .put(TunnelTypeGre.class, GRE_TRUNK_INTERFACE) - .put(TunnelTypeMplsOverGre.class, MPLS_OVER_GRE) - .put(TunnelTypeVxlan.class, VXLAN_TRUNK_INTERFACE) - .put(TunnelTypeVxlanGpe.class, VXLAN_TRUNK_INTERFACE) - .build(); + private IfmUtil() { + throw new IllegalStateException("Utility class"); + } + + private static final ImmutableMap, InterfaceInfo.InterfaceType> + TUNNEL_TYPE_MAP = new ImmutableMap.Builder, InterfaceInfo.InterfaceType>() + .put(TunnelTypeGre.class, GRE_TRUNK_INTERFACE).put(TunnelTypeMplsOverGre.class, MPLS_OVER_GRE) + .put(TunnelTypeVxlan.class, VXLAN_TRUNK_INTERFACE).put(TunnelTypeVxlanGpe.class, VXLAN_TRUNK_INTERFACE) + .put(TunnelTypeLogicalGroup.class, LOGICAL_GROUP_INTERFACE) + .build(); public static BigInteger getDpnFromNodeConnectorId(NodeConnectorId portId) { + return new BigInteger(getDpnStringFromNodeConnectorId(portId)); + } + + public static String getDpnStringFromNodeConnectorId(NodeConnectorId portId) { /* * NodeConnectorId is of form 'openflow:dpnid:portnum' */ - String[] split = portId.getValue().split(IfmConstants.OF_URI_SEPARATOR); - return new BigInteger(split[1]); + return portId.getValue().split(IfmConstants.OF_URI_SEPARATOR)[1]; } - public static BigInteger getDpnFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState){ + public static BigInteger getDpnFromInterface( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.interfaces.rev140508.interfaces.state.Interface ifState) { NodeConnectorId ncId = getNodeConnectorIdFromInterface(ifState); - if(ncId != null){ + if (ncId != null) { return getDpnFromNodeConnectorId(ncId); } return null; } - public static String getPortNoFromInterfaceName(String ifaceName, DataBroker broker) { - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = - InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(ifaceName, broker); - - if(ifState == null){ - throw new NullPointerException("Interface information not present in oper DS for " +ifaceName); - } - String lowerLayerIf = ifState.getLowerLayerIf().get(0); - NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf); - String portNo = IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId); - - return portNo; - } public static String getPortNoFromNodeConnectorId(NodeConnectorId portId) { /* @@ -148,9 +151,9 @@ public class IfmUtil { public static Long getPortNumberFromNodeConnectorId(NodeConnectorId portId) { String portNo = getPortNoFromNodeConnectorId(portId); - try{ + try { return Long.valueOf(portNo); - }catch(NumberFormatException ex){ + } catch (NumberFormatException ex) { LOG.trace("Unable to retrieve port number from nodeconnector id for {}", portId); } return IfmConstants.INVALID_PORT_NO; @@ -161,84 +164,69 @@ public class IfmUtil { } public static InstanceIdentifier buildId(String interfaceName) { - //TODO Make this generic and move to AbstractDataChangeListener or Utils. - InstanceIdentifierBuilder idBuilder = - InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName)); - InstanceIdentifier id = idBuilder.build(); - return id; - } - - public static InstanceIdentifier buildStateInterfaceId(String interfaceName) { - InstanceIdentifierBuilder idBuilder = - InstanceIdentifier.builder(InterfacesState.class) - .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class, - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName)); - InstanceIdentifier id = idBuilder.build(); - return id; - } - - public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName( + // TODO Make this generic and move to AbstractDataChangeListener or + // Utils. + InstanceIdentifierBuilder idBuilder = InstanceIdentifier.builder(Interfaces.class) + .child(Interface.class, new InterfaceKey(interfaceName)); + return idBuilder.build(); + } + + public static InstanceIdentifier buildStateInterfaceId( + String interfaceName) { + InstanceIdentifierBuilder idBuilder = InstanceIdentifier + .builder(InterfacesState.class) + .child(org.opendaylight.yang.gen.v1.urn + .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class, + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.interfaces.rev140508.interfaces.state.InterfaceKey( + interfaceName)); + return idBuilder.build(); + } + + public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName( String name) { - return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name); - } - - public static InstanceIdentifier getPoolId(String poolName){ - InstanceIdentifier.InstanceIdentifierBuilder idBuilder = - InstanceIdentifier.builder(IdPools.class).child(IdPool.class, new IdPoolKey(poolName)); - InstanceIdentifier id = idBuilder.build(); - return id; + return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.interfaces.rev140508.interfaces.state.InterfaceKey( + name); } - public static List getPortNameAndSuffixFromInterfaceName(String intfName) { - List strList = new ArrayList<>(2); - int index = intfName.indexOf(":"); - if (index != -1) { - strList.add(0, intfName.substring(0, index)); - strList.add(1, intfName.substring(index)); - } - return strList; + public static InstanceIdentifier getPoolId(String poolName) { + return InstanceIdentifier.builder(IdPools.class).child(IdPool.class, new IdPoolKey(poolName)).build(); } - public static long getGroupId(long ifIndex, InterfaceInfo.InterfaceType infType) { - if (infType == InterfaceInfo.InterfaceType.LOGICAL_GROUP_INTERFACE) { - return ifIndex + IfmConstants.LOGICAL_GROUP_START; - } - else if (infType == VLAN_INTERFACE) { - return ifIndex + IfmConstants.VLAN_GROUP_START; - } else { - return ifIndex + IfmConstants.TRUNK_GROUP_START; + public static long getGroupId(int ifIndex, InterfaceInfo.InterfaceType infType) { + if (infType == LOGICAL_GROUP_INTERFACE) { + return getLogicalTunnelSelectGroupId(ifIndex); } + return 0; } - public static List getDpIdPortNameAndSuffixFromInterfaceName(String intfName) { - List strList = new ArrayList<>(3); - int index1 = intfName.indexOf(":"); - if (index1 != -1) { - int index2 = intfName.indexOf(":", index1 + 1 ); - strList.add(0, intfName.substring(0, index1)); - if (index2 != -1) { - strList.add(1, intfName.substring(index1, index2)); - strList.add(2, intfName.substring(index2)); - } else { - strList.add(1, intfName.substring(index1)); - strList.add(2, ""); - } - } - return strList; - } - + /** + * Synchronous blocking read from data store. + * + * @deprecated Use + * {@link SingleTransactionDataBroker#syncReadOptional(DataBroker, LogicalDatastoreType, InstanceIdentifier)} + * instead of this. + */ + @Deprecated public static Optional read(LogicalDatastoreType datastoreType, - InstanceIdentifier path, DataBroker broker) { + InstanceIdentifier path, DataBroker broker) { try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) { return tx.read(datastoreType, path).get(); - } catch (Exception e) { + } catch (InterruptedException | ExecutionException e) { + LOG.error("Cannot read identifier", e); throw new RuntimeException(e); } } public static List getEgressActionsForInterface(String interfaceName, Long tunnelKey, Integer actionKey, - DataBroker dataBroker, Boolean isDefaultEgress) { - List listActionInfo = getEgressActionInfosForInterface(interfaceName, tunnelKey, actionKey==null?0:actionKey, dataBroker, isDefaultEgress); + InterfaceManagerCommonUtils interfaceUtils, Boolean isDefaultEgress) { + List listActionInfo = getEgressActionInfosForInterface(interfaceName, tunnelKey, + actionKey == null ? 0 : actionKey, interfaceUtils, isDefaultEgress); List actionsList = new ArrayList<>(); for (ActionInfo actionInfo : listActionInfo) { actionsList.add(actionInfo.buildAction()); @@ -247,55 +235,56 @@ public class IfmUtil { } public static List getEgressInstructionsForInterface(String interfaceName, Long tunnelKey, - DataBroker dataBroker, Boolean isDefaultEgress) { + InterfaceManagerCommonUtils interfaceUtils, Boolean isDefaultEgress) { List instructions = new ArrayList<>(); - List actionList = MDSALUtil.buildActions(getEgressActionInfosForInterface( - interfaceName, tunnelKey, 0, dataBroker, isDefaultEgress)); + List actionList = MDSALUtil.buildActions( + getEgressActionInfosForInterface(interfaceName, tunnelKey, 0, interfaceUtils, isDefaultEgress)); instructions.add(MDSALUtil.buildApplyActionsInstruction(actionList)); - return instructions; + return instructions; } public static List getEgressInstructionsForInterface(Interface interfaceInfo, String portNo, - Long tunnelKey, boolean isDefaultEgress, int ifIndex) { + Long tunnelKey, boolean isDefaultEgress, + int ifIndex, long groupId) { List instructions = new ArrayList<>(); InterfaceInfo.InterfaceType ifaceType = getInterfaceType(interfaceInfo); List actionList = MDSALUtil.buildActions( - getEgressActionInfosForInterface(interfaceInfo, portNo, ifaceType, tunnelKey, 0, isDefaultEgress, ifIndex)); + getEgressActionInfosForInterface(interfaceInfo, portNo, ifaceType, tunnelKey, 0, + isDefaultEgress, ifIndex, groupId)); instructions.add(MDSALUtil.buildApplyActionsInstruction(actionList)); - return instructions; + return instructions; } - - public static List getEgressActionInfosForInterface(String interfaceName, - int actionKeyStart, - DataBroker dataBroker, - Boolean isDefaultEgress) { - return getEgressActionInfosForInterface(interfaceName, null, actionKeyStart, dataBroker, isDefaultEgress); + public static List getEgressActionInfosForInterface(String interfaceName, int actionKeyStart, + InterfaceManagerCommonUtils interfaceUtils, Boolean isDefaultEgress) { + return getEgressActionInfosForInterface(interfaceName, null, actionKeyStart, interfaceUtils, isDefaultEgress); } /** - * Returns a list of Actions to be taken when sending a packet over an interface + * Returns a list of Actions to be taken when sending a packet over an + * interface. * * @param interfaceName - * @param tunnelKey Optional. + * name of the interface + * @param tunnelKey + * Optional. * @param actionKeyStart - * @param dataBroker - * @return + * action key + * @param interfaceUtils + * InterfaceManagerCommonUtils + * @return list of actions */ - public static List getEgressActionInfosForInterface(String interfaceName, - Long tunnelKey, - int actionKeyStart, - DataBroker dataBroker, - Boolean isDefaultEgress) { - Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), - dataBroker); - if(interfaceInfo == null){ - throw new NullPointerException("Interface information not present in config DS for " +interfaceName); + public static List getEgressActionInfosForInterface(String interfaceName, Long tunnelKey, + int actionKeyStart, InterfaceManagerCommonUtils interfaceUtils, Boolean isDefaultEgress) { + Interface interfaceInfo = interfaceUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName)); + if (interfaceInfo == null) { + throw new NullPointerException("Interface information not present in config DS for " + interfaceName); } - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState = - InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker); - if(ifState == null){ - throw new NullPointerException("Interface information not present in oper DS for " +interfaceName); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.interfaces.rev140508.interfaces.state.Interface ifState = + interfaceUtils.getInterfaceState(interfaceName); + if (ifState == null) { + throw new NullPointerException("Interface information not present in oper DS for " + interfaceName); } String lowerLayerIf = ifState.getLowerLayerIf().get(0); NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf); @@ -303,42 +292,64 @@ public class IfmUtil { InterfaceInfo.InterfaceType ifaceType = getInterfaceType(interfaceInfo); return getEgressActionInfosForInterface(interfaceInfo, portNo, ifaceType, tunnelKey, actionKeyStart, - isDefaultEgress, ifState.getIfIndex()); + isDefaultEgress, ifState.getIfIndex(), 0); } - - public static List getEgressActionInfosForInterface(Interface interfaceInfo, - String portNo, - InterfaceInfo.InterfaceType ifaceType, - Long tunnelKey, - int actionKeyStart, - boolean isDefaultEgress, - int ifIndex) { + /** + * Returns the list of egress actions for a given interface. + * + * @param interfaceInfo the interface to look up + * @param portNo port number + * @param ifaceType the type of the interface + * @param tunnelKey the tunnel key + * @param actionKeyStart the start for the first key assigned for the new actions + * @param isDefaultEgress if it is the default egress + * @param ifIndex interface index + * @param groupId group Id + * @return list of actions for the interface + */ + // The following suppression is for javac, not for checkstyle + @SuppressWarnings("fallthrough") + @SuppressFBWarnings("SF_SWITCH_FALLTHROUGH") + public static List getEgressActionInfosForInterface(Interface interfaceInfo, String portNo, + InterfaceInfo.InterfaceType ifaceType, Long tunnelKey, int actionKeyStart, boolean isDefaultEgress, + int ifIndex, long groupId) { List result = new ArrayList<>(); switch (ifaceType) { case MPLS_OVER_GRE: - case VXLAN_TRUNK_INTERFACE: + // fall through case GRE_TRUNK_INTERFACE: - if(!isDefaultEgress) { - //TODO tunnel_id to encode GRE key, once it is supported - // Until then, tunnel_id should be "cleaned", otherwise it stores the value coming from a VXLAN tunnel + if (!isDefaultEgress) { + // TODO tunnel_id to encode GRE key, once it is supported + // Until then, tunnel_id should be "cleaned", otherwise it + // stores the value coming from a VXLAN tunnel if (tunnelKey == null) { tunnelKey = 0L; } - result.add(new ActionSetFieldTunnelId(actionKeyStart++, BigInteger.valueOf(tunnelKey))); - - IfTunnel ifTunnel = interfaceInfo.getAugmentation(IfTunnel.class); - if (BooleanUtils.isTrue(ifTunnel.isTunnelRemoteIpFlow())) { + } + // fall through + case VXLAN_TRUNK_INTERFACE: + if (!isDefaultEgress) { + if (tunnelKey != null) { + result.add(new ActionSetFieldTunnelId(actionKeyStart++, BigInteger.valueOf(tunnelKey))); + } + } else { + // For OF Tunnels default egress actions need to set tunnelIps + IfTunnel ifTunnel = interfaceInfo.augmentation(IfTunnel.class); + if (BooleanUtils.isTrue(ifTunnel.isTunnelRemoteIpFlow() + && ifTunnel.getTunnelDestination() != null)) { result.add(new ActionSetTunnelDestinationIp(actionKeyStart++, ifTunnel.getTunnelDestination())); } - if (BooleanUtils.isTrue(ifTunnel.isTunnelSourceIpFlow())) { + if (BooleanUtils.isTrue(ifTunnel.isTunnelSourceIpFlow() + && ifTunnel.getTunnelSource() != null)) { result.add(new ActionSetTunnelSourceIp(actionKeyStart++, ifTunnel.getTunnelSource())); } } + // fall through case VLAN_INTERFACE: - if(isDefaultEgress) { - IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class); - LOG.trace("L2Vlan: {}", vlanIface); + if (isDefaultEgress) { + IfL2vlan vlanIface = interfaceInfo.augmentation(IfL2vlan.class); + LOG.trace("get egress actions for l2vlan interface: {}", vlanIface); boolean isVlanTransparent = false; int vlanVid = 0; if (vlanIface != null) { @@ -350,13 +361,18 @@ public class IfmUtil { result.add(new ActionSetFieldVlanVid(actionKeyStart++, vlanVid)); } result.add(new ActionOutput(actionKeyStart++, new Uri(portNo))); - }else{ - long regValue = MetaDataUtil.getReg6ValueForLPortDispatcher(ifIndex, NwConstants.DEFAULT_SERVICE_INDEX); - result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, IfmConstants.REG6_START_INDEX, - IfmConstants.REG6_END_INDEX, regValue)); - result.add(new ActionNxResubmit(actionKeyStart++, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE)); + } else { + addEgressActionInfosForInterface(ifIndex, actionKeyStart, result); } break; + case LOGICAL_GROUP_INTERFACE: + if (isDefaultEgress) { + result.add(new ActionGroup(groupId)); + } else { + addEgressActionInfosForInterface(ifIndex, actionKeyStart, result); + } + break; + default: LOG.warn("Interface Type {} not handled yet", ifaceType); break; @@ -364,8 +380,15 @@ public class IfmUtil { return result; } + public static void addEgressActionInfosForInterface(int ifIndex, int actionKeyStart, List result) { + long regValue = MetaDataUtil.getReg6ValueForLPortDispatcher(ifIndex, NwConstants.DEFAULT_SERVICE_INDEX); + result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, IfmConstants.REG6_START_INDEX, + IfmConstants.REG6_END_INDEX, regValue)); + result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE)); + } + public static NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) { - return new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":"))); + return new NodeId(ncId.getValue().substring(0, ncId.getValue().lastIndexOf(':'))); } public static BigInteger[] mergeOpenflowMetadataWriteInstructions(List instructions) { @@ -374,9 +397,11 @@ public class IfmUtil { if (instructions != null && !instructions.isEmpty()) { // check if metadata write instruction is present for (Instruction instruction : instructions) { - org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction actualInstruction = instruction.getInstruction(); + org.opendaylight.yang.gen.v1.urn.opendaylight.flow + .types.rev131026.instruction.Instruction actualInstruction = instruction + .getInstruction(); if (actualInstruction instanceof WriteMetadataCase) { - WriteMetadataCase writeMetaDataInstruction = (WriteMetadataCase) actualInstruction ; + WriteMetadataCase writeMetaDataInstruction = (WriteMetadataCase) actualInstruction; WriteMetadata availableMetaData = writeMetaDataInstruction.getWriteMetadata(); metadata = metadata.or(availableMetaData.getMetadata()); metadataMask = metadataMask.or(availableMetaData.getMetadataMask()); @@ -387,64 +412,48 @@ public class IfmUtil { } public static Integer allocateId(IdManagerService idManager, String poolName, String idKey) { - AllocateIdInput getIdInput = new AllocateIdInputBuilder() - .setPoolName(poolName) - .setIdKey(idKey).build(); + AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); try { Future> result = idManager.allocateId(getIdInput); RpcResult rpcResult = result.get(); - if(rpcResult.isSuccessful()) { + if (rpcResult.isSuccessful()) { return rpcResult.getResult().getIdValue().intValue(); } else { LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors()); } } catch (InterruptedException | ExecutionException e) { - LOG.warn("Exception when getting Unique Id",e); + LOG.warn("Exception when getting Unique Id", e); } return INVALID_ID; } public static void releaseId(IdManagerService idManager, String poolName, String idKey) { - ReleaseIdInput idInput = new ReleaseIdInputBuilder() - .setPoolName(poolName) - .setIdKey(idKey).build(); + ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); try { - Future> result = idManager.releaseId(idInput); - RpcResult rpcResult = result.get(); - if(!rpcResult.isSuccessful()) { - LOG.warn("RPC Call to release Id {} with Key {} returned with Errors {}", - idKey, rpcResult.getErrors()); + ListenableFuture> result = idManager.releaseId(idInput); + RpcResult rpcResult = result.get(); + if (!rpcResult.isSuccessful()) { + LOG.warn("RPC Call to release Id with Key {} returned with Errors {}", idKey, rpcResult.getErrors()); } } catch (InterruptedException | ExecutionException e) { LOG.warn("Exception when releasing Id for key {}", idKey, e); } } - public static BigInteger getDpnId(DatapathId datapathId){ + public static BigInteger getDpnId(DatapathId datapathId) { if (datapathId != null) { - // Adding logs for a random issue spotted during datapath id conversion + // Adding logs for a random issue spotted during datapath id + // conversion String dpIdStr = datapathId.getValue().replace(":", ""); - BigInteger dpnId = new BigInteger(dpIdStr, 16); - return dpnId; + return new BigInteger(dpIdStr, 16); } return null; } - public static NodeConnectorId getNodeConnectorIdFromInterface(String interfaceName, DataBroker dataBroker) { - return FlowBasedServicesUtils.getNodeConnectorIdFromInterface(interfaceName, dataBroker); - } - - public static String getPortName(DataBroker dataBroker, NodeConnectorId ncId){ - InstanceIdentifier ncIdentifier = - InstanceIdentifier.builder(Nodes.class) - .child(Node.class, new NodeKey(getNodeIdFromNodeConnectorId(ncId))) - .child(NodeConnector.class, new NodeConnectorKey(ncId)).build(); - return read(LogicalDatastoreType.OPERATIONAL, ncIdentifier, dataBroker).transform( - nc -> nc.getAugmentation(FlowCapableNodeConnector.class).getName()).orNull(); - } - - public static NodeConnectorId getNodeConnectorIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState){ - if(ifState != null) { + public static NodeConnectorId getNodeConnectorIdFromInterface( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang + .ietf.interfaces.rev140508.interfaces.state.Interface ifState) { + if (ifState != null) { List ofportIds = ifState.getLowerLayerIf(); return new NodeConnectorId(ofportIds.get(0)); } @@ -452,30 +461,33 @@ public class IfmUtil { } public static InterfaceInfo.InterfaceType getInterfaceType(Interface iface) { - InterfaceInfo.InterfaceType interfaceType = org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE; - Class ifType = iface + InterfaceInfo.InterfaceType interfaceType = org.opendaylight + .genius.interfacemanager.globals.InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE; + Class ifType = iface .getType(); if (ifType.isAssignableFrom(L2vlan.class)) { interfaceType = VLAN_INTERFACE; } else if (ifType.isAssignableFrom(Tunnel.class)) { - IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class); - Class tunnelType = ifTunnel + IfTunnel ifTunnel = iface.augmentation(IfTunnel.class); + Class tunnelType = ifTunnel .getTunnelInterfaceType(); - interfaceType = TUNNEL_TYPE_MAP.get(tunnelType); + interfaceType = tunnelType.isAssignableFrom(TunnelTypeLogicalGroup.class) + ? InterfaceInfo.InterfaceType.LOGICAL_GROUP_INTERFACE : TUNNEL_TYPE_MAP.get(tunnelType); } return interfaceType; } - public static VlanInterfaceInfo getVlanInterfaceInfo(String interfaceName, Interface iface, BigInteger dpId) { - + public static VlanInterfaceInfo getVlanInterfaceInfo(Interface iface, BigInteger dpId) { short vlanId = 0; String portName = null; - IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class); - ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class); + IfL2vlan vlanIface = iface.augmentation(IfL2vlan.class); + ParentRefs parentRefs = iface.augmentation(ParentRefs.class); if (parentRefs != null && parentRefs.getParentInterface() != null) { portName = parentRefs.getParentInterface(); - }else { + } else { LOG.warn("Portname set to null since parentRef is Null"); } VlanInterfaceInfo vlanInterfaceInfo = new VlanInterfaceInfo(dpId, portName, vlanId); @@ -504,58 +516,69 @@ public class IfmUtil { return new BigInteger("FFFF", 16).and(BigInteger.valueOf(portNumber)); } - public static String generateMacAddress(long portNo){ + public static String generateMacAddress(long portNo) { String unformattedMAC = getDeadBeefBytesForMac().or(fillPortNumberToMac(portNo)).toString(16); - return unformattedMAC.replaceAll("(.{2})", "$1"+IfmConstants.MAC_SEPARATOR). - substring(0, IfmConstants.MAC_STRING_LENGTH); + return unformattedMAC.replaceAll("(.{2})", "$1" + IfmConstants.MAC_SEPARATOR).substring(0, + IfmConstants.MAC_STRING_LENGTH); } - public static PhysAddress getPhyAddress(long portNo, FlowCapableNodeConnector flowCapableNodeConnector){ + public static PhysAddress getPhyAddress(long portNo, FlowCapableNodeConnector flowCapableNodeConnector) { String southboundMacAddress = flowCapableNodeConnector.getHardwareAddress().getValue(); - if(IfmConstants.INVALID_MAC.equals(southboundMacAddress)){ - LOG.debug("Invalid MAC Address received for {}, generating MAC Address", flowCapableNodeConnector.getName()); + if (IfmConstants.INVALID_MAC.equals(southboundMacAddress)) { + LOG.debug("Invalid MAC Address received for {}, generating MAC Address", + flowCapableNodeConnector.getName()); southboundMacAddress = generateMacAddress(portNo); } return new PhysAddress(southboundMacAddress); } - public static void updateInterfaceParentRef(WriteTransaction t, String interfaceName, String parentInterface) { + public static void updateInterfaceParentRef(TypedWriteTransaction tx, String interfaceName, + String parentInterface) { InstanceIdentifier parentRefIdentifier = InstanceIdentifier.builder(Interfaces.class) .child(Interface.class, new InterfaceKey(interfaceName)).augmentation(ParentRefs.class).build(); ParentRefs parentRefs = new ParentRefsBuilder().setParentInterface(parentInterface).build(); - t.merge(LogicalDatastoreType.CONFIGURATION, parentRefIdentifier, parentRefs); - LOG.debug("Updating parentRefInterface for interfaceName {}. interfaceKey {}, with parentRef augmentation pointing to {}", + tx.merge(parentRefIdentifier, parentRefs); + LOG.debug( + "Updating parentRefInterface for interfaceName {}. " + + "interfaceKey {}, with parentRef augmentation pointing to {}", interfaceName, new InterfaceKey(interfaceName), parentInterface); } public static InstanceIdentifier buildBoundServicesIId(short servicePriority, String interfaceName, - Class serviceMode) { + Class serviceMode) { return InstanceIdentifier.builder(ServiceBindings.class) - .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode)) - .child(BoundServices.class, new BoundServicesKey(servicePriority)) - .build(); + .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode)) + .child(BoundServices.class, new BoundServicesKey(servicePriority)).build(); } - public static void bindService(WriteTransaction t, String interfaceName, BoundServices serviceInfo, - Class serviceMode) { + public static void bindService(TypedWriteTransaction tx, String interfaceName, + BoundServices serviceInfo, Class serviceMode) { LOG.info("Binding Service {} for : {}", serviceInfo.getServiceName(), interfaceName); - InstanceIdentifier boundServicesInstanceIdentifier = - buildBoundServicesIId(serviceInfo.getServicePriority(), interfaceName, serviceMode); - t.put(LogicalDatastoreType.CONFIGURATION, boundServicesInstanceIdentifier, serviceInfo, true); + InstanceIdentifier boundServicesInstanceIdentifier = buildBoundServicesIId( + serviceInfo.getServicePriority(), interfaceName, serviceMode); + tx.put(boundServicesInstanceIdentifier, serviceInfo, CREATE_MISSING_PARENTS); } - public static void unbindService(DataBroker dataBroker, String interfaceName, InstanceIdentifier - boundServicesInstanceIdentifier){ + public static void unbindService(ManagedNewTransactionRunner txRunner, JobCoordinator coordinator, + String interfaceName, InstanceIdentifier boundServicesInstanceIdentifier) { + coordinator.enqueueJob(interfaceName, () -> Collections.singletonList( + txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, + tx -> unbindService(tx, interfaceName, boundServicesInstanceIdentifier)))); + } + + public static void unbindService(TypedWriteTransaction tx, String interfaceName, + InstanceIdentifier boundServicesInstanceIdentifier) { LOG.info("Unbinding Service from : {}", interfaceName); - DataStoreJobCoordinator dataStoreJobCoordinator = DataStoreJobCoordinator.getInstance(); - dataStoreJobCoordinator.enqueueJob(interfaceName, - () -> { - WriteTransaction t = dataBroker.newWriteOnlyTransaction(); - t.delete(LogicalDatastoreType.CONFIGURATION, boundServicesInstanceIdentifier); - List> futures = new ArrayList<>(); - futures.add(t.submit()); - return futures; - } - ); + tx.delete(boundServicesInstanceIdentifier); + } + + public static long getLogicalTunnelSelectGroupId(int lportTag) { + return org.opendaylight.genius.interfacemanager.globals.IfmConstants.VXLAN_GROUPID_MIN + lportTag; + } + + // TODO Replace this with mdsal's DataObjectUtils.nullToEmpty when upgrading to mdsal 3.0.2 + @Nonnull + public static List nullToEmpty(final @Nullable List input) { + return input != null ? input : emptyList(); } }