X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=neutron-ovsdb%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fgroupbasedpolicy%2Fneutron%2Fovsdb%2Futil%2FInventoryHelper.java;h=807ad1c8e84ce101ab1741db3a9d7281a108448d;hb=02dd576a2ff7d7a8c304bd74a239c150be1ddd2b;hp=2cbca5eb969c9f35b213fda62824f8dc1785bd9e;hpb=30580757fd142ea79838b94faaa4bfc296e149dd;p=groupbasedpolicy.git diff --git a/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/util/InventoryHelper.java b/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/util/InventoryHelper.java old mode 100644 new mode 100755 index 2cbca5eb9..807ad1c8e --- a/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/util/InventoryHelper.java +++ b/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/util/InventoryHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2015 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, @@ -7,14 +7,17 @@ */ package org.opendaylight.groupbasedpolicy.neutron.ovsdb.util; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.DataStore.getLongFromDpid; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.DataStore.readFromDs; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.DataStore.submitToDs; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getOvsdbBridge; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getOvsdbBridgeFromTerminationPoint; import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getOvsdbTerminationPoint; +import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs; +import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.submitToDs; + +import com.google.common.base.Optional; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.opendaylight.controller.md.sal.binding.api.DataBroker; @@ -22,9 +25,13 @@ import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.neutron.ovsdb.AbstractTunnelType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.groupbasedpolicy.util.DataStoreHelper; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.ExternalInterfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.ExternalInterfacesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.ExternalInterfacesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.Tunnel; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; @@ -39,27 +46,43 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Optional; - public class InventoryHelper { + private static final Logger LOG = LoggerFactory.getLogger(InventoryHelper.class); + private static final String HEX = "0x"; - private static final Long MAX_OF_PORT=65534L; /** - * Construct a String that can be used to create a - * {@link NodeId}. + * Convert an OpenFlow Datapath ID to a Long. + * + * @param dpid The OpenFlow Datapath ID + * @return The Long representation of the DPID + */ + public static Long getLongFromDpid(String dpid) { + String[] addressInBytes = dpid.split(":"); + Long address = (Long.decode(HEX + addressInBytes[2]) << 40) | (Long.decode(HEX + addressInBytes[3]) << 32) + | (Long.decode(HEX + addressInBytes[4]) << 24) | (Long.decode(HEX + addressInBytes[5]) << 16) + | (Long.decode(HEX + addressInBytes[6]) << 8) | (Long.decode(HEX + addressInBytes[7])); + return address; + } + + private static final Long MAX_OF_PORT = 65534L; + + /** + * Construct a String that can be used to create a {@link NodeId}. * The String is constructed by getting the Datapath ID from the OVSDB bridge * augmentation, converting that to a Long, and prepending it with the * "openflow:" prefix. * - * @param ovsdbBridge The OVSDB bridge augmentation + * @param ovsdbBridge The {@link OvsdbBridgeAugmentation} + * @param ovsdbTpIid the {@link OvsdbTerminationPointAugmentation} + * @param dataBroker the {@link DataBroker} * @return String representation of the Inventory NodeId, null if it fails */ public static String getInventoryNodeIdString(OvsdbBridgeAugmentation ovsdbBridge, InstanceIdentifier ovsdbTpIid, DataBroker dataBroker) { DatapathId dpid = ovsdbBridge.getDatapathId(); if (dpid == null) { - OvsdbBridgeAugmentation bridgeData = getOvsdbBridge(ovsdbTpIid, dataBroker); + OvsdbBridgeAugmentation bridgeData = getOvsdbBridgeFromTerminationPoint(ovsdbTpIid, dataBroker); dpid = bridgeData.getDatapathId(); if (dpid == null) { LOG.error("No Data Path ID for OVSDB Bridge {}", ovsdbBridge); @@ -68,8 +91,8 @@ public class InventoryHelper { } Long macLong = getLongFromDpid(ovsdbBridge.getDatapathId().getValue()); String nodeIdString = "openflow:" + String.valueOf(macLong); - if(StringUtils.countMatches(nodeIdString, ":") != 1) { - LOG.error("{} is not correct format for NodeId.",nodeIdString); + if (StringUtils.countMatches(nodeIdString, ":") != 1) { + LOG.error("{} is not correct format for NodeId.", nodeIdString); return null; } return nodeIdString; @@ -83,24 +106,22 @@ public class InventoryHelper { * * @param inventoryNodeId The string representation of the Inventory NodeId * @param ovsdbTp The {@link OvsdbTerminationPointAugmentation} + * @param tpIid the InstanceIdentifier for OvsdbTerminationPointAugmentation + * @param dataBroker the {@link DataBroker} * @return String representation of the Inventory NodeConnectorId, null if it fails */ public static String getInventoryNodeConnectorIdString(String inventoryNodeId, - OvsdbTerminationPointAugmentation ovsdbTp, - InstanceIdentifier tpIid, - DataBroker dataBroker) { + OvsdbTerminationPointAugmentation ovsdbTp, InstanceIdentifier tpIid, + DataBroker dataBroker) { Long ofport = null; - if (ovsdbTp.getOfport() != null && ovsdbTp.getOfport()>MAX_OF_PORT) { - LOG.debug("Invalid OpenFlow port {} for {}",ovsdbTp.getOfport(), ovsdbTp); + if (ovsdbTp.getOfport() != null && ovsdbTp.getOfport() > MAX_OF_PORT) { + LOG.debug("Invalid OpenFlow port {} for {}", ovsdbTp.getOfport(), ovsdbTp); return null; } if (ovsdbTp.getOfport() == null) { - OvsdbTerminationPointAugmentation readOvsdbTp = - getOvsdbTerminationPoint(tpIid, dataBroker); - if (readOvsdbTp == null - || readOvsdbTp.getOfport() == null - || readOvsdbTp.getOfport() >MAX_OF_PORT) { - LOG.debug("Couldn't get OpenFlow port for {}",ovsdbTp); + OvsdbTerminationPointAugmentation readOvsdbTp = getOvsdbTerminationPoint(tpIid, dataBroker); + if (readOvsdbTp == null || readOvsdbTp.getOfport() == null || readOvsdbTp.getOfport() > MAX_OF_PORT) { + LOG.debug("Couldn't get OpenFlow port for {}", ovsdbTp); return null; } ofport = readOvsdbTp.getOfport(); @@ -109,8 +130,8 @@ public class InventoryHelper { } String nodeConnectorIdString = inventoryNodeId + ":" + String.valueOf(ofport); - if(StringUtils.countMatches(nodeConnectorIdString, ":") != 2) { - LOG.error("{} is not correct format for NodeConnectorId.",nodeConnectorIdString); + if (StringUtils.countMatches(nodeConnectorIdString, ":") != 2) { + LOG.error("{} is not correct format for NodeConnectorId.", nodeConnectorIdString); return null; } return nodeConnectorIdString; @@ -119,15 +140,18 @@ public class InventoryHelper { /** * Read the {@link OfOverlayNodeConfig} augmentation from the * Inventory Node, and verify that the tunnel types we need - * are present + * are present. * + * @param nodeIdString The inventory node id string + * @param requiredTunnelTypes the list of tunnel types + * @param dataBroker the {@link DataBroker} * @return true if tunnel types are present, false otherwise */ - public static boolean checkOfOverlayConfig(String nodeIdString, - List requiredTunnelTypes, DataBroker dataBroker) { + public static boolean checkOfOverlayConfig(String nodeIdString, List requiredTunnelTypes, + DataBroker dataBroker) { OfOverlayNodeConfig config = getOfOverlayConfig(nodeIdString, dataBroker); if (config == null || config.getTunnel() == null) { - LOG.debug("No OfOverlay config for {}",nodeIdString); + LOG.debug("No OfOverlay config for {}", nodeIdString); return false; } @@ -135,9 +159,9 @@ public class InventoryHelper { * See if the OfOverlayNodeConfig has the * tunnel type information. */ - for (AbstractTunnelType tunnelType: requiredTunnelTypes) { + for (AbstractTunnelType tunnelType : requiredTunnelTypes) { boolean tunnelPresent = false; - for (Tunnel tunnel: config.getTunnel()) { + for (Tunnel tunnel : config.getTunnel()) { if (tunnelType.getTunnelType().equals(tunnel.getTunnelType())) { tunnelPresent = true; break; @@ -150,91 +174,180 @@ public class InventoryHelper { return true; } + public static InstanceIdentifier addOfOverlayExternalPort(NodeId nodeId, NodeConnectorId ncId, + DataBroker dataBroker) { + InstanceIdentifier nodeExternalInterfacesIid = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(nodeId)) + .augmentation(OfOverlayNodeConfig.class) + .child(ExternalInterfaces.class, new ExternalInterfacesKey(ncId)) + .build(); + + ExternalInterfaces externalInterfaces = new ExternalInterfacesBuilder().setKey(new ExternalInterfacesKey(ncId)) + .setNodeConnectorId(ncId) + .build(); + WriteTransaction transaction = dataBroker.newWriteOnlyTransaction(); + transaction.put(LogicalDatastoreType.CONFIGURATION, nodeExternalInterfacesIid, externalInterfaces, true); + DataStoreHelper.submitToDs(transaction); + LOG.trace("Added external interface node connector {} to node {}", ncId.getValue(), nodeId.getValue()); + return nodeExternalInterfacesIid; + } + public static OfOverlayNodeConfig getOfOverlayConfig(String nodeIdString, DataBroker dataBroker) { - InstanceIdentifier ofOverlayNodeIid = InstanceIdentifier.builder( - Nodes.class) + InstanceIdentifier ofOverlayNodeIid = InstanceIdentifier.builder(Nodes.class) .child(Node.class, new NodeKey(new NodeId(nodeIdString))) .augmentation(OfOverlayNodeConfig.class) .build(); ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction(); - Optional overlayConfig = readFromDs(LogicalDatastoreType.OPERATIONAL, ofOverlayNodeIid, transaction ); + Optional overlayConfig = readFromDs(LogicalDatastoreType.CONFIGURATION, ofOverlayNodeIid, + transaction); if (overlayConfig.isPresent()) { return overlayConfig.get(); } return null; } - private static void addOfOverlayAugmentation(OfOverlayNodeConfig config, String nodeIdString, DataBroker dataBroker) { - InstanceIdentifier ofOverlayNodeIid = InstanceIdentifier.builder( - Nodes.class) - .child(Node.class, new NodeKey(new NodeId(nodeIdString))) - .augmentation(OfOverlayNodeConfig.class) - .build(); - - WriteTransaction transaction = dataBroker.newReadWriteTransaction(); - transaction.put(LogicalDatastoreType.CONFIGURATION, ofOverlayNodeIid, config, true); - submitToDs(transaction); - } - /** - * Update the {@link OfOverlayConfig} of an Inventory Node + * Update the {@link OfOverlayNodeConfig} of an Inventory Node * using the new tunnel state. * - * @param nodeIdString - * @param tunnels - * @param dataBroker + * @param ip the ipaddress + * @param nodeIdString the string representation of the inventory NodeId + * @param nodeConnectorIdString the string representation of the inventory NodeConnectorId + * @param tunnelType the tunnel type + * @param dataBroker the {@link DataBroker} */ - public static void updateOfOverlayConfig(IpAddress ip, String nodeIdString, - String nodeConnectorIdString, List tunnels, DataBroker dataBroker) { + public static void updateOfOverlayConfig(IpAddress ip, String nodeIdString, String nodeConnectorIdString, + AbstractTunnelType tunnelType, DataBroker dataBroker) { - if ((ip == null) || (nodeIdString == null) - || (nodeConnectorIdString == null)) { + if ((ip == null) || (nodeIdString == null) || (nodeConnectorIdString == null)) { LOG.debug("Can't update OfOverlay: requisite information not present"); return; } NodeConnectorId nodeConnectorId = new NodeConnectorId(nodeConnectorIdString); - List tunnelList = new ArrayList(); - List existingTunnels = new ArrayList(); + + + // Pull existing augmentation OfOverlayNodeConfig ofConfig = getOfOverlayConfig(nodeIdString, dataBroker); + + // If it exists, use it in new augmentation constructor, else new augmentation + OfOverlayNodeConfigBuilder ofOverlayNodeConfigBuilder; + Set existingTunnels = new HashSet(); if (ofConfig != null) { - existingTunnels = ofConfig.getTunnel(); + ofOverlayNodeConfigBuilder = new OfOverlayNodeConfigBuilder(ofConfig); + if (ofConfig.getTunnel() != null) { + existingTunnels.addAll(ofConfig.getTunnel()); + } + } else { + ofOverlayNodeConfigBuilder = new OfOverlayNodeConfigBuilder(); } + + // Determine if this is an update to existing tunnel of this type or a new tunnel boolean tunnelsUpdated = false; - for (AbstractTunnelType tunnelType: tunnels) { - boolean tunnelFound = false; - for (Tunnel currentTun: existingTunnels) { - if (tunnelType.getTunnelType().equals(currentTun.getTunnelType())) { - // tunnel update - TunnelBuilder tunnelBuilder = new TunnelBuilder(currentTun); - tunnelBuilder.setIp(ip); - tunnelBuilder.setPort(tunnelType.getPortNumber()); - tunnelBuilder.setNodeConnectorId(nodeConnectorId); - tunnelList.add(tunnelBuilder.build()); - tunnelFound = true; - tunnelsUpdated = true; - } - } - // new tunnel - if (tunnelFound == false) { - TunnelBuilder tunnelBuilder = new TunnelBuilder(); + TunnelBuilder tunnelBuilder = new TunnelBuilder(); + + boolean tunnelFound = false; + for (Tunnel currentTun : existingTunnels) { + if (tunnelType.getTunnelType().equals(currentTun.getTunnelType())) { + // tunnel update tunnelBuilder.setIp(ip); tunnelBuilder.setPort(tunnelType.getPortNumber()); tunnelBuilder.setNodeConnectorId(nodeConnectorId); tunnelBuilder.setTunnelType(tunnelType.getTunnelType()); - tunnelList.add(tunnelBuilder.build()); + tunnelFound = true; tunnelsUpdated = true; + break; + } + } + // new tunnel + if (tunnelFound == false) { + tunnelBuilder.setIp(ip); + tunnelBuilder.setPort(tunnelType.getPortNumber()); + tunnelBuilder.setNodeConnectorId(nodeConnectorId); + tunnelBuilder.setTunnelType(tunnelType.getTunnelType()); + tunnelsUpdated = true; + } + + // Nothing was updated, nothing to see here, move along... + if (tunnelsUpdated == false) { + return; + } + + existingTunnels.add(tunnelBuilder.build()); + + // Update the OfOverlayNodeConfig with the new tunnel information + if (!existingTunnels.isEmpty()) { + ofOverlayNodeConfigBuilder.setTunnel(new ArrayList(existingTunnels)); + } + OfOverlayNodeConfig newConfig = ofOverlayNodeConfigBuilder.build(); + if (addOfOverlayConfig(newConfig, new NodeId(nodeIdString), dataBroker)) { + LOG.trace("updateOfOverlayConfig - Added Tunnel: {} to Node: {} at NodeConnector: {}", + tunnelBuilder.build(), nodeIdString, nodeConnectorIdString); + } else { + LOG.error("updateOfOverlayConfig - could not write OfOverlayNodeConfig: {} to datastore.", newConfig); + } + } + + public static void removeTunnelsOfOverlayConfig(String nodeIdString, + List tunnels, + DataBroker dataBroker) { + + if (nodeIdString == null) { + LOG.debug("Can't update OfOverlay: requisite information not present"); + return; + } + List existingTunnels = new ArrayList<>(); + OfOverlayNodeConfig ofConfig = getOfOverlayConfig(nodeIdString, dataBroker); + if (ofConfig != null) { + existingTunnels = ofConfig.getTunnel(); + } + Set tunnelsToRemove = new HashSet<>(); + for (AbstractTunnelType tunnelType : tunnels) { + for (Tunnel currentTun : existingTunnels) { + if (tunnelType.getTunnelType().equals(currentTun.getTunnelType())) { + tunnelsToRemove.add(currentTun); + } } } - if (tunnelsUpdated == true) { - OfOverlayNodeConfigBuilder ofOverlayBuilder = null; - if (ofConfig == null) { - ofOverlayBuilder = new OfOverlayNodeConfigBuilder(); - } else { - ofOverlayBuilder = new OfOverlayNodeConfigBuilder(ofConfig); + + // runs only if some tunnels were really removed + if (existingTunnels.removeAll(tunnelsToRemove)) { + ReadWriteTransaction writeTx = dataBroker.newReadWriteTransaction(); + for (Tunnel tunnel : tunnelsToRemove) { + InstanceIdentifier tunnelIid = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(new NodeId(nodeIdString))) + .augmentation(OfOverlayNodeConfig.class) + .child(Tunnel.class, tunnel.getKey()) + .build(); + writeTx.delete(LogicalDatastoreType.CONFIGURATION, tunnelIid); + LOG.trace("Removing tunnel: {} from node {}",tunnel, nodeIdString); } - ofOverlayBuilder.setTunnel(tunnelList); - addOfOverlayAugmentation(ofOverlayBuilder.build(), nodeIdString, dataBroker); + submitToDs(writeTx); + } + } + + private static boolean addOfOverlayConfig(OfOverlayNodeConfig newConfig, NodeId nodeId, DataBroker dataBroker) { + ReadWriteTransaction writeTx = dataBroker.newReadWriteTransaction(); + InstanceIdentifier ofOverlayNodeIid = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(nodeId)) + .augmentation(OfOverlayNodeConfig.class) + .build(); + writeTx.put(LogicalDatastoreType.CONFIGURATION, ofOverlayNodeIid, newConfig, true); + LOG.trace("Adding tunnel: {} to node {}", newConfig, nodeId.getValue()); + return submitToDs(writeTx); + } + + private static boolean addTunnelsOfOverlayConfig(List tunnels, NodeId nodeId, DataBroker dataBroker) { + ReadWriteTransaction writeTx = dataBroker.newReadWriteTransaction(); + for (Tunnel tunnel : tunnels) { + InstanceIdentifier tunnelIid = InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(nodeId)) + .augmentation(OfOverlayNodeConfig.class) + .child(Tunnel.class, tunnel.getKey()) + .build(); + writeTx.put(LogicalDatastoreType.CONFIGURATION, tunnelIid, tunnel, true); + LOG.trace("Adding tunnel: {} to node {}",tunnel, nodeId.getValue()); } + return submitToDs(writeTx); } }