<version>${project.version}</version>
</dependency>
<!-- Testing Dependencies -->
- <dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
--- /dev/null
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.ovsdb.hwvtepsouthbound;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.junit.After;
+import org.junit.Before;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+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.clustering.EntityOwnershipService;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvoker;
+import org.opendaylight.ovsdb.hwvtepsouthbound.transactions.md.TransactionInvokerImpl;
+import org.opendaylight.ovsdb.lib.OvsdbClient;
+import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo;
+import org.opendaylight.ovsdb.lib.operations.Comment;
+import org.opendaylight.ovsdb.lib.operations.Insert;
+import org.opendaylight.ovsdb.lib.operations.OperationResult;
+import org.opendaylight.ovsdb.lib.operations.Operations;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
+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.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.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.util.List;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+import static org.powermock.api.support.membermodification.MemberMatcher.field;
+import static org.powermock.api.support.membermodification.MemberModifier.suppress;
+
+public class DataChangeListenerTestBase extends AbstractDataBrokerTest {
+
+ static Logger LOG = LoggerFactory.getLogger(DataChangeListenerTestBase.class);
+
+ static DataBroker dataBroker;
+
+ EntityOwnershipService entityOwnershipService;
+ OvsdbClient ovsdbClient;
+ DatabaseSchema dbSchema;
+ ListenableFuture<DatabaseSchema> listenableDbSchema = mock(ListenableFuture.class);
+ TransactionInvoker transactionInvoker;
+ OvsdbConnectionInfo connectionInfo;
+ Operations operations;
+ HwvtepDataChangeListener hwvtepDataChangeListener;
+ HwvtepConnectionManager hwvtepConnectionManager;
+ HwvtepConnectionInstance connectionInstance;
+
+ ArgumentCaptor<TypedBaseTable> insertOpCapture;
+ ArgumentCaptor<List> transactCaptor;
+
+ String nodeUuid;
+ InstanceIdentifier<Node> nodeIid;
+
+ @Before
+ public void setupTest() throws Exception {
+ /**
+ * Use the same databroker across tests ,otherwise the following exception is thrown
+ * Caused by: java.lang.RuntimeException: org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.
+ * topology.rev131021.node.attributes.SupportingNode$StreamWriter: frozen class (cannot edit)
+ */
+ if (dataBroker == null) {
+ dataBroker = getDataBroker();
+ }
+ entityOwnershipService = mock(EntityOwnershipService.class);
+ loadSchema();
+ mockConnectionInstance();
+ mockConnectionManager();
+ mockOperations();
+
+ nodeUuid = java.util.UUID.randomUUID().toString();
+ nodeIid = createInstanceIdentifier(nodeUuid);
+ addNode(OPERATIONAL);
+ addNode(CONFIGURATION);
+ hwvtepDataChangeListener = new HwvtepDataChangeListener(dataBroker, hwvtepConnectionManager);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ hwvtepDataChangeListener.close();
+ deleteNode(OPERATIONAL);
+ deleteNode(CONFIGURATION);
+ }
+
+ void loadSchema() {
+ try (InputStream resourceAsStream = DataChangeListenerTestBase.class.getResourceAsStream("hwvtep_schema.json")) {
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode jsonNode = mapper.readTree(resourceAsStream);
+ dbSchema = DatabaseSchema.fromJson(HwvtepSchemaConstants.HARDWARE_VTEP,
+ jsonNode.get("result"));
+ listenableDbSchema = mock(ListenableFuture.class);
+ when(listenableDbSchema.get()).thenReturn(dbSchema);
+ } catch (Exception e) {
+ LOG.error("Failed to load schema", e);
+ }
+ }
+
+ private void mockConnectionManager() throws IllegalAccessException {
+ hwvtepConnectionManager = PowerMockito.mock(HwvtepConnectionManager.class, Mockito.CALLS_REAL_METHODS);
+ field(HwvtepConnectionManager.class, "db").set(hwvtepConnectionManager, dataBroker);
+ field(HwvtepConnectionManager.class, "txInvoker").set(hwvtepConnectionManager, transactionInvoker);
+ field(HwvtepConnectionManager.class, "entityOwnershipService").set(hwvtepConnectionManager, entityOwnershipService);
+ suppress(PowerMockito.method(HwvtepConnectionManager.class, "getConnectionInstance", HwvtepPhysicalSwitchAttributes.class));
+ when(hwvtepConnectionManager.getConnectionInstance(Mockito.any(HwvtepPhysicalSwitchAttributes.class))).
+ thenReturn(connectionInstance);
+ when(hwvtepConnectionManager.getConnectionInstance(Mockito.any(Node.class))).
+ thenReturn(connectionInstance);
+ }
+
+ void mockConnectionInstance() throws IllegalAccessException {
+ connectionInfo = mock(OvsdbConnectionInfo.class);
+ ovsdbClient = mock(OvsdbClient.class);
+ transactionInvoker = new TransactionInvokerImpl(dataBroker);
+ connectionInstance = PowerMockito.mock(HwvtepConnectionInstance.class, Mockito.CALLS_REAL_METHODS);
+ field(HwvtepConnectionInstance.class, "instanceIdentifier").set(connectionInstance, nodeIid);
+ field(HwvtepConnectionInstance.class, "txInvoker").set(connectionInstance, transactionInvoker);
+ field(HwvtepConnectionInstance.class, "deviceInfo").set(connectionInstance, new HwvtepDeviceInfo());
+ field(HwvtepConnectionInstance.class, "client").set(connectionInstance, ovsdbClient);
+ when(connectionInstance.getConnectionInfo()).thenReturn(connectionInfo);
+ when(connectionInstance.getConnectionInfo().getRemoteAddress()).thenReturn(mock(InetAddress.class));
+ when(connectionInstance.getInstanceIdentifier()).thenReturn(nodeIid);
+ doReturn(listenableDbSchema).when(connectionInstance).getSchema(anyString());
+ connectionInstance.createTransactInvokers();
+ }
+
+ void mockOperations() {
+ resetOperations();
+ }
+
+ /**
+ * resets the captures so that we can validate the captors of the immediate next execution
+ */
+ void resetOperations() {
+ insertOpCapture = ArgumentCaptor.forClass(TypedBaseTable.class);
+ Insert insert = mock(Insert.class);
+ when(insert.withId(any(String.class))).thenReturn(insert);
+ Operations.op = PowerMockito.mock(Operations.class);
+ when(Operations.op.comment(any(String.class))).thenReturn(mock(Comment.class));
+ when(Operations.op.insert(insertOpCapture.capture())).thenReturn(insert);
+
+ ListenableFuture<List<OperationResult>> ft = mock(ListenableFuture.class);
+ transactCaptor = ArgumentCaptor.forClass(List.class);
+ when(ovsdbClient.transact(any(DatabaseSchema.class), transactCaptor.capture())).thenReturn(ft);
+ }
+
+ void addNode(LogicalDatastoreType logicalDatastoreType) throws Exception {
+ NodeBuilder nodeBuilder = prepareNode(nodeIid);
+ HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder();
+ nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, builder.build());
+ WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
+ transaction.put(logicalDatastoreType, nodeIid, nodeBuilder.build(), WriteTransaction.CREATE_MISSING_PARENTS);
+ transaction.submit();
+ }
+
+ void deleteNode(LogicalDatastoreType logicalDatastoreType) {
+ ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
+ tx.delete(logicalDatastoreType, nodeIid);
+ tx.submit();
+ }
+
+ void addData(LogicalDatastoreType logicalDatastoreType, Class<? extends DataObject> dataObject,
+ String[]... data) {
+ NodeBuilder nodeBuilder = prepareNode(nodeIid);
+ HwvtepGlobalAugmentationBuilder builder = new HwvtepGlobalAugmentationBuilder();
+ if (LogicalSwitches.class == dataObject) {
+ TestBuilders.addLogicalSwitches(builder, data);
+ }
+ if (TerminationPoint.class == dataObject) {
+ TestBuilders.addGlobalTerminationPoints(nodeBuilder, nodeIid, data);
+ }
+ if (RemoteUcastMacs.class == dataObject) {
+ TestBuilders.addRemoteUcastMacs(nodeIid, builder, data);
+ }
+ if (RemoteMcastMacs.class == dataObject) {
+ TestBuilders.addRemoteMcastMacs(nodeIid, builder, data);
+ }
+ nodeBuilder.addAugmentation(HwvtepGlobalAugmentation.class, builder.build());
+ mergeNode(logicalDatastoreType, nodeIid, nodeBuilder);
+ }
+
+ NodeBuilder prepareNode(InstanceIdentifier<Node> iid) {
+ NodeBuilder nodeBuilder = new NodeBuilder();
+ nodeBuilder.setNodeId(iid.firstKeyOf(Node.class).getNodeId());
+ return nodeBuilder;
+ }
+
+ Node mergeNode(LogicalDatastoreType datastoreType, InstanceIdentifier<Node> id, NodeBuilder nodeBuilder) {
+ Node node = nodeBuilder.build();
+ WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
+ transaction.merge(datastoreType, id, node, WriteTransaction.CREATE_MISSING_PARENTS);
+ transaction.submit();
+ return node;
+ }
+
+ public InstanceIdentifier<Node> createInstanceIdentifier(String nodeIdString) {
+ NodeId nodeId = new NodeId(new Uri(nodeIdString));
+ NodeKey nodeKey = new NodeKey(nodeId);
+ TopologyKey topoKey = new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID);
+ return InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, topoKey)
+ .child(Node.class, nodeKey)
+ .build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.ovsdb.hwvtepsouthbound;
+
+import com.google.common.collect.Lists;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.opendaylight.ovsdb.lib.operations.Operations;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
+import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
+import org.opendaylight.ovsdb.schema.hardwarevtep.McastMacsRemote;
+import org.opendaylight.ovsdb.schema.hardwarevtep.UcastMacsRemote;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
+
+/**
+ * Unit tests for the data-tree change listener.
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({HwvtepConnectionInstance.class, HwvtepConnectionManager.class, Operations.class})
+public class HwvtepDataChangeListenerTest extends DataChangeListenerTestBase {
+
+ static Logger LOG = LoggerFactory.getLogger(HwvtepDataChangeListenerTest.class);
+
+ String[][] ucastMacs = new String[][]{
+ {"20:00:00:00:00:01", "11.10.10.1", "192.168.122.20", "ls0"},
+ {"20:00:00:00:00:02", "11.10.10.2", "192.168.122.20", "ls0"},
+ {"20:00:00:00:00:03", "11.10.10.3", "192.168.122.30", "ls1"},
+ {"20:00:00:00:00:04", "11.10.10.4", "192.168.122.30", "ls1"}
+ };
+
+ String[][] logicalSwitches = new String[][]{
+ {"ls0", "100"},
+ {"ls1", "200"},
+ };
+
+ String[][] terminationPoints = new String[][]{
+ {"192.168.122.10"},
+ {"192.168.122.20"},
+ {"192.168.122.30"},
+ {"192.168.122.40"}
+ };
+
+ String[][] mcastMacs = new String[][]{
+ {"FF:FF:FF:FF:FF:FF", "ls0", "192.168.122.20", "192.168.122.30"},
+ {"FF:FF:FF:FF:FF:FF", "ls1", "192.168.122.10", "192.168.122.30"}
+ };
+
+ @Test
+ public <T extends DataObject> void testLogicalSwitchAdd() throws Exception {
+ addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ verifyThatLogicalSwitchCreated();
+ }
+
+ @Test
+ public <T extends DataObject> void testUcastMacAdd() throws Exception {
+ addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ resetOperations();
+ addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
+ addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
+ //4 ucast macs + 2 termination points
+ verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class));
+ //TODO add finer grained validation
+ }
+
+ @Test
+ public <T extends DataObject> void testMcastMacAdd() throws Exception {
+ addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ resetOperations();
+ addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
+ //2 mcast macs + 2 locator sets + 3 termination points
+ verify(Operations.op, times(7)).insert(Matchers.<McastMacsRemote>any());
+ }
+
+ @Test
+ public <T extends DataObject> void testAddMacs() throws Exception {
+ addData(CONFIGURATION, LogicalSwitches.class, logicalSwitches);
+ addData(OPERATIONAL, LogicalSwitches.class, logicalSwitches);
+ resetOperations();
+ addData(CONFIGURATION, TerminationPoint.class, terminationPoints);
+ addData(CONFIGURATION, RemoteUcastMacs.class, ucastMacs);
+ verify(Operations.op, times(6)).insert(any(UcastMacsRemote.class));
+
+ addData(OPERATIONAL, TerminationPoint.class, terminationPoints);
+ addData(OPERATIONAL, RemoteUcastMacs.class, ucastMacs);
+
+ resetOperations();
+ addData(CONFIGURATION, RemoteMcastMacs.class, mcastMacs);
+ //2 mcast mac + 2 locator sets ( termination point already added )
+ verify(Operations.op, times(4)).insert(Matchers.<McastMacsRemote>any());
+ }
+
+ private void verifyThatLogicalSwitchCreated() {
+ verify(ovsdbClient, times(1)).transact(any(DatabaseSchema.class), any(List.class));
+ verify(Operations.op, times(2)).insert(any(LogicalSwitch.class));
+
+ assertNotNull(insertOpCapture.getAllValues());
+ assertTrue(insertOpCapture.getAllValues().size() == 2);
+
+ List<String> expected = Lists.newArrayList("ls0", "ls1");
+ Iterator<TypedBaseTable> it = insertOpCapture.getAllValues().iterator();
+ while (it.hasNext()) {
+ TypedBaseTable table = it.next();
+ assertTrue(table instanceof LogicalSwitch);
+ LogicalSwitch ls = (LogicalSwitch)table;
+ assertTrue(expected.contains(ls.getName()));
+ expected.remove(ls.getName());
+ it.next();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.ovsdb.hwvtepsouthbound;
+
+import com.google.common.collect.Lists;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSetBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+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.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+public class TestBuilders {
+
+ public static final String VXLAN_OVER_IPV4 = "vxlan_over_ipv4";
+
+ public static void addLogicalSwitches(HwvtepGlobalAugmentationBuilder augmentationBuilder, String[]... data) {
+ List<LogicalSwitches> logicalSwitcheses = Lists.newArrayList();
+ for (String row[] : data) {
+ logicalSwitcheses.add(TestBuilders.buildLogicalSwitch(row));
+ }
+ augmentationBuilder.setLogicalSwitches(logicalSwitcheses);
+ }
+
+ public static void addRemoteMcastMacs(InstanceIdentifier<Node> iid,
+ HwvtepGlobalAugmentationBuilder augmentationBuilder, String[]... data) {
+ List<RemoteMcastMacs> remoteMcastMacses = Lists.newArrayList();
+ for (String row[] : data) {
+ String teps[] = Arrays.copyOfRange(row, 2, row.length);
+ remoteMcastMacses.add(TestBuilders.buildRemoteMcastMacs(iid, row[0], row[1], teps));
+ }
+ augmentationBuilder.setRemoteMcastMacs(remoteMcastMacses);
+ }
+
+ public static List<RemoteUcastMacs> addRemoteUcastMacs(InstanceIdentifier<Node> iid,
+ HwvtepGlobalAugmentationBuilder augmentationBuilder,
+ String[]... data) {
+ List<RemoteUcastMacs> remoteUcastMacses = Lists.newArrayList();
+ for (String row[] : data) {
+ remoteUcastMacses.add(TestBuilders.buildRemoteUcastMacs(iid, row[0], row[1], row[2], row[3]));
+ }
+ augmentationBuilder.setRemoteUcastMacs(remoteUcastMacses);
+ return remoteUcastMacses;
+ }
+
+ public static void addGlobalTerminationPoints(NodeBuilder nodeBuilder, InstanceIdentifier<Node> nodeIid,
+ String[]... data) {
+ List<TerminationPoint> terminationPoints = Lists.newArrayList();
+ for (String row[] : data) {
+ terminationPoints.add(TestBuilders.buildTerminationPoint(nodeIid, row[0]));
+ }
+ nodeBuilder.setTerminationPoint(terminationPoints);
+ }
+
+ public static HwvtepLogicalSwitchRef buildLogicalSwitchesRef(InstanceIdentifier<Node> nodeIid,
+ String logicalSwitchName ) {
+ InstanceIdentifier<LogicalSwitches> lSwitchIid = nodeIid.augmentation(HwvtepGlobalAugmentation.class)
+ .child(LogicalSwitches.class, new LogicalSwitchesKey(new HwvtepNodeName(logicalSwitchName)));
+ return new HwvtepLogicalSwitchRef(lSwitchIid);
+ }
+
+ public static RemoteUcastMacs buildRemoteUcastMacs(InstanceIdentifier<Node> nodeIid, String vmMac,
+ String vmip, String tepIp, String logicalSwitchName) {
+ RemoteUcastMacsBuilder ucmlBuilder = new RemoteUcastMacsBuilder();
+ ucmlBuilder.setIpaddr(new IpAddress(vmip.toCharArray()));
+ ucmlBuilder.setMacEntryKey(new MacAddress(vmMac));
+ ucmlBuilder.setMacEntryUuid(getUUid(vmMac));
+ ucmlBuilder.setLocatorRef(buildLocatorRef(nodeIid, tepIp));
+ ucmlBuilder.setLogicalSwitchRef(buildLogicalSwitchesRef(nodeIid, logicalSwitchName));
+ return ucmlBuilder.build();
+ }
+
+ public static TerminationPoint buildTerminationPoint(InstanceIdentifier<Node> nodeIid, String ip) {
+ TerminationPointKey tpKey = new TerminationPointKey(new TpId("vxlan_over_ipv4:"+ip));
+ TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+ if (nodeIid != null) {
+ tpBuilder.setKey(tpKey);
+ tpBuilder.setTpId(tpKey.getTpId());
+ HwvtepPhysicalLocatorAugmentationBuilder tpAugmentationBuilder =
+ new HwvtepPhysicalLocatorAugmentationBuilder();
+ tpAugmentationBuilder.setPhysicalLocatorUuid(getUUid(ip));
+ tpAugmentationBuilder.setEncapsulationType(HwvtepSouthboundMapper.createEncapsulationType(VXLAN_OVER_IPV4));
+ tpAugmentationBuilder.setDstIp(new IpAddress(ip.toCharArray()));
+ tpBuilder.addAugmentation(HwvtepPhysicalLocatorAugmentation.class, tpAugmentationBuilder.build());
+ }
+ return tpBuilder.build();
+ }
+
+ public static LogicalSwitches buildLogicalSwitch(String... keys) {
+ String logicalSwitch = keys[0];
+ String tunnelKey = keys[1];
+ LogicalSwitchesBuilder logicalSwitchesBuilder = new LogicalSwitchesBuilder();
+ logicalSwitchesBuilder.setKey(new LogicalSwitchesKey(new HwvtepNodeName(logicalSwitch)));
+ logicalSwitchesBuilder.setHwvtepNodeName(new HwvtepNodeName(logicalSwitch));
+ logicalSwitchesBuilder.setTunnelKey(tunnelKey);
+ Uuid uuid = getUUid(logicalSwitch);
+ logicalSwitchesBuilder.setLogicalSwitchUuid(uuid);
+ return logicalSwitchesBuilder.build();
+ }
+
+ public static RemoteMcastMacs buildRemoteMcastMacs(InstanceIdentifier<Node> iid, String mac,
+ String logicalSwitchName,String tepIps[]) {
+
+ RemoteMcastMacsBuilder mMacLocalBuilder = new RemoteMcastMacsBuilder();
+ if (mac.equals(HwvtepSouthboundConstants.UNKNOWN_DST_STRING)) {
+ mMacLocalBuilder.setMacEntryKey(HwvtepSouthboundConstants.UNKNOWN_DST_MAC);
+ } else {
+ mMacLocalBuilder.setMacEntryKey(new MacAddress(mac));
+ }
+ mMacLocalBuilder.setMacEntryUuid(getUUid(mac));
+ mMacLocalBuilder.setLogicalSwitchRef(buildLogicalSwitchesRef(iid, logicalSwitchName));
+ List<LocatorSet> locatorSets = Lists.newArrayList();
+ for (String tepIp : tepIps) {
+ locatorSets.add(new LocatorSetBuilder().setLocatorRef(
+ buildLocatorRef(iid, tepIp)).build());
+ }
+ mMacLocalBuilder.setLocatorSet(locatorSets);
+ return mMacLocalBuilder.build();
+ }
+
+ public static HwvtepPhysicalLocatorRef buildLocatorRef(InstanceIdentifier<Node> nodeIid,String tepIp) {
+ InstanceIdentifier<TerminationPoint> tepId = buildTpId(nodeIid, tepIp);
+ return new HwvtepPhysicalLocatorRef(tepId);
+ }
+
+ public static Uuid getUUid(String key) {
+ return new Uuid(UUID.nameUUIDFromBytes(key.getBytes()).toString());
+ }
+
+ public static InstanceIdentifier<TerminationPoint> buildTpId(InstanceIdentifier<Node> nodeIid,String tepIp) {
+ String tpKeyStr = VXLAN_OVER_IPV4 +':'+tepIp;
+ TerminationPointKey tpKey = new TerminationPointKey(new TpId(tpKeyStr));
+ return nodeIid.child(TerminationPoint.class, tpKey);
+ }
+}
--- /dev/null
+{
+ "error": null,
+ "id": "0",
+ "result": {
+ "cksum": "58544667 7319",
+ "name": "hardware_vtep",
+ "tables": {
+ "Arp_Sources_Local": {
+ "columns": {
+ "locator": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Locator",
+ "type": "uuid"
+ }
+ }
+ },
+ "src_mac": {
+ "type": "string"
+ }
+ },
+ "isRoot": true
+ },
+ "Arp_Sources_Remote": {
+ "columns": {
+ "locator": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Locator",
+ "type": "uuid"
+ }
+ }
+ },
+ "src_mac": {
+ "type": "string"
+ }
+ },
+ "isRoot": true
+ },
+ "Global": {
+ "columns": {
+ "managers": {
+ "type": {
+ "key": {
+ "refTable": "Manager",
+ "type": "uuid"
+ },
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "switches": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Switch",
+ "type": "uuid"
+ },
+ "max": "unlimited",
+ "min": 0
+ }
+ }
+ },
+ "isRoot": true,
+ "maxRows": 1
+ },
+ "Logical_Binding_Stats": {
+ "columns": {
+ "bytes_from_local": {
+ "type": "integer"
+ },
+ "bytes_to_local": {
+ "type": "integer"
+ },
+ "packets_from_local": {
+ "type": "integer"
+ },
+ "packets_to_local": {
+ "type": "integer"
+ }
+ }
+ },
+ "Logical_Router": {
+ "columns": {
+ "description": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "static_routes": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0,
+ "value": "string"
+ }
+ },
+ "switch_binding": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0,
+ "value": {
+ "refTable": "Logical_Switch",
+ "type": "uuid"
+ }
+ }
+ }
+ },
+ "indexes": [
+ [
+ "name"
+ ]
+ ],
+ "isRoot": true
+ },
+ "Logical_Switch": {
+ "columns": {
+ "description": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "_uuid": {
+ "type": "string"
+ },
+ "tunnel_key": {
+ "type": {
+ "key": "integer",
+ "min": 0
+ }
+ }
+ },
+ "indexes": [
+ [
+ "name"
+ ]
+ ],
+ "isRoot": true
+ },
+ "Manager": {
+ "columns": {
+ "inactivity_probe": {
+ "type": {
+ "key": "integer",
+ "min": 0
+ }
+ },
+ "is_connected": {
+ "ephemeral": true,
+ "type": "boolean"
+ },
+ "max_backoff": {
+ "type": {
+ "key": {
+ "minInteger": 1000,
+ "type": "integer"
+ },
+ "min": 0
+ }
+ },
+ "other_config": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0,
+ "value": "string"
+ }
+ },
+ "status": {
+ "ephemeral": true,
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0,
+ "value": "string"
+ }
+ },
+ "target": {
+ "type": "string"
+ }
+ },
+ "indexes": [
+ [
+ "target"
+ ]
+ ]
+ },
+ "Mcast_Macs_Local": {
+ "columns": {
+ "MAC": {
+ "type": "string"
+ },
+ "ipaddr": {
+ "type": "string"
+ },
+ "locator_set": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Locator_Set",
+ "type": "uuid"
+ }
+ }
+ },
+ "logical_switch": {
+ "type": {
+ "key": {
+ "refTable": "Logical_Switch",
+ "type": "uuid"
+ }
+ }
+ }
+ },
+ "isRoot": true
+ },
+ "Mcast_Macs_Remote": {
+ "columns": {
+ "MAC": {
+ "type": "string"
+ },
+ "ipaddr": {
+ "type": "string"
+ },
+ "locator_set": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Locator_Set",
+ "type": "uuid"
+ }
+ }
+ },
+ "logical_switch": {
+ "type": {
+ "key": {
+ "refTable": "Logical_Switch",
+ "type": "uuid"
+ }
+ }
+ }
+ },
+ "isRoot": true
+ },
+ "Physical_Locator": {
+ "columns": {
+ "dst_ip": {
+ "mutable": false,
+ "type": "string"
+ },
+ "encapsulation_type": {
+ "mutable": false,
+ "type": {
+ "key": {
+ "enum": "vxlan_over_ipv4",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "indexes": [
+ [
+ "encapsulation_type",
+ "dst_ip"
+ ]
+ ]
+ },
+ "Physical_Locator_Set": {
+ "columns": {
+ "locators": {
+ "mutable": false,
+ "type": {
+ "key": {
+ "refTable": "Physical_Locator",
+ "type": "uuid"
+ },
+ "max": "unlimited"
+ }
+ }
+ }
+ },
+ "Physical_Port": {
+ "columns": {
+ "description": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "port_fault_status": {
+ "ephemeral": true,
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "vlan_bindings": {
+ "type": {
+ "key": {
+ "maxInteger": 4095,
+ "minInteger": 0,
+ "type": "integer"
+ },
+ "max": "unlimited",
+ "min": 0,
+ "value": {
+ "refTable": "Logical_Switch",
+ "type": "uuid"
+ }
+ }
+ },
+ "vlan_stats": {
+ "type": {
+ "key": {
+ "maxInteger": 4095,
+ "minInteger": 0,
+ "type": "integer"
+ },
+ "max": "unlimited",
+ "min": 0,
+ "value": {
+ "refTable": "Logical_Binding_Stats",
+ "type": "uuid"
+ }
+ }
+ }
+ }
+ },
+ "Physical_Switch": {
+ "columns": {
+ "description": {
+ "type": "string"
+ },
+ "management_ips": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "name": {
+ "type": "string"
+ },
+ "ports": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Port",
+ "type": "uuid"
+ },
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "switch_fault_status": {
+ "ephemeral": true,
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "tunnel_ips": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0
+ }
+ },
+ "tunnels": {
+ "type": {
+ "key": {
+ "refTable": "Tunnel",
+ "type": "uuid"
+ },
+ "max": "unlimited",
+ "min": 0
+ }
+ }
+ },
+ "indexes": [
+ [
+ "name"
+ ]
+ ]
+ },
+ "Tunnel": {
+ "columns": {
+ "bfd_config_local": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0,
+ "value": "string"
+ }
+ },
+ "bfd_config_remote": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0,
+ "value": "string"
+ }
+ },
+ "bfd_params": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0,
+ "value": "string"
+ }
+ },
+ "bfd_status": {
+ "type": {
+ "key": "string",
+ "max": "unlimited",
+ "min": 0,
+ "value": "string"
+ }
+ },
+ "local": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Locator",
+ "type": "uuid"
+ }
+ }
+ },
+ "remote": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Locator",
+ "type": "uuid"
+ }
+ }
+ }
+ }
+ },
+ "Ucast_Macs_Local": {
+ "columns": {
+ "MAC": {
+ "type": "string"
+ },
+ "ipaddr": {
+ "type": "string"
+ },
+ "locator": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Locator",
+ "type": "uuid"
+ }
+ }
+ },
+ "logical_switch": {
+ "type": {
+ "key": {
+ "refTable": "Logical_Switch",
+ "type": "uuid"
+ }
+ }
+ }
+ },
+ "isRoot": true
+ },
+ "Ucast_Macs_Remote": {
+ "columns": {
+ "MAC": {
+ "type": "string"
+ },
+ "ipaddr": {
+ "type": "string"
+ },
+ "locator": {
+ "type": {
+ "key": {
+ "refTable": "Physical_Locator",
+ "type": "uuid"
+ }
+ }
+ },
+ "logical_switch": {
+ "type": {
+ "key": {
+ "refTable": "Logical_Switch",
+ "type": "uuid"
+ }
+ }
+ }
+ },
+ "isRoot": true
+ }
+ },
+ "version": "1.3.0"
+ }
+}