From 70762f11bb7afd997bdb525c7d3b9d17481af65b Mon Sep 17 00:00:00 2001 From: Tomas Cechvala Date: Thu, 10 Nov 2016 15:38:54 +0100 Subject: [PATCH] Hostconfig for Openstack in VPP renderer Different underlay technologies may be used in multinode environment (ovs, vpp, etc.) Configuration for hosts on a particular node may be passed to Openstack by using hostconfigs feature. If GBP discoveres a VPP capable node, neutron-vpp-mapper (if installed) will react to this by exposing a config specific for the node into /restconf/operational/neutron:neutron/hostconfigs On the Openstack side, pseudo-agent-binding port binding controller (networking-odl) will periodically scan the datatree mentioned above and if it finds data, it will update agent database (neutron) with them. Later on, if someone is going to boot nova instance, nova will bind the port in such a way as the configuration in agent DB for the given node tells it. E.g. if vif_type is 'ovs', a port will be created and bound to OVS. If it's 'vhostuser' nova will bind the port to a vhostuser socket (which path is also specified in the config) How to enable hostconfig feature in Devstack/Openstack: modify ml2.conf by adding the following lines: port_binding_controller=pseudo-agentdb-binding ODL_HOSTCONF_URI=restconf/operational/neutron:neutron/hostconfigs URL= Change-Id: I43dd10a4dc0d7bb62ab3c9f0c6b100718b528cad Signed-off-by: Tomas Cechvala --- .../neutron/vpp/mapper/NeutronVppMapper.java | 4 + .../neutron/vpp/mapper/SocketInfo.java | 5 + .../mapper/hostconfigs/VppNodeListener.java | 102 ++++++++++++++++++ .../vpp/mapper/util/HostconfigUtil.java | 72 +++++++++++++ .../vpp/mapper/hostconfigs/TestResources.java | 101 +++++++++++++++++ .../hostconfigs/VppNodeListenerTest.java | 57 ++++++++++ .../vpp/mapper/util/HostconfigUtilTest.java | 36 +++++++ 7 files changed, 377 insertions(+) create mode 100644 neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/VppNodeListener.java create mode 100644 neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/util/HostconfigUtil.java create mode 100644 neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/TestResources.java create mode 100644 neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/VppNodeListenerTest.java create mode 100644 neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/util/HostconfigUtilTest.java diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/NeutronVppMapper.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/NeutronVppMapper.java index e1b17f1a9..994778564 100644 --- a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/NeutronVppMapper.java +++ b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/NeutronVppMapper.java @@ -9,6 +9,7 @@ package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.hostconfigs.VppNodeListener; import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors.NeutronListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,10 +17,12 @@ import org.slf4j.LoggerFactory; public class NeutronVppMapper implements AutoCloseable { NeutronListener neutronListener; + VppNodeListener vppNodeListener; private static final Logger LOG = LoggerFactory.getLogger(NeutronVppMapper.class); public NeutronVppMapper(String socketPath, String socketPrefix, DataBroker dataBroker) { SocketInfo socketInfo = new SocketInfo(socketPath, socketPrefix); + vppNodeListener = new VppNodeListener(dataBroker, socketInfo); neutronListener = new NeutronListener(dataBroker, socketInfo); LOG.info("Neutron VPP started!"); } @@ -27,5 +30,6 @@ public class NeutronVppMapper implements AutoCloseable { @Override public void close() { neutronListener.close(); + vppNodeListener.close(); } } diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/SocketInfo.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/SocketInfo.java index 3c0706031..c98a07c15 100644 --- a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/SocketInfo.java +++ b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/SocketInfo.java @@ -12,6 +12,7 @@ public class SocketInfo { private String socketPath; private String socketPrefix; + private final String PORT_ID = "$PORT_ID"; public SocketInfo(String socketPath, String socketPrefix) { this.socketPath = socketPath; @@ -26,6 +27,10 @@ public class SocketInfo { return socketPrefix; } + public String getVhostUserSocket() { + return new StringBuilder().append(socketPath).append(socketPrefix).append(PORT_ID).toString(); + } + @Override public int hashCode() { final int prime = 31; diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/VppNodeListener.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/VppNodeListener.java new file mode 100644 index 000000000..39b3a85d3 --- /dev/null +++ b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/VppNodeListener.java @@ -0,0 +1,102 @@ +/* + * 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.neutron.vpp.mapper.hostconfigs; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; +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.vpp.mapper.SocketInfo; +import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.util.HostconfigUtil; +import org.opendaylight.groupbasedpolicy.util.DataStoreHelper; +import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers; +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.RendererKey; +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.neutron.hostconfig.rev150712.hostconfig.attributes.Hostconfigs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.Hostconfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.HostconfigKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +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.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VppNodeListener extends DataTreeChangeHandler { + + private static final Logger LOG = LoggerFactory.getLogger(VppNodeListener.class); + + private SocketInfo socketInfo; + public static final RendererName VPP_RENDERER_NAME = new RendererName("vpp-renderer"); + + public VppNodeListener(DataBroker dataBroker, SocketInfo socketInfo) { + super(dataBroker); + this.socketInfo = socketInfo; + registerDataTreeChangeListener(new DataTreeIdentifier<>( + LogicalDatastoreType.OPERATIONAL, getVppNodeWildcardIid())); + } + + private InstanceIdentifier getVppNodeWildcardIid() { + return InstanceIdentifier.builder(Renderers.class) + .child(Renderer.class, new RendererKey(VPP_RENDERER_NAME)) + .child(RendererNodes.class) + .child(RendererNode.class) + .build(); + } + + @Override + protected void onWrite(DataObjectModification rootNode, + InstanceIdentifier rootIdentifier) { + writeData(rootNode.getDataAfter()); + } + + @Override + protected void onDelete(DataObjectModification rootNode, + InstanceIdentifier rootIdentifier) { + deleteData(rootNode.getDataBefore()); + } + + @Override + protected void onSubtreeModified(DataObjectModification rootNode, + InstanceIdentifier rootIdentifier) { + deleteData(rootNode.getDataAfter()); + writeData(rootNode.getDataBefore()); + } + + private void writeData(RendererNode rendererNode) { + NodeKey nodeKey = rendererNode.getNodePath().firstKeyOf(Node.class); + WriteTransaction wTx = dataProvider.newWriteOnlyTransaction(); + Hostconfig hcData = HostconfigUtil.createHostconfigsDataFor(nodeKey.getNodeId(), socketInfo); + wTx.put(LogicalDatastoreType.OPERATIONAL, hostconfigIid(nodeKey.getNodeId()), hcData); + DataStoreHelper.submitToDs(wTx); + LOG.info("Hostconfig data written to DS for VPP node {}", nodeKey); + } + + private InstanceIdentifier hostconfigIid(NodeId nodeId) { + return InstanceIdentifier.builder(Neutron.class) + .child(Hostconfigs.class) + .child(Hostconfig.class, new HostconfigKey(nodeId.getValue(), HostconfigUtil.L2_HOST_TYPE)) + .build(); + } + + private void deleteData(RendererNode rendererNode) { + NodeKey nodeKey = rendererNode.getNodePath().firstKeyOf(Node.class); + ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction(); + DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, hostconfigIid(nodeKey.getNodeId()), rwTx); + DataStoreHelper.submitToDs(rwTx); + LOG.info("Hostconfig data removed from DS for VPP node {}", nodeKey); + } +} diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/util/HostconfigUtil.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/util/HostconfigUtil.java new file mode 100644 index 000000000..487c9c756 --- /dev/null +++ b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/util/HostconfigUtil.java @@ -0,0 +1,72 @@ +/* + * 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.neutron.vpp.mapper.util; + +import java.util.List; + +import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.SocketInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.Hostconfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.HostconfigBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + + +public class HostconfigUtil { + + public static final String L2_HOST_TYPE = "ODL L2"; + private static final String VHOST_USER = "vhostuser"; + private static final String VNIC_TYPE = "normal"; + private static final String HAS_DATAPATH_TYPE_NETDEV = "False"; + private static final String SUPPORT_VHOST_USER = "True"; + private static final String VHOSTUSER_MODE = "server"; + private static final List supportedNetworkTypes = Lists.newArrayList("local", "vlan", "vxlan", "gre"); + + public static Hostconfig createHostconfigsDataFor(NodeId nodeId, SocketInfo socketInfo) { + Preconditions.checkNotNull(nodeId); + Preconditions.checkNotNull(socketInfo); + JsonObject odlL2 = new JsonObject(); + odlL2.add("allowed_network_types", buildSupportedNetworkTypes()); + odlL2.add("supported_vnic_types", buildSupportedVnicTypes(socketInfo)); + return new HostconfigBuilder().setHostId(nodeId.getValue()) + .setHostType(L2_HOST_TYPE) + .setConfig(odlL2.toString()) + .build(); + } + + private static JsonArray buildSupportedNetworkTypes() { + JsonArray networkTypes = new JsonArray(); + supportedNetworkTypes.forEach(networkTypes::add); + return networkTypes; + } + + private static JsonArray buildSupportedVnicTypes(SocketInfo socketInfo) { + JsonArray supportedVnicTypes = new JsonArray(); + JsonObject supportedVnicType = new JsonObject(); + supportedVnicType.addProperty("vnic_type", VNIC_TYPE); + supportedVnicType.addProperty("vif_type", VHOST_USER); + supportedVnicType.add("vif_details", buildVifDetails(socketInfo)); + supportedVnicTypes.add(supportedVnicType); + return supportedVnicTypes; + } + + private static JsonObject buildVifDetails(SocketInfo socketInfo) { + JsonObject vifDetails = new JsonObject(); + vifDetails.addProperty("has_datapath_type_netdev", HAS_DATAPATH_TYPE_NETDEV); + vifDetails.addProperty("support_vhost_user", SUPPORT_VHOST_USER); + vifDetails.addProperty("port_prefix", socketInfo.getSocketPrefix()); + vifDetails.addProperty("vhostuser_socket_dir", socketInfo.getSocketPath()); + vifDetails.addProperty("vhostuser_mode", VHOSTUSER_MODE); + vifDetails.addProperty("vhostuser_socket", socketInfo.getVhostUserSocket()); + return vifDetails; + } +} diff --git a/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/TestResources.java b/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/TestResources.java new file mode 100644 index 000000000..50c8be8b9 --- /dev/null +++ b/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/TestResources.java @@ -0,0 +1,101 @@ +/* + * 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.neutron.vpp.mapper.hostconfigs; + +import java.util.concurrent.ExecutionException; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.util.HostconfigUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers; +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.RendererKey; +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.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.Hostconfigs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.Hostconfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.HostconfigKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +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.NodeBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +import com.google.common.base.Optional; + +public class TestResources extends AbstractDataBrokerTest { + + protected DataBroker dataBroker; + + void setDataBroker() { + this.dataBroker = getDataBroker(); + } + + void writeTopologyNode(TopologyId topologyId, NodeId nodeId) throws InterruptedException, ExecutionException { + WriteTransaction wTx = dataBroker.newWriteOnlyTransaction(); + wTx.put(LogicalDatastoreType.CONFIGURATION, createNodeIid(topologyId, nodeId), new NodeBuilder().setNodeId(nodeId).build(), true); + wTx.submit().get(); + } + + void writeRendererNode(InstanceIdentifier nodeIid) throws InterruptedException, + ExecutionException { + InstanceIdentifier rendererNodeIid = createRendererNodeIid(nodeIid); + RendererNode rendererNode = new RendererNodeBuilder().setNodePath(nodeIid).build(); + WriteTransaction wTx = dataBroker.newWriteOnlyTransaction(); + wTx.put(LogicalDatastoreType.OPERATIONAL, rendererNodeIid, rendererNode, true); + wTx.submit().get(); + } + + void deleteRendererNode(InstanceIdentifier nodeIid) throws InterruptedException, ExecutionException { + InstanceIdentifier rendererNodeIid = createRendererNodeIid(nodeIid); + WriteTransaction wTx = dataBroker.newWriteOnlyTransaction(); + wTx.delete(LogicalDatastoreType.OPERATIONAL, rendererNodeIid); + wTx.submit().get(); + } + + Optional readHostconfig(NodeId nodeId) throws InterruptedException, ExecutionException { + ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction(); + Optional opt = rTx.read(LogicalDatastoreType.OPERATIONAL, createHostconfigWildcardNodeIid(nodeId)) + .get(); + rTx.close(); + return opt; + } + + static InstanceIdentifier createNodeIid(TopologyId topologyId, NodeId nodeId) { + return InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(topologyId)) + .child(Node.class, new NodeKey(nodeId)) + .build(); + } + + InstanceIdentifier createRendererNodeIid(InstanceIdentifier nodeIid) { + return InstanceIdentifier.builder(Renderers.class) + .child(Renderer.class, new RendererKey(VppNodeListener.VPP_RENDERER_NAME)) + .child(RendererNodes.class) + .child(RendererNode.class, new RendererNodeKey(nodeIid)) + .build(); + } + + InstanceIdentifier createHostconfigWildcardNodeIid(NodeId nodeId) { + return InstanceIdentifier.builder(Neutron.class) + .child(Hostconfigs.class) + .child(Hostconfig.class, new HostconfigKey(nodeId.getValue(), HostconfigUtil.L2_HOST_TYPE)) + .build(); + } +} diff --git a/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/VppNodeListenerTest.java b/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/VppNodeListenerTest.java new file mode 100644 index 000000000..12c1ec9f2 --- /dev/null +++ b/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/hostconfigs/VppNodeListenerTest.java @@ -0,0 +1,57 @@ +/* + * 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.neutron.vpp.mapper.hostconfigs; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.concurrent.ExecutionException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.SocketInfo; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class VppNodeListenerTest extends TestResources { + + private TopologyId topologyId = new TopologyId("topology1"); + private NodeId nodeId = new NodeId("node1"); + private InstanceIdentifier nodeIid = createNodeIid(topologyId, nodeId); + private VppNodeListener vppNodeListener; + + @Before + public void init() throws InterruptedException, ExecutionException { + String socketPath = "/tmp/"; + String socketPrefix = "socket_"; + setDataBroker(); + vppNodeListener = new VppNodeListener(dataBroker, new SocketInfo(socketPath, socketPrefix)); + writeTopologyNode(topologyId, nodeId); + writeRendererNode(createNodeIid(topologyId, nodeId)); + } + + @Test + public void writeDataTest() throws InterruptedException, ExecutionException { + assertTrue(readHostconfig(nodeId).isPresent()); + } + + @Test + public void deleteDataTest() throws InterruptedException, ExecutionException { + deleteRendererNode(nodeIid); + assertFalse(readHostconfig(nodeId).isPresent()); + } + + @After + public void after() { + vppNodeListener.close(); + } +} diff --git a/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/util/HostconfigUtilTest.java b/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/util/HostconfigUtilTest.java new file mode 100644 index 000000000..dc32d35cf --- /dev/null +++ b/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/util/HostconfigUtilTest.java @@ -0,0 +1,36 @@ +/* + * 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.neutron.vpp.mapper.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.SocketInfo; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.hostconfig.rev150712.hostconfig.attributes.hostconfigs.Hostconfig; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; + + +public class HostconfigUtilTest { + + private final NodeId NODE_ID = new NodeId("node1"); + private final String HOST_TYPE = "ODL L2"; + private final String PATH = "/tmp/"; + private final String PREFIX = "socket_"; + private final String VHOSTUSER = "vhostuser"; + + @Test + public void createHostconfigsDataForTest() { + Hostconfig hc = HostconfigUtil.createHostconfigsDataFor(NODE_ID, new SocketInfo(PATH, PREFIX)); + assertEquals(hc.getHostId(), NODE_ID.getValue()); + assertEquals(hc.getHostType(), HOST_TYPE); + assertTrue(hc.getConfig().contains(PATH)); + assertTrue(hc.getConfig().contains(VHOSTUSER)); + } +} -- 2.36.6