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=fb6951c90abc93c6d57ac3a7ed4cd08b90ac23ae;hpb=201ab8f7ca2a143122d43e35da679d1654a6e665;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 old mode 100644 new mode 100755 index fb6951c90..2cf2b78df --- 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 @@ -10,38 +10,40 @@ package org.opendaylight.groupbasedpolicy.neutron.ovsdb; 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 static org.opendaylight.groupbasedpolicy.neutron.ovsdb.NodeDataChangeListener.processNodeNotification; -import static org.opendaylight.groupbasedpolicy.neutron.ovsdb.NodeDataChangeListener.getProviderMapping; -import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; -import java.util.Map.Entry; - +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; @@ -52,17 +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 com.google.common.base.Optional; - -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); @@ -76,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); } @@ -93,42 +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()) { - if (iid instanceof OvsdbTerminationPointAugmentation) { - /* - * Remove the state from OfOverlay? - */ + @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; } } } @@ -171,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; @@ -179,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; } /* @@ -191,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(); @@ -234,15 +212,82 @@ 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. + * + * @param nodeId {@link NodeId} + * @param ovsdbTp {@link OvsdbTerminationPointAugmentation} + * @param ovsdbTpIid termination point's IID {@link InstanceIdentifier} + */ + private void processRemovedTp(NodeId nodeId, OvsdbTerminationPointAugmentation ovsdbTp, + InstanceIdentifier ovsdbTpIid) { + if (isTunnelPort(ovsdbTp, requiredTunnelTypes)) { + removeTunnelsOfOverlayConfig(nodeId.getValue(), requiredTunnelTypes, dataBroker); + } else { + deleteLocationForTp(ovsdbTp); + } + } + + /** + * Delete location on EP for given TP. + * + * @param ovsdbTp {@link OvsdbTerminationPointAugmentation} + */ + private void deleteLocationForTp(OvsdbTerminationPointAugmentation ovsdbTp) { + String externalId = getNeutronPortUuid(ovsdbTp); + if (externalId != null) { + EndpointKey epKey = getEpKeyFromNeutronMapper(new UniqueId(externalId), dataBroker); + if (epKey == null) { + LOG.debug("TerminationPoint {} with external ID {} is not in Neutron Map.", ovsdbTp, externalId); + return; + } + ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction(); + 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); + return; + } + updateEndpointRemoveLocation(ep, dataBroker.newReadWriteTransaction()); + } else { + LOG.debug("TerminationPoint {} has no external ID, not processing.", ovsdbTp); + } + } + /** * Check to see if the {@link OvsdbTerminationPointAugmentation} is also a Tunnel port that we * care about. * - * @param ovsdbTp - * @param requiredTunnelTypes + * @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)) { @@ -257,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) { @@ -279,10 +324,9 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A * Check to see if all tunnel ports are present, and if not, * create them. * - * @param tpIid - * @return + * @param nodeIid {@link InstanceIdentifier} */ - private void createTunnelPorts(InstanceIdentifier nodeIid, DataBroker dataBroker) { + private void createTunnelPorts(InstanceIdentifier nodeIid) { Node node = getTopologyNode(nodeIid, dataBroker); checkNotNull(node); @@ -308,7 +352,7 @@ public class TerminationPointDataChangeListener implements DataChangeListener, A break; } } - if (tunnelPresent == false) { + if (!tunnelPresent) { createTunnelPort(nodeIid, node, tunnelType, dataBroker); } } @@ -327,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();