Search in sources :

Example 1 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project netvirt by opendaylight.

the class NodeConnectedHandler method handleNodeConnected.

/**
 * Takes care of merging the data when a node gets connected.
 * When a ha child node gets connected , we perform the following.
 * Merge the ha parent config data to child node.
 * Merge the ha parent physical node config data to child physical node.
 * Merge the child operational data to parent operational data.
 * Merge the child physical switch node operational data to parent physical switch operational node .
 *
 * @param childNode   Ha child node
 * @param childNodePath Ha child Iid
 * @param haNodePath  Ha Iid
 * @param haGlobalCfg Ha Global Config Node
 * @param haPSCfg Ha Physical Config Node
 * @param tx Transaction
 * @throws ReadFailedException  Exception thrown if read fails
 */
public void handleNodeConnected(Node childNode, InstanceIdentifier<Node> childNodePath, InstanceIdentifier<Node> haNodePath, Optional<Node> haGlobalCfg, Optional<Node> haPSCfg, ReadWriteTransaction tx) throws ReadFailedException {
    HwvtepHAUtil.buildGlobalConfigForHANode(tx, childNode, haNodePath, haGlobalCfg);
    copyChildOpToHA(childNode, haNodePath, tx);
    readAndCopyChildPSOpToHAPS(childNode, haNodePath, tx);
    if (haGlobalCfg.isPresent()) {
        // copy ha config to newly connected child case of reconnected child
        if (haPSCfg.isPresent()) {
            /*
                 copy task of physical switch node is done in the next transaction
                 The reason being if it is done in the same transaction,
                 hwvtep plugin is not able to proess this update and send vlanbindings to device
                 as it is expecting the logical switch to be already present in operational ds
                 (created in the device)
                 */
            HAJobScheduler.getInstance().submitJob(() -> {
                try {
                    hwvtepHACache.updateConnectedNodeStatus(childNodePath);
                    LOG.info("HA child reconnected handleNodeReConnected {}", childNode.getNodeId().getValue());
                    ReadWriteTransaction tx1 = db.newReadWriteTransaction();
                    copyHAPSConfigToChildPS(haPSCfg.get(), childNodePath, tx1);
                    tx1.submit().checkedGet();
                } catch (TransactionCommitFailedException e) {
                    LOG.error("Failed to process ", e);
                }
            });
        }
        copyHANodeConfigToChild(haGlobalCfg.get(), childNodePath, tx);
    }
    deleteChildPSConfigIfHAPSConfigIsMissing(haGlobalCfg, childNode, tx);
}
Also used : TransactionCommitFailedException(org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException) ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction)

Example 2 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project netvirt by opendaylight.

the class NodeCopier method copyPSNode.

@Override
public void copyPSNode(Optional<Node> srcPsNodeOptional, InstanceIdentifier<Node> srcPsPath, InstanceIdentifier<Node> dstPsPath, InstanceIdentifier<Node> dstGlobalPath, LogicalDatastoreType logicalDatastoreType, ReadWriteTransaction tx) throws ReadFailedException {
    if (!srcPsNodeOptional.isPresent() && logicalDatastoreType == CONFIGURATION) {
        Futures.addCallback(tx.read(logicalDatastoreType, srcPsPath), new FutureCallback<Optional<Node>>() {

            @Override
            public void onSuccess(Optional<Node> nodeOptional) {
                HAJobScheduler.getInstance().submitJob(() -> {
                    try {
                        ReadWriteTransaction tx1 = new BatchedTransaction();
                        if (nodeOptional.isPresent()) {
                            copyPSNode(nodeOptional, srcPsPath, dstPsPath, dstGlobalPath, logicalDatastoreType, tx1);
                        } else {
                            /**
                             * Deleting node please refer @see #copyGlobalNode for explanation
                             */
                            HwvtepHAUtil.deleteNodeIfPresent(tx1, logicalDatastoreType, dstPsPath);
                        }
                    } catch (ReadFailedException e) {
                        LOG.error("Failed to read src node {}", srcPsNodeOptional.get());
                    }
                });
            }

            @Override
            public void onFailure(Throwable throwable) {
            }
        });
        return;
    }
    NodeBuilder dstPsNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(dstPsPath);
    PhysicalSwitchAugmentationBuilder dstPsAugmentationBuilder = new PhysicalSwitchAugmentationBuilder();
    PhysicalSwitchAugmentation srcPsAugmenatation = srcPsNodeOptional.get().getAugmentation(PhysicalSwitchAugmentation.class);
    Node existingDstPsNode = HwvtepHAUtil.readNode(tx, logicalDatastoreType, dstPsPath);
    PhysicalSwitchAugmentation existingDstPsAugmentation = HwvtepHAUtil.getPhysicalSwitchAugmentationOfNode(existingDstPsNode);
    if (OPERATIONAL == logicalDatastoreType) {
        psAugmentationMerger.mergeOperationalData(dstPsAugmentationBuilder, existingDstPsAugmentation, srcPsAugmenatation, dstPsPath);
        psNodeMerger.mergeOperationalData(dstPsNodeBuilder, existingDstPsNode, srcPsNodeOptional.get(), dstPsPath);
    } else {
        psAugmentationMerger.mergeConfigData(dstPsAugmentationBuilder, srcPsAugmenatation, dstPsPath);
        psNodeMerger.mergeConfigData(dstPsNodeBuilder, srcPsNodeOptional.get(), dstPsPath);
    }
    mergeOpManagedByAttributes(srcPsAugmenatation, dstPsAugmentationBuilder, dstGlobalPath);
    dstPsNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, dstPsAugmentationBuilder.build());
    Node dstPsNode = dstPsNodeBuilder.build();
    tx.merge(logicalDatastoreType, dstPsPath, dstPsNode, true);
    LOG.debug("Copied {} physical switch node from {} to {}", logicalDatastoreType, srcPsPath, dstPsPath);
}
Also used : ReadFailedException(org.opendaylight.controller.md.sal.common.api.data.ReadFailedException) BatchedTransaction(org.opendaylight.netvirt.elan.l2gw.ha.BatchedTransaction) PhysicalSwitchAugmentationBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder) Optional(com.google.common.base.Optional) Node(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node) PhysicalSwitchAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation) ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) NodeBuilder(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder)

Example 3 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project netvirt by opendaylight.

the class NodeCopier method copyGlobalNode.

@Override
public void copyGlobalNode(Optional<Node> srcGlobalNodeOptional, InstanceIdentifier<Node> srcPath, InstanceIdentifier<Node> dstPath, LogicalDatastoreType logicalDatastoreType, ReadWriteTransaction tx) throws ReadFailedException {
    if (!srcGlobalNodeOptional.isPresent() && logicalDatastoreType == CONFIGURATION) {
        Futures.addCallback(tx.read(logicalDatastoreType, srcPath), new FutureCallback<Optional<Node>>() {

            @Override
            public void onSuccess(Optional<Node> nodeOptional) {
                HAJobScheduler.getInstance().submitJob(() -> {
                    try {
                        ReadWriteTransaction tx1 = new BatchedTransaction();
                        if (nodeOptional.isPresent()) {
                            copyGlobalNode(nodeOptional, srcPath, dstPath, logicalDatastoreType, tx1);
                        } else {
                            /**
                             * In case the Parent HA Global Node is not present and Child HA node is present
                             * It means that both the child are disconnected/removed hence the parent is deleted.
                             * @see org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpNodeListener
                             * OnGLobalNode() delete function
                             * So we should delete the existing config child node as cleanup
                             */
                            HwvtepHAUtil.deleteNodeIfPresent(tx1, logicalDatastoreType, dstPath);
                        }
                    } catch (ReadFailedException e) {
                        LOG.error("Failed to read source node {}", srcPath);
                    }
                });
            }

            @Override
            public void onFailure(Throwable throwable) {
            }
        });
        return;
    }
    HwvtepGlobalAugmentation srcGlobalAugmentation = srcGlobalNodeOptional.get().getAugmentation(HwvtepGlobalAugmentation.class);
    if (srcGlobalAugmentation == null) {
        /**
         * If Source HA Global Node is not present
         * It means that both the child are disconnected/removed hence the parent is deleted.
         * @see org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpNodeListener OnGLobalNode() delete function
         * So we should delete the existing config child node as cleanup
         */
        HwvtepHAUtil.deleteNodeIfPresent(tx, logicalDatastoreType, dstPath);
        return;
    }
    NodeBuilder haNodeBuilder = HwvtepHAUtil.getNodeBuilderForPath(dstPath);
    HwvtepGlobalAugmentationBuilder haBuilder = new HwvtepGlobalAugmentationBuilder();
    Optional<Node> existingDstGlobalNodeOptional = tx.read(logicalDatastoreType, dstPath).checkedGet();
    Node existingDstGlobalNode = existingDstGlobalNodeOptional.isPresent() ? existingDstGlobalNodeOptional.get() : null;
    HwvtepGlobalAugmentation existingHAGlobalData = HwvtepHAUtil.getGlobalAugmentationOfNode(existingDstGlobalNode);
    globalAugmentationMerger.mergeOperationalData(haBuilder, existingHAGlobalData, srcGlobalAugmentation, dstPath);
    globalNodeMerger.mergeOperationalData(haNodeBuilder, existingDstGlobalNode, srcGlobalNodeOptional.get(), dstPath);
    if (OPERATIONAL == logicalDatastoreType) {
        haBuilder.setManagers(HwvtepHAUtil.buildManagersForHANode(srcGlobalNodeOptional.get(), existingDstGlobalNodeOptional));
        // Also update the manager section in config which helps in cluster reboot scenarios
        haBuilder.getManagers().stream().forEach((manager) -> {
            InstanceIdentifier<Managers> managerIid = dstPath.augmentation(HwvtepGlobalAugmentation.class).child(Managers.class, manager.getKey());
            tx.put(CONFIGURATION, managerIid, manager, true);
        });
    }
    haBuilder.setDbVersion(srcGlobalAugmentation.getDbVersion());
    haNodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, haBuilder.build());
    Node haNode = haNodeBuilder.build();
    if (OPERATIONAL == logicalDatastoreType) {
        tx.merge(logicalDatastoreType, dstPath, haNode, true);
    } else {
        tx.put(logicalDatastoreType, dstPath, haNode, true);
    }
}
Also used : ReadFailedException(org.opendaylight.controller.md.sal.common.api.data.ReadFailedException) BatchedTransaction(org.opendaylight.netvirt.elan.l2gw.ha.BatchedTransaction) Optional(com.google.common.base.Optional) Node(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node) HwvtepGlobalAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation) NodeBuilder(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder) HwvtepGlobalAugmentationBuilder(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder) Managers(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Managers) ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction)

Example 4 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project netvirt by opendaylight.

the class MergeCommandsAggregator method mergeUpdate.

public void mergeUpdate(InstanceIdentifier<Node> dstPath, DataObjectModification mod, LogicalDatastoreType datastoreType, ReadWriteTransaction tx) {
    if (mod == null) {
        return;
    }
    Collection<DataObjectModification> modifications = mod.getModifiedChildren();
    modifications.stream().filter(modification -> skipCopy.negate().test(datastoreType, modification.getDataType())).filter(modification -> commands.get(modification.getDataType()) != null).peek(modification -> LOG.debug("Received {} modification {} copy/delete to {}", datastoreType, modification, dstPath)).forEach(modification -> {
        MergeCommand mergeCommand = commands.get(modification.getDataType());
        boolean create = modification.getDataAfter() != null;
        DataObject data = create ? modification.getDataAfter() : modification.getDataBefore();
        InstanceIdentifier<DataObject> transformedId = mergeCommand.generateId(dstPath, data);
        DataObject transformedItem = mergeCommand.transform(dstPath, data);
        Optional<DataObject> existingDataOptional = null;
        try {
            existingDataOptional = tx.read(datastoreType, transformedId).checkedGet();
        } catch (ReadFailedException ex) {
            LOG.error("Failed to read data {} from {}", transformedId, datastoreType);
            return;
        }
        String destination = datastoreType == CONFIGURATION ? "child" : "parent";
        if (create) {
            if (isDataUpdated(existingDataOptional, transformedItem)) {
                LOG.debug("Copy to {} {} {}", destination, datastoreType, transformedId);
                tx.put(datastoreType, transformedId, transformedItem, true);
            } else {
                LOG.debug("Data not updated skip copy to {}", transformedId);
            }
        } else {
            if (existingDataOptional.isPresent()) {
                LOG.debug("Delete from {} {} {}", destination, datastoreType, transformedId);
                tx.delete(datastoreType, transformedId);
            } else {
                LOG.debug("Delete skipped for {}", transformedId);
            }
        }
    });
}
Also used : Logger(org.slf4j.Logger) Node(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node) Collection(java.util.Collection) LogicalDatastoreType(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType) LoggerFactory(org.slf4j.LoggerFactory) CONFIGURATION(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION) HashMap(java.util.HashMap) SuperTypeUtil(org.opendaylight.genius.utils.SuperTypeUtil) LocalUcastCmd(org.opendaylight.netvirt.elan.l2gw.ha.commands.LocalUcastCmd) RemoteUcastCmd(org.opendaylight.netvirt.elan.l2gw.ha.commands.RemoteUcastCmd) OPERATIONAL(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL) MergeCommand(org.opendaylight.netvirt.elan.l2gw.ha.commands.MergeCommand) Objects(java.util.Objects) BiPredicate(java.util.function.BiPredicate) InstanceIdentifier(org.opendaylight.yangtools.yang.binding.InstanceIdentifier) Optional(com.google.common.base.Optional) ReadFailedException(org.opendaylight.controller.md.sal.common.api.data.ReadFailedException) Map(java.util.Map) DataObjectModification(org.opendaylight.controller.md.sal.binding.api.DataObjectModification) Builder(org.opendaylight.yangtools.concepts.Builder) DataObject(org.opendaylight.yangtools.yang.binding.DataObject) ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) ReadFailedException(org.opendaylight.controller.md.sal.common.api.data.ReadFailedException) DataObject(org.opendaylight.yangtools.yang.binding.DataObject) DataObjectModification(org.opendaylight.controller.md.sal.binding.api.DataObjectModification) MergeCommand(org.opendaylight.netvirt.elan.l2gw.ha.commands.MergeCommand)

Example 5 with ReadWriteTransaction

use of org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction in project netvirt by opendaylight.

the class HAOpNodeListener method readAndCopyChildPsOpToParent.

private void readAndCopyChildPsOpToParent(Node childNode, ReadWriteTransaction tx) {
    String childGlobalNodeId = childNode.getNodeId().getValue();
    List<InstanceIdentifier> childPsIids = new ArrayList<>();
    HwvtepGlobalAugmentation hwvtepGlobalAugmentation = childNode.getAugmentation(HwvtepGlobalAugmentation.class);
    if (hwvtepGlobalAugmentation == null || HwvtepHAUtil.isEmpty(hwvtepGlobalAugmentation.getSwitches())) {
        haOpClusteredListener.getConnectedNodes().stream().filter((connectedIid) -> IS_PS_CHILD_TO_GLOBAL_NODE.test(childGlobalNodeId, connectedIid)).forEach((connectedIid) -> childPsIids.add(connectedIid));
    } else {
        hwvtepGlobalAugmentation.getSwitches().forEach((switches) -> childPsIids.add(switches.getSwitchRef().getValue()));
    }
    if (childPsIids.isEmpty()) {
        LOG.info("No child ps found for global {}", childGlobalNodeId);
    }
    childPsIids.forEach((psIid) -> {
        try {
            InstanceIdentifier<Node> childPsIid = psIid;
            Optional<Node> childPsNode = tx.read(LogicalDatastoreType.OPERATIONAL, childPsIid).checkedGet();
            if (childPsNode.isPresent()) {
                LOG.debug("Child oper PS node found");
                onPsNodeAdd(childPsIid, childPsNode.get(), tx);
            } else {
                LOG.debug("Child oper ps node not found {}", childPsIid);
            }
        } catch (ReadFailedException e) {
            LOG.error("Failed to read child ps node {}", psIid);
        }
    });
}
Also used : IHAEventHandler(org.opendaylight.netvirt.elan.l2gw.ha.handlers.IHAEventHandler) HAEventHandler(org.opendaylight.netvirt.elan.l2gw.ha.handlers.HAEventHandler) LoggerFactory(org.slf4j.LoggerFactory) Singleton(javax.inject.Singleton) OPERATIONAL(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) Strings(com.google.common.base.Strings) BiPredicate(java.util.function.BiPredicate) HwvtepHAUtil(org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil) Optional(com.google.common.base.Optional) DataObjectModification(org.opendaylight.controller.md.sal.binding.api.DataObjectModification) NodeCopier(org.opendaylight.netvirt.elan.l2gw.ha.handlers.NodeCopier) Logger(org.slf4j.Logger) Node(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node) Predicate(java.util.function.Predicate) LogicalDatastoreType(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType) Set(java.util.Set) Collectors(java.util.stream.Collectors) DataBroker(org.opendaylight.controller.md.sal.binding.api.DataBroker) HwvtepGlobalAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation) List(java.util.List) InstanceIdentifier(org.opendaylight.yangtools.yang.binding.InstanceIdentifier) ReadFailedException(org.opendaylight.controller.md.sal.common.api.data.ReadFailedException) ReadWriteTransaction(org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction) ReadFailedException(org.opendaylight.controller.md.sal.common.api.data.ReadFailedException) Node(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node) ArrayList(java.util.ArrayList) HwvtepGlobalAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation) InstanceIdentifier(org.opendaylight.yangtools.yang.binding.InstanceIdentifier)

Aggregations

ReadWriteTransaction (org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction)67 Optional (com.google.common.base.Optional)21 TransactionCommitFailedException (org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException)17 Test (org.junit.Test)16 FlowCapableNode (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode)13 Node (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node)13 CountDownLatch (java.util.concurrent.CountDownLatch)11 Mockito.doReturn (org.mockito.Mockito.doReturn)11 Nodes (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes)11 InstanceIdentifier (org.opendaylight.yangtools.yang.binding.InstanceIdentifier)11 ReadFailedException (org.opendaylight.controller.md.sal.common.api.data.ReadFailedException)10 NodeId (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId)9 DataTreeModification (org.opendaylight.controller.md.sal.binding.api.DataTreeModification)8 TestUtils.newInvNodeKey (org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newInvNodeKey)8 NodeKey (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey)8 TestUtils.newLink (org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newLink)7 Link (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link)7 ArrayList (java.util.ArrayList)6 Flow (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow)6 NodeBuilder (org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder)6