X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=neutron-ovsdb%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fgroupbasedpolicy%2Fneutron%2Fovsdb%2FTerminationPointDataChangeListener.java;h=2cf2b78dfd96d2367b493c7c89e1109dc4e4e867;hb=e9b93945fe12111eb58baa076e4257a16a685037;hp=b8f6ce6afc979e0c0bc33a096ab61ee56af6a5cb;hpb=ced9c03f303c0e301e59437d6cd32f70ced14b1e;p=groupbasedpolicy.git diff --git a/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/TerminationPointDataChangeListener.java b/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/TerminationPointDataChangeListener.java index b8f6ce6af..2cf2b78df 100755 --- a/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/TerminationPointDataChangeListener.java +++ b/neutron-ovsdb/src/main/java/org/opendaylight/groupbasedpolicy/neutron/ovsdb/TerminationPointDataChangeListener.java @@ -8,20 +8,42 @@ package org.opendaylight.groupbasedpolicy.neutron.ovsdb; -import com.google.common.base.Optional; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.EndpointHelper.lookupEndpoint; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.EndpointHelper.updateEndpointRemoveLocation; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.EndpointHelper.updateEndpointWithLocation; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.checkOfOverlayConfig; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.getInventoryNodeConnectorIdString; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.getInventoryNodeIdString; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.removeTunnelsOfOverlayConfig; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.updateOfOverlayConfig; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.NeutronHelper.getEpKeyFromNeutronMapper; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.createTunnelPort; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getManagerNode; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getOvsdbBridgeFromTerminationPoint; +import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getTopologyNode; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener; +import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; +import org.opendaylight.controller.md.sal.binding.api.DataTreeModification; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.ovsdb.southbound.SouthboundConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Uuid; +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.common.rev140421.UniqueId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation; @@ -32,38 +54,15 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map.Entry; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.NodeDataChangeListener.getProviderMapping; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.NodeDataChangeListener.processNodeNotification; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.EndpointHelper.lookupEndpoint; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.EndpointHelper.updateEndpointRemoveLocation; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.EndpointHelper.updateEndpointWithLocation; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.checkOfOverlayConfig; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.getInventoryNodeConnectorIdString; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.getInventoryNodeIdString; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.removeTunnelsOfOverlayConfig; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.InventoryHelper.updateOfOverlayConfig; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.NeutronHelper.getEpKeyFromNeutronMapper; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.createTunnelPort; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getManagerNode; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getOvsdbBridgeFromTerminationPoint; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.util.OvsdbHelper.getTopologyNode; -import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs; - -public class TerminationPointDataChangeListener implements DataChangeListener, AutoCloseable { +public class TerminationPointDataChangeListener implements DataTreeChangeListener, + AutoCloseable { private static final String NEUTRON_EXTERNAL_ID_KEY = "iface-id"; - private final ListenerRegistration registration; + private final ListenerRegistration registration; private final DataBroker dataBroker; private final EndpointService epService; private static final Logger LOG = LoggerFactory.getLogger(TerminationPointDataChangeListener.class); @@ -77,15 +76,15 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A .child(Node.class) .child(TerminationPoint.class) .augmentation(OvsdbTerminationPointAugmentation.class); - registration = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid, this, - DataChangeScope.ONE); + registration = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>( + LogicalDatastoreType.OPERATIONAL, iid), this); requiredTunnelTypes = createSupportedTunnelsList(); } private List createSupportedTunnelsList() { - List required = new ArrayList(); - // required.add(new VxlanGpeTunnelType()); + List required = new ArrayList<>(); required.add(new VxlanTunnelType()); + required.add(new VxlanGpeTunnelType()); return Collections.unmodifiableList(required); } @@ -94,48 +93,36 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A registration.close(); } - @Override - public void onDataChanged(AsyncDataChangeEvent, DataObject> change) { - - /* - * TerminationPoint notifications with OVSDB augmentations - * vSwitch ports. Iterate through the list of new ports. - */ - for (Entry, DataObject> entry : change.getCreatedData().entrySet()) { - if (entry.getValue() instanceof OvsdbTerminationPointAugmentation) { - OvsdbTerminationPointAugmentation ovsdbTp = (OvsdbTerminationPointAugmentation) entry.getValue(); - InstanceIdentifier ovsdbTpIid = (InstanceIdentifier) entry.getKey(); - OvsdbBridgeAugmentation ovsdbBridge = getOvsdbBridgeFromTerminationPoint(ovsdbTpIid, dataBroker); - processOvsdbBridge(ovsdbBridge, ovsdbTp, ovsdbTpIid); - } - } - - /* - * Updates - */ - for (Entry, DataObject> entry : change.getUpdatedData().entrySet()) { - if (entry.getValue() instanceof OvsdbTerminationPointAugmentation) { - OvsdbTerminationPointAugmentation ovsdbTp = (OvsdbTerminationPointAugmentation) entry.getValue(); - InstanceIdentifier ovsdbTpIid = (InstanceIdentifier) entry.getKey(); - OvsdbBridgeAugmentation ovsdbBridge = getOvsdbBridgeFromTerminationPoint(ovsdbTpIid, dataBroker); - processOvsdbBridge(ovsdbBridge, ovsdbTp, ovsdbTpIid); - } - } + /* + * When vSwitch is deleted, we loose data in operational DS to determine Iid of + * corresponding NodeId. + */ + private static final Map, NodeId> NODE_ID_BY_TERMIN_POINT = + new HashMap<>(); - /* - * Deletions - */ - for (InstanceIdentifier iid : change.getRemovedPaths()) { - DataObject old = change.getOriginalData().get(iid); - if (old instanceof OvsdbTerminationPointAugmentation) { - OvsdbTerminationPointAugmentation ovsdbTp = (OvsdbTerminationPointAugmentation) old; - @SuppressWarnings("unchecked") - InstanceIdentifier ovsdbTpIid = - (InstanceIdentifier) iid; - OvsdbBridgeAugmentation ovsdbBridge = getOvsdbBridgeFromTerminationPoint(ovsdbTpIid, dataBroker); - if (ovsdbBridge != null) { - processRemovedTp(ovsdbBridge, ovsdbTp, ovsdbTpIid); - } + @Override + public void onDataTreeChanged(Collection> changes) { + for (DataTreeModification change: changes) { + DataObjectModification rootNode = change.getRootNode(); + InstanceIdentifier ovsdbTpIid = change.getRootPath().getRootIdentifier(); + OvsdbTerminationPointAugmentation origOvsdbTp = rootNode.getDataBefore(); + switch (rootNode.getModificationType()) { + case SUBTREE_MODIFIED: + case WRITE: + OvsdbTerminationPointAugmentation updatedOvsdbTp = rootNode.getDataAfter(); + OvsdbBridgeAugmentation ovsdbBridge = getOvsdbBridgeFromTerminationPoint(ovsdbTpIid, dataBroker); + if (origOvsdbTp == null) { + NODE_ID_BY_TERMIN_POINT.put(ovsdbTpIid, + new NodeId(getInventoryNodeIdString(ovsdbBridge, ovsdbTpIid, dataBroker))); + } + + processOvsdbBridge(ovsdbBridge, updatedOvsdbTp, ovsdbTpIid); + break; + case DELETE: + processRemovedTp(NODE_ID_BY_TERMIN_POINT.get(ovsdbTpIid), origOvsdbTp, ovsdbTpIid); + break; + default: + break; } } } @@ -178,7 +165,7 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A */ if (externalId != null) { - EndpointKey epKey = getEpKeyFromNeutronMapper(new Uuid(externalId), dataBroker); + EndpointKey epKey = getEpKeyFromNeutronMapper(new UniqueId(externalId), dataBroker); if (epKey == null) { LOG.debug("TerminationPoint {} with external ID {} is not in Neutron Map", ovsdbTp, externalId); return; @@ -186,9 +173,8 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A ReadOnlyTransaction transaction = dataBroker.newReadOnlyTransaction(); ep = lookupEndpoint(epKey, transaction); if (ep == null) { - LOG.warn( - "TerminationPoint {} with external ID {} is in Neutron Map, but corresponding Endpoint {} isn't in Endpoint Repository", - ovsdbTp, externalId, epKey); + LOG.warn("TerminationPoint {} with external ID {} is in Neutron Map, " + + "but corresponding Endpoint {} isn't in Endpoint Repository", ovsdbTp, externalId, epKey); return; } /* @@ -198,42 +184,27 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A * OfOverlay augmentation. If it hasn't, go see if the * tunnel ports exist, and if not, go and create them. */ - if (checkOfOverlayConfig(nodeIdString, requiredTunnelTypes, dataBroker) != true) { + if (!checkOfOverlayConfig(nodeIdString, requiredTunnelTypes, dataBroker)) { checkNotNull(nodeIid); /* * Check to see if we need to create a * tunnel port on the parent node */ - createTunnelPorts(nodeIid, dataBroker); + createTunnelPorts(nodeIid); } } else { LOG.debug("TerminationPoint {} had no external ID, not processing for external ID.", ovsdbTp); } - /* - * Check if Neutron External port was announed in Node before TerminationPoint it refers to - * was actually instantiated. This may or may not have external information in the future, hence - * not process as IF/ELSE externalID. - */ - ReadOnlyTransaction transaction = dataBroker.newReadOnlyTransaction(); - Optional node = readFromDs(LogicalDatastoreType.OPERATIONAL, nodeIid, transaction); - if (node.isPresent() - && node.get().getAugmentation(OvsdbNodeAugmentation.class) != null) { - OvsdbNodeAugmentation ovsdbNodeAug = node.get().getAugmentation(OvsdbNodeAugmentation.class); - if (getProviderMapping(ovsdbNodeAug) != null) { - processNodeNotification(ovsdbNodeAug); - - } - } else { - } /* * This may be a notification for a tunnel we just created. * In that case, we need to update the Inventory Node's OfOverlay * augmentation with missing information */ - if (isTunnelPort(ovsdbTp, requiredTunnelTypes)) { - updateOfOverlayConfig(hostIp, nodeIdString, nodeConnectorIdString, requiredTunnelTypes, dataBroker); + AbstractTunnelType tunnel = getTunnelType(ovsdbTp, requiredTunnelTypes); + if (tunnel != null) { + updateOfOverlayConfig(hostIp, nodeIdString, nodeConnectorIdString, tunnel, dataBroker); } if (externalId != null) { ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); @@ -243,43 +214,31 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A /** * If removed termination point was a tunnel port, - * removes attached tunnels (namely Vxlan-type) from OVSDB bridge; - * else removes location info from TP + * removes attached tunnels (namely Vxlan-type) from OVSDB bridge, + * else removes location info from TP. * - * @param ovsdbBridge {@link OvsdbBridgeAugmentation} + * @param nodeId {@link NodeId} * @param ovsdbTp {@link OvsdbTerminationPointAugmentation} * @param ovsdbTpIid termination point's IID {@link InstanceIdentifier} */ - private void processRemovedTp(OvsdbBridgeAugmentation ovsdbBridge, OvsdbTerminationPointAugmentation ovsdbTp, InstanceIdentifier ovsdbTpIid) { - - checkNotNull(ovsdbBridge); - if (ovsdbBridge.getBridgeName().getValue().equals(ovsdbTp.getName())) { - LOG.debug("Termination Point {} same as Bridge {}. Not processing.", ovsdbTp.getName(), ovsdbBridge.getBridgeName().getValue()); - return; - } - - String nodeIdString = getInventoryNodeIdString(ovsdbBridge, ovsdbTpIid, dataBroker); - if (nodeIdString == null) { - LOG.debug("nodeIdString for TerminationPoint {} was null.", ovsdbTp); - return; - } - + private void processRemovedTp(NodeId nodeId, OvsdbTerminationPointAugmentation ovsdbTp, + InstanceIdentifier ovsdbTpIid) { if (isTunnelPort(ovsdbTp, requiredTunnelTypes)) { - removeTunnelsOfOverlayConfig(nodeIdString, requiredTunnelTypes, dataBroker); + removeTunnelsOfOverlayConfig(nodeId.getValue(), requiredTunnelTypes, dataBroker); } else { deleteLocationForTp(ovsdbTp); } } /** - * Delete location on EP for given TP + * Delete location on EP for given TP. * * @param ovsdbTp {@link OvsdbTerminationPointAugmentation} */ - private void deleteLocationForTp(OvsdbTerminationPointAugmentation ovsdbTp){ + private void deleteLocationForTp(OvsdbTerminationPointAugmentation ovsdbTp) { String externalId = getNeutronPortUuid(ovsdbTp); if (externalId != null) { - EndpointKey epKey = getEpKeyFromNeutronMapper(new Uuid(externalId), dataBroker); + EndpointKey epKey = getEpKeyFromNeutronMapper(new UniqueId(externalId), dataBroker); if (epKey == null) { LOG.debug("TerminationPoint {} with external ID {} is not in Neutron Map.", ovsdbTp, externalId); return; @@ -288,7 +247,8 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A Endpoint ep = lookupEndpoint(epKey, readOnlyTransaction); readOnlyTransaction.close(); if (ep == null) { - LOG.warn("TerminationPoint {} with external ID {} is in Neutron Map, but corresponding Endpoint {} isn't in Endpoint Repository.", ovsdbTp, externalId, epKey); + LOG.warn("TerminationPoint {} with external ID {} is in Neutron Map," + + " but corresponding Endpoint {} isn't in Endpoint Repository.", ovsdbTp, externalId, epKey); return; } updateEndpointRemoveLocation(ep, dataBroker.newReadWriteTransaction()); @@ -298,14 +258,36 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A } /** + * Check to see if the {@link OvsdbTerminationPointAugmentation} is also a Tunnel port that we + * care about. + * + * @param ovsdbTp {@link OvsdbTerminationPointAugmentation} + * @param requiredTunnelTypes {@link List} of tunnel types + */ + private static AbstractTunnelType getTunnelType(OvsdbTerminationPointAugmentation ovsdbTp, + List requiredTunnelTypes) { + if (ovsdbTp.getInterfaceType() != null) { + for (AbstractTunnelType tunnelType : requiredTunnelTypes) { + if (tunnelType.isValidTunnelPort(ovsdbTp)) { + return tunnelType; + } + } + } + return null; + } + + /* * Check to see if the {@link OvsdbTerminationPointAugmentation} * is also a Tunnel port that we care about. * * @param ovsdbTp {@link OvsdbTerminationPointAugmentation} + * * @param requiredTunnelTypes {@link List} of tunnel types + * * @return true if it's a required tunnel port, false if it isn't */ - private boolean isTunnelPort(OvsdbTerminationPointAugmentation ovsdbTp, List requiredTunnelTypes) { + private static boolean isTunnelPort(OvsdbTerminationPointAugmentation ovsdbTp, + List requiredTunnelTypes) { if (ovsdbTp.getInterfaceType() != null) { for (AbstractTunnelType tunnelType : requiredTunnelTypes) { if (tunnelType.isValidTunnelPort(ovsdbTp)) { @@ -320,7 +302,7 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A * Get the Neutron Port UUID from an {@link OvsdbTerminationPointAugmentation}. * The Neutron Port UUID is stored as an "external-id" in the termination point. * - * @param ovsdbTp The OVSDB Termination Point augmentation + * @param ovsdbTp The {@link OvsdbTerminationPointAugmentation} * @return The String representation of the Neutron Port UUID, null if not present */ private String getNeutronPortUuid(OvsdbTerminationPointAugmentation ovsdbTp) { @@ -343,9 +325,8 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A * create them. * * @param nodeIid {@link InstanceIdentifier} - * @param dataBroker {@link DataBroker} */ - private void createTunnelPorts(InstanceIdentifier nodeIid, DataBroker dataBroker) { + private void createTunnelPorts(InstanceIdentifier nodeIid) { Node node = getTopologyNode(nodeIid, dataBroker); checkNotNull(node); @@ -390,8 +371,9 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A */ OvsdbNodeAugmentation managerNode = getManagerNode(ovsdbBridge, dataBroker); - if (managerNode == null) + if (managerNode == null) { return null; + } if (managerNode.getConnectionInfo() != null) { return managerNode.getConnectionInfo().getRemoteIp();