From c999ab7e816888e23c80b816b77905769291a53b Mon Sep 17 00:00:00 2001 From: Vladimir Lavor Date: Wed, 30 Nov 2016 14:04:55 +0100 Subject: [PATCH] VppNodeManager improvements * Unused available netconf node cache removed * VppNodeWriter removed, status is written from manager * If node is connected but mountpoint is not available, such a node will not be considered ready Change-Id: If8381d9079e61742e7a580e0d0a41fc68bcf3002 Signed-off-by: Vladimir Lavor --- .../renderer/vpp/manager/VppNodeManager.java | 96 +++++++++-------- .../renderer/vpp/util/VppNodeWriter.java | 90 ---------------- .../renderer/vpp/util/VppNodeWriterTest.java | 101 ------------------ 3 files changed, 50 insertions(+), 237 deletions(-) delete mode 100644 renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppNodeWriter.java delete mode 100644 renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppNodeWriterTest.java diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java index cfd64a189..0859505ba 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java @@ -12,16 +12,20 @@ import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topolog import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connecting; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; - +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.CheckedFuture; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.MountPoint; import org.opendaylight.controller.md.sal.binding.api.MountPointService; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; -import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppNodeWriter; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory; +import org.opendaylight.groupbasedpolicy.util.DataStoreHelper; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeKey; @@ -39,31 +43,23 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; - public class VppNodeManager { private static final TopologyId TOPOLOGY_ID = new TopologyId("topology-netconf"); private static final Logger LOG = LoggerFactory.getLogger(VppNodeManager.class); - private static final Map, DataBroker> netconfNodeCache = new HashMap<>(); private static final String V3PO_CAPABILITY = "(urn:opendaylight:params:xml:ns:yang:v3po?revision=2016-12-14)v3po"; private static final String INTERFACES_CAPABILITY = "(urn:ietf:params:xml:ns:yang:ietf-interfaces?revision=2014-05-08)ietf-interfaces"; private static final NodeId CONTROLLER_CONFIG_NODE = new NodeId("controller-config"); private final DataBroker dataBroker; - private final MountPointService mountService; private final List requiredCapabilities; + private final MountPointService mountService; - public VppNodeManager(DataBroker dataBroker, BindingAwareBroker.ProviderContext session) { + public VppNodeManager(final DataBroker dataBroker, final BindingAwareBroker.ProviderContext session) { this.dataBroker = Preconditions.checkNotNull(dataBroker); - mountService = Preconditions.checkNotNull(session.getSALService(MountPointService.class)); + this.mountService = Preconditions.checkNotNull(session.getSALService(MountPointService.class)); requiredCapabilities = initializeRequiredCapabilities(); } - static DataBroker getDataBrokerFromCache(InstanceIdentifier iid) { - return netconfNodeCache.get(iid); // TODO read from DS - } - /** * Synchronizes nodes to DataStore based on their modification state which results in * create/update/remove of Node. @@ -125,38 +121,65 @@ public class VppNodeManager { } if (afterNodeStatus.equals(Connecting)) { resolveDisconnectedNode(node); - LOG.info("Node {} has been disconnected, removing from available nodes", node.getNodeId().getValue()); + LOG.info("Node {} is disconnected, removing from available nodes", node.getNodeId().getValue()); } } private void removeNode(Node node) { resolveDisconnectedNode(node); - LOG.info("Node {} has been removed", node.getNodeId().getValue()); + LOG.info("Node {} is removed", node.getNodeId().getValue()); } private void resolveConnectedNode(Node node, NetconfNode netconfNode) { InstanceIdentifier mountPointIid = getMountpointIid(node); - // Mountpoint iid == path in renderer-node RendererNode rendererNode = remapNode(mountPointIid); - VppNodeWriter vppNodeWriter = new VppNodeWriter(); - vppNodeWriter.cache(rendererNode); if (!isCapableNetconfDevice(node, netconfNode)) { LOG.warn("Node {} is not connected.", node.getNodeId().getValue()); return; } - vppNodeWriter.commitToDatastore(dataBroker); - DataBroker mountpoint = getNodeMountPoint(mountPointIid); - netconfNodeCache.put(mountPointIid, mountpoint); + final DataBroker mountpoint = getNodeMountPoint(mountPointIid); + if (mountpoint == null) { + LOG.warn("Mountpoint not available for node {}", node.getNodeId().getValue()); + return; + } + final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction(); + wTx.put(LogicalDatastoreType.OPERATIONAL, VppIidFactory.getRendererNodeIid(rendererNode), rendererNode, true); + DataStoreHelper.submitToDs(wTx); LOG.info("Node {} is capable and ready.", node.getNodeId().getValue()); } private void resolveDisconnectedNode(Node node) { InstanceIdentifier mountPointIid = getMountpointIid(node); RendererNode rendererNode = remapNode(mountPointIid); - VppNodeWriter vppNodeWriter = new VppNodeWriter(); - vppNodeWriter.cache(rendererNode); - vppNodeWriter.removeFromDatastore(dataBroker); - netconfNodeCache.remove(mountPointIid); + final WriteTransaction wTx = dataBroker.newWriteOnlyTransaction(); + wTx.delete(LogicalDatastoreType.OPERATIONAL, VppIidFactory.getRendererNodeIid(rendererNode)); + CheckedFuture submitFuture = wTx.submit(); + try { + submitFuture.checkedGet(); + } catch (TransactionCommitFailedException e) { + LOG.error("Write transaction failed to {}", e.getMessage()); + } catch (Exception e) { + LOG.error("Failed to .. {}", e.getMessage()); + } + } + + private DataBroker getNodeMountPoint(InstanceIdentifier mountPointIid) { + Optional optionalObject = mountService.getMountPoint(mountPointIid); + MountPoint mountPoint; + if (optionalObject.isPresent()) { + mountPoint = optionalObject.get(); + if (mountPoint != null) { + Optional optionalDataBroker = mountPoint.getService(DataBroker.class); + if (optionalDataBroker.isPresent()) { + return optionalDataBroker.get(); + } else { + LOG.warn("Cannot obtain data broker from mountpoint {}", mountPoint); + } + } else { + LOG.warn("Cannot obtain mountpoint with IID {}", mountPointIid); + } + } + return null; } private RendererNode remapNode(InstanceIdentifier path) { @@ -194,25 +217,6 @@ public class VppNodeManager { .allMatch(availableCapabilities::contains); } - private DataBroker getNodeMountPoint(InstanceIdentifier mountPointIid) { - Optional optionalObject = mountService.getMountPoint(mountPointIid); - MountPoint mountPoint; - if (optionalObject.isPresent()) { - mountPoint = optionalObject.get(); - if (mountPoint != null) { - Optional optionalDataBroker = mountPoint.getService(DataBroker.class); - if (optionalDataBroker.isPresent()) { - return optionalDataBroker.get(); - } else { - LOG.debug("Cannot obtain data broker from mountpoint {}", mountPoint); - } - } else { - LOG.debug("Cannot obtain mountpoint with IID {}", mountPointIid); - } - } - return null; - } - private NetconfNode getNodeAugmentation(Node node) { NetconfNode netconfNode = node.getAugmentation(NetconfNode.class); if (netconfNode == null) { diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppNodeWriter.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppNodeWriter.java deleted file mode 100644 index 1e65549ac..000000000 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppNodeWriter.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016 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, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.groupbasedpolicy.renderer.vpp.util; - -import java.util.ArrayList; -import java.util.List; - -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodesBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.util.concurrent.CheckedFuture; - -public class VppNodeWriter { - - private static final Logger LOG = LoggerFactory.getLogger(VppNodeWriter.class); - private List rendererNodesCache; - - public VppNodeWriter() { - rendererNodesCache = new ArrayList<>(); - } - - public void cache(RendererNode node) { - rendererNodesCache.add(node); - } - - /** - * Put all cached items to data store. - * - * @param dataBroker appropriate data provider - */ - public void commitToDatastore(DataBroker dataBroker) { - RendererNodes rendererNodes = buildRendererNodes(); - WriteTransaction wtx = dataBroker.newWriteOnlyTransaction(); - InstanceIdentifier iid = VppIidFactory.getRendererNodesIid(); - try { - wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, rendererNodes, true); - CheckedFuture submitFuture = wtx.submit(); - submitFuture.checkedGet(); - // Clear cache - rendererNodesCache.clear(); - } catch (TransactionCommitFailedException e) { - LOG.error("Write transaction failed to {}", e.getMessage()); - } catch (Exception e) { - LOG.error("Failed to .. {}", e.getMessage()); - } - } - - /** - * Removes all cached items from data store. - * - * @param dataBroker appropriate data provider - */ - public void removeFromDatastore(DataBroker dataBroker) { - WriteTransaction wtx = dataBroker.newWriteOnlyTransaction(); - for (RendererNode nodeToRemove : rendererNodesCache) { - InstanceIdentifier iid = VppIidFactory.getRendererNodeIid(nodeToRemove); - try { - wtx.delete(LogicalDatastoreType.OPERATIONAL, iid); - CheckedFuture submitFuture = wtx.submit(); - submitFuture.checkedGet(); - // Clear cache - } catch (TransactionCommitFailedException e) { - LOG.error("Write transaction failed to {}", e.getMessage()); - } catch (Exception e) { - LOG.error("Failed to .. {}", e.getMessage()); - } - } - rendererNodesCache.clear(); - } - - private RendererNodes buildRendererNodes() { - RendererNodesBuilder rendererNodesBuilder = new RendererNodesBuilder(); - rendererNodesBuilder.setRendererNode(new ArrayList<>(rendererNodesCache)); - return rendererNodesBuilder.build(); - } -} diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppNodeWriterTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppNodeWriterTest.java deleted file mode 100644 index 72ea1dabe..000000000 --- a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppNodeWriterTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2016 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, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.groupbasedpolicy.renderer.vpp.util; - -import com.google.common.util.concurrent.Futures; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InOrder; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeBuilder; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Test for {@link VppNodeWriter}. - */ -@RunWith(MockitoJUnitRunner.class) -public class VppNodeWriterTest { - - private static final String RENDERER_NAME = "vpp-renderer"; - - @Mock - private DataBroker dataBroker; - @Mock - private WriteTransaction wTx; - @Captor - private ArgumentCaptor> rendererNodesPathCpt; - @Captor - private ArgumentCaptor rendererNodesCpt; - - private InOrder inOrder; - - private VppNodeWriter nodeWriter; - - @Before - public void setUp() throws Exception { - nodeWriter = new VppNodeWriter(); - Mockito.when(dataBroker.newWriteOnlyTransaction()).thenReturn(wTx); - Mockito.when(wTx.submit()).thenReturn(Futures.immediateCheckedFuture(null)); - } - - @After - public void tearDown() throws Exception { - inOrder.verifyNoMoreInteractions(); - } - - @Test - public void testCommitToDatastore_with_node() throws Exception { - final RendererNode node = new RendererNodeBuilder().build(); - nodeWriter.cache(node); - nodeWriter.commitToDatastore(dataBroker); - - commonChecks(); - - final RendererNodes rendererNodes = rendererNodesCpt.getValue(); - Assert.assertEquals(1, rendererNodes.getRendererNode().size()); - } - - @Test - public void testCommitToDatastore_empty() throws Exception { - nodeWriter.commitToDatastore(dataBroker); - - commonChecks(); - - final RendererNodes rendererNodes = rendererNodesCpt.getValue(); - Assert.assertEquals(0, rendererNodes.getRendererNode().size()); - } - - private void commonChecks() { - inOrder = Mockito.inOrder(dataBroker, wTx); - inOrder.verify(dataBroker).newWriteOnlyTransaction(); - inOrder.verify(wTx).merge(Matchers.eq(LogicalDatastoreType.OPERATIONAL), rendererNodesPathCpt.capture(), - rendererNodesCpt.capture(), Matchers.eq(true)); - inOrder.verify(wTx).submit(); - - final InstanceIdentifier rendererNodesPath = rendererNodesPathCpt.getValue(); - Assert.assertEquals(RENDERER_NAME, extractRendererName(rendererNodesPath)); - } - - private String extractRendererName(final InstanceIdentifier rendererNodesPath) { - return rendererNodesPath.firstKeyOf(Renderer.class).getName().getValue(); - } -} -- 2.36.6