Bug 7757 -Removing qos deprecations in carbon
[ovsdb.git] / southbound / southbound-it / src / test / java / org / opendaylight / ovsdb / southbound / it / SouthboundIT.java
1 /*
2  * Copyright © 2015, 2017 Red Hat, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.ovsdb.southbound.it;
9
10 import static org.junit.Assert.assertNotNull;
11 import static org.junit.Assert.assertTrue;
12 import static org.junit.Assert.fail;
13 import static org.ops4j.pax.exam.CoreOptions.composite;
14 import static org.ops4j.pax.exam.CoreOptions.maven;
15 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties;
16 import static org.ops4j.pax.exam.CoreOptions.vmOption;
17 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
18 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
19
20 import com.google.common.collect.ImmutableBiMap;
21 import com.google.common.collect.ImmutableList;
22 import com.google.common.collect.Lists;
23 import com.google.common.collect.Sets;
24 import java.lang.annotation.Annotation;
25 import java.lang.reflect.Method;
26 import java.net.InetAddress;
27 import java.net.UnknownHostException;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.HashSet;
31 import java.util.List;
32 import java.util.Properties;
33 import java.util.Set;
34 import javax.annotation.Nullable;
35 import javax.inject.Inject;
36 import org.junit.After;
37 import org.junit.Assert;
38 import org.junit.Assume;
39 import org.junit.Before;
40 import org.junit.Ignore;
41 import org.junit.Test;
42 import org.junit.internal.AssumptionViolatedException;
43 import org.junit.runner.RunWith;
44 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
45 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
46 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
47 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
48 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
49 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
50 import org.opendaylight.ovsdb.lib.notation.Version;
51 import org.opendaylight.ovsdb.schema.openvswitch.Queue;
52 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
53 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
54 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
55 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
56 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbQueueRef;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeBase;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIds;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.Mappings;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIds;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfig;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueList;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIds;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfig;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
128 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
129 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
130 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
131 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
132 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
133 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
134 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
135 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
136 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
137 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
138 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
139 import org.opendaylight.yangtools.concepts.Builder;
140 import org.opendaylight.yangtools.yang.binding.DataObject;
141 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
142 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
143 import org.ops4j.pax.exam.Configuration;
144 import org.ops4j.pax.exam.Option;
145 import org.ops4j.pax.exam.junit.PaxExam;
146 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
147 import org.ops4j.pax.exam.options.MavenUrlReference;
148 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
149 import org.ops4j.pax.exam.spi.reactors.PerClass;
150 import org.ops4j.pax.exam.util.Filter;
151 import org.osgi.framework.BundleContext;
152 import org.slf4j.Logger;
153 import org.slf4j.LoggerFactory;
154
155 /**
156  * Integration tests for southbound-impl
157  *
158  * @author Sam Hague (shague@redhat.com)
159  */
160 @RunWith(PaxExam.class)
161 @ExamReactorStrategy(PerClass.class)
162 public class SouthboundIT extends AbstractMdsalTestBase {
163     private static final String NETDEV_DP_TYPE = "netdev";
164     private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
165     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
166     private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000;
167     private static final String FORMAT_STR = "%s_%s_%d";
168     private static final Version AUTOATTACH_FROM_VERSION = Version.fromString("7.11.2");
169     private static final Version IF_INDEX_FROM_VERSION = Version.fromString("7.2.1");
170     private static final Long MAX_BACKOFF = 10000L;
171     private static final Long INACTIVITY_PROBE = 30000L;
172     private static String addressStr;
173     private static int portNumber;
174     private static String connectionType;
175     private static boolean setup = false;
176     private static MdsalUtils mdsalUtils = null;
177     private static Node ovsdbNode;
178     private static int testMethodsRemaining;
179     private static Version schemaVersion;
180     @Inject @Filter(timeout=60000)
181     private static DataBroker dataBroker = null;
182
183     @Inject
184     private BundleContext bundleContext;
185
186     private static final NotifyingDataChangeListener CONFIGURATION_LISTENER =
187             new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION);
188     private static final NotifyingDataChangeListener OPERATIONAL_LISTENER =
189             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL);
190
191
192     private static class NotifyingDataChangeListener implements DataChangeListener {
193         private final LogicalDatastoreType type;
194         private final Set<InstanceIdentifier<?>> createdIids = new HashSet<>();
195         private final Set<InstanceIdentifier<?>> removedIids = new HashSet<>();
196         private final Set<InstanceIdentifier<?>> updatedIids = new HashSet<>();
197         private final InstanceIdentifier<?> iid;
198         private final int RETRY_WAIT = 100;
199
200         private NotifyingDataChangeListener(LogicalDatastoreType type) {
201             this.type = type;
202             this.iid = null;
203         }
204
205         private NotifyingDataChangeListener(LogicalDatastoreType type, InstanceIdentifier<?> iid) {
206             this.type = type;
207             this.iid = iid;
208         }
209
210         @Override
211         public void onDataChanged(
212                 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> asyncDataChangeEvent) {
213             LOG.info("{} DataChanged: created {}", type, asyncDataChangeEvent.getCreatedData().keySet());
214             LOG.info("{} DataChanged: removed {}", type, asyncDataChangeEvent.getRemovedPaths());
215             LOG.info("{} DataChanged: updated {}", type, asyncDataChangeEvent.getUpdatedData().keySet());
216             createdIids.addAll(asyncDataChangeEvent.getCreatedData().keySet());
217             removedIids.addAll(asyncDataChangeEvent.getRemovedPaths());
218             updatedIids.addAll(asyncDataChangeEvent.getUpdatedData().keySet());
219             // Handled managed iids
220             for (DataObject obj : asyncDataChangeEvent.getCreatedData().values()) {
221                 if (obj instanceof ManagedNodeEntry) {
222                     ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj;
223                     LOG.info("{} DataChanged: created managed {}", managedNodeEntry.getBridgeRef().getValue());
224                     createdIids.add(managedNodeEntry.getBridgeRef().getValue());
225                 }
226             }
227             synchronized(this) {
228                 notifyAll();
229             }
230         }
231
232         public boolean isCreated(InstanceIdentifier<?> iid) {
233             return createdIids.remove(iid);
234         }
235
236         public boolean isRemoved(InstanceIdentifier<?> iid) {
237             return removedIids.remove(iid);
238         }
239
240         public boolean isUpdated(InstanceIdentifier<?> iid) {
241             return updatedIids.remove(iid);
242         }
243
244         public void clear() {
245             createdIids.clear();
246             removedIids.clear();
247             updatedIids.clear();
248         }
249
250         public void registerDataChangeListener() {
251             dataBroker.registerDataChangeListener(type, iid, this, AsyncDataBroker.DataChangeScope.SUBTREE);
252         }
253
254         public void waitForCreation(long timeout) throws InterruptedException {
255             synchronized (this) {
256                 long _start = System.currentTimeMillis();
257                 LOG.info("Waiting for {} DataChanged creation on {}", type, iid);
258                 while (!isCreated(iid) && (System.currentTimeMillis() - _start) < timeout) {
259                     wait(RETRY_WAIT);
260                 }
261                 LOG.info("Woke up, waited {}ms for creation of {}", (System.currentTimeMillis() - _start), iid);
262             }
263         }
264
265         public void waitForDeletion(long timeout) throws InterruptedException {
266             synchronized (this) {
267                 long _start = System.currentTimeMillis();
268                 LOG.info("Waiting for {} DataChanged deletion on {}", type, iid);
269                 while (!isRemoved(iid) && (System.currentTimeMillis() - _start) < timeout) {
270                     wait(RETRY_WAIT);
271                 }
272                 LOG.info("Woke up, waited {}ms for deletion of {}", (System.currentTimeMillis() - _start), iid);
273             }
274         }
275
276         public void waitForUpdate(long timeout) throws InterruptedException {
277             synchronized (this) {
278                 long _start = System.currentTimeMillis();
279                 LOG.info("Waiting for {} DataChanged update on {}", type, iid);
280                 while (!isUpdated(iid) && (System.currentTimeMillis() - _start) < timeout) {
281                     wait(RETRY_WAIT);
282                 }
283                 LOG.info("Woke up, waited {}ms for update of {}", (System.currentTimeMillis() - _start), iid);
284             }
285         }
286
287     }
288
289     @Configuration
290     public Option[] config() {
291         Option[] options = super.config();
292         Option[] propertyOptions = getPropertiesOptions();
293         Option[] otherOptions = getOtherOptions();
294         Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
295         System.arraycopy(options, 0, combinedOptions, 0, options.length);
296         System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
297         System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
298                 otherOptions.length);
299         return combinedOptions;
300     }
301
302     private Option[] getOtherOptions() {
303         return new Option[] {
304                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
305                 keepRuntimeFolder()
306         };
307     }
308
309     @Override
310     public String getKarafDistro() {
311         return maven()
312                 .groupId("org.opendaylight.ovsdb")
313                 .artifactId("southbound-karaf")
314                 .versionAsInProject()
315                 .type("zip")
316                 .getURL();
317     }
318
319     @Override
320     public MavenUrlReference getFeatureRepo() {
321         return maven()
322                 .groupId("org.opendaylight.ovsdb")
323                 .artifactId("southbound-features")
324                 .classifier("features")
325                 .type("xml")
326                 .versionAsInProject();
327     }
328
329     @Override
330     public String getFeatureName() {
331         return "odl-ovsdb-southbound-test";
332     }
333
334     protected String usage() {
335         return "Integration Test needs a valid connection configuration as follows :\n"
336                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
337                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
338     }
339
340     @Override
341     public Option getLoggingOption() {
342         return composite(
343                 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
344                         "log4j.logger.org.opendaylight.ovsdb",
345                         LogLevelOption.LogLevel.TRACE.name()),
346                 super.getLoggingOption());
347     }
348
349     private Option[] getPropertiesOptions() {
350         Properties props = new Properties(System.getProperties());
351         String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
352                 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
353         String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
354                 SouthboundITConstants.DEFAULT_SERVER_PORT);
355         String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
356                 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
357
358         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
359                 connectionType, addressStr, portStr);
360
361         return new Option[] {
362                 propagateSystemProperties(
363                         SouthboundITConstants.SERVER_IPADDRESS,
364                         SouthboundITConstants.SERVER_PORT,
365                         SouthboundITConstants.CONNECTION_TYPE),
366                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
367                         SouthboundITConstants.SERVER_IPADDRESS, addressStr),
368                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
369                         SouthboundITConstants.SERVER_PORT, portStr),
370                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
371                         SouthboundITConstants.CONNECTION_TYPE, connectionType),
372         };
373     }
374
375     @Before
376     @Override
377     public void setup() throws InterruptedException {
378         if (setup) {
379             LOG.info("Skipping setup, already initialized");
380             return;
381         }
382
383         try {
384             super.setup();
385         } catch (Exception e) {
386             LOG.warn("Failed to setup test", e);
387         }
388         Assert.assertNotNull("db should not be null", dataBroker);
389
390         LOG.info("sleeping for 10s to let the features finish installing");
391         Thread.sleep(10000);
392
393         addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
394         String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
395         try {
396             portNumber = Integer.parseInt(portStr);
397         } catch (NumberFormatException e) {
398             fail("Invalid port number " + portStr + System.lineSeparator() + usage());
399         }
400         connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
401
402         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
403                 connectionType, addressStr, portNumber);
404         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
405             if (addressStr == null) {
406                 fail(usage());
407             }
408         }
409
410         mdsalUtils = new MdsalUtils(dataBroker);
411         assertTrue("Did not find " + SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), getOvsdbTopology());
412         final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
413         final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
414         dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
415                 iid, CONFIGURATION_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
416         dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
417                 iid, OPERATIONAL_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
418
419         ovsdbNode = connectOvsdbNode(connectionInfo);
420         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
421         assertNotNull("The OvsdbNodeAugmentation cannot be null", ovsdbNodeAugmentation);
422         schemaVersion = Version.fromString(ovsdbNodeAugmentation.getDbVersion());
423         LOG.info("schemaVersion = {}", schemaVersion);
424
425         // Let's count the test methods (we need to use this instead of @AfterClass on teardown() since the latter is
426         // useless with pax-exam)
427         for (Method method : getClass().getMethods()) {
428             boolean testMethod = false;
429             boolean ignoreMethod = false;
430             for (Annotation annotation : method.getAnnotations()) {
431                 if (Test.class.equals(annotation.annotationType())) {
432                     testMethod = true;
433                 }
434                 if (Ignore.class.equals(annotation.annotationType())) {
435                     ignoreMethod = true;
436                 }
437             }
438             if (testMethod && !ignoreMethod) {
439                 testMethodsRemaining++;
440             }
441         }
442         LOG.info("{} test methods to run", testMethodsRemaining);
443
444         setup = true;
445     }
446
447     @After
448     public void teardown() {
449         testMethodsRemaining--;
450         LOG.info("{} test methods remaining", testMethodsRemaining);
451         if (testMethodsRemaining == 0) {
452             try {
453                 disconnectOvsdbNode(getConnectionInfo(addressStr, portNumber));
454             } catch (InterruptedException e) {
455                 LOG.warn("Interrupted while disconnecting", e);
456             }
457         }
458     }
459
460     private Boolean getOvsdbTopology() {
461         LOG.info("getOvsdbTopology: looking for {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue());
462         Boolean found = false;
463         final TopologyId topologyId = SouthboundUtils.OVSDB_TOPOLOGY_ID;
464         InstanceIdentifier<Topology> path =
465                 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
466         for (int i = 0; i < 60; i++) {
467             Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
468             if (topology != null) {
469                 LOG.info("getOvsdbTopology: found {}...", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue());
470                 found = true;
471                 break;
472             } else {
473                 LOG.info("getOvsdbTopology: still looking ({})...", i);
474                 try {
475                     Thread.sleep(1000);
476                 } catch (InterruptedException e) {
477                     LOG.warn("Interrupted while waiting for {}", SouthboundUtils.OVSDB_TOPOLOGY_ID.getValue(), e);
478                 }
479             }
480         }
481         return found;
482     }
483
484     /**
485      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
486      * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
487      *
488      * @throws InterruptedException
489      */
490     @Test
491     public void testPassiveNode() throws InterruptedException {
492         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
493             //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
494             Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
495         }
496     }
497
498     private static ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
499         InetAddress inetAddress = null;
500         try {
501             inetAddress = InetAddress.getByName(addressStr);
502         } catch (UnknownHostException e) {
503             fail("Could not resolve " + addressStr + ": " + e);
504         }
505
506         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
507         PortNumber port = new PortNumber(portNumber);
508
509         final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
510                 .setRemoteIp(address)
511                 .setRemotePort(port)
512                 .build();
513         LOG.info("connectionInfo: {}", connectionInfo);
514         return connectionInfo;
515     }
516
517     @Test
518     public void testNetworkTopology() throws InterruptedException {
519         NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
520                 InstanceIdentifier.create(NetworkTopology.class));
521         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
522                 networkTopology);
523
524         networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
525                 InstanceIdentifier.create(NetworkTopology.class));
526         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
527                 networkTopology);
528     }
529
530     @Test
531     public void testOvsdbTopology() throws InterruptedException {
532         InstanceIdentifier<Topology> path = InstanceIdentifier
533                 .create(NetworkTopology.class)
534                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
535
536         Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
537         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
538                 topology);
539
540         topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
541
542         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
543                 topology);
544     }
545
546     private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
547         final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
548         Assert.assertTrue(
549                 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, SouthboundUtils.createNode(connectionInfo)));
550         waitForOperationalCreation(iid);
551         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
552         Assert.assertNotNull(node);
553         LOG.info("Connected to {}", SouthboundUtils.connectionInfoToString(connectionInfo));
554         return node;
555     }
556
557     private void waitForOperationalCreation(InstanceIdentifier<Node> iid) throws InterruptedException {
558         synchronized (OPERATIONAL_LISTENER) {
559             long _start = System.currentTimeMillis();
560             LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid);
561             while (!OPERATIONAL_LISTENER.isCreated(
562                     iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
563                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
564             }
565             LOG.info("Woke up, waited {} for creation of {}", (System.currentTimeMillis() - _start), iid);
566         }
567     }
568
569     private static void waitForOperationalDeletion(InstanceIdentifier<Node> iid) throws InterruptedException {
570         synchronized (OPERATIONAL_LISTENER) {
571             long _start = System.currentTimeMillis();
572             LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid);
573             while (!OPERATIONAL_LISTENER.isRemoved(
574                     iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
575                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
576             }
577             LOG.info("Woke up, waited {} for deletion of {}", (System.currentTimeMillis() - _start), iid);
578         }
579     }
580
581     private void waitForOperationalUpdate(InstanceIdentifier<Node> iid) throws InterruptedException {
582         synchronized (OPERATIONAL_LISTENER) {
583             long _start = System.currentTimeMillis();
584             LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid);
585             while (!OPERATIONAL_LISTENER.isUpdated(
586                     iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
587                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
588             }
589             LOG.info("Woke up, waited {} for update of {}", (System.currentTimeMillis() - _start), iid);
590         }
591     }
592
593     private static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
594         final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
595         Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
596         waitForOperationalDeletion(iid);
597         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
598         Assert.assertNull(node);
599         LOG.info("Disconnected from {}", SouthboundUtils.connectionInfoToString(connectionInfo));
600     }
601
602     @Test
603     public void testAddDeleteOvsdbNode() throws InterruptedException {
604         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
605         // At this point we're connected, disconnect and reconnect (the connection will be removed at the very end)
606         disconnectOvsdbNode(connectionInfo);
607         connectOvsdbNode(connectionInfo);
608     }
609
610     @Test
611     public void testDpdkSwitch() throws InterruptedException {
612         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
613         List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
614                 .getDatapathTypeEntry();
615         if (datapathTypeEntries == null) {
616             LOG.info("DPDK not supported on this node.");
617         } else {
618             for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
619                 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
620                 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
621                 LOG.info("dp type is {}", dpTypeStr);
622                 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
623                     LOG.info("Found a DPDK node; adding a corresponding netdev device");
624                     InstanceIdentifier<Node> bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo,
625                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
626                     NodeId bridgeNodeId = SouthboundUtils.createManagedNodeId(bridgeIid);
627                     try (TestBridge testBridge = new TestBridge(connectionInfo, bridgeIid,
628                             SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null, true, dpType, null, null,
629                             null)) {
630                         // Verify that the device is netdev
631                         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
632                         Assert.assertNotNull(bridge);
633                         Assert.assertEquals(dpType, bridge.getDatapathType());
634
635                         // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs)
636                         List<String> dpdkTypes = new ArrayList<>();
637                         dpdkTypes.add("dpdk");
638                         dpdkTypes.add("dpdkr");
639                         dpdkTypes.add("dpdkvhostuser");
640                         //dpdkTypes.add("dpdkvhost");
641
642                         for (String dpdkType : dpdkTypes) {
643                             String testPortname = "test"+dpdkType+"port";
644                             LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType);
645                             Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
646                                     .get(dpdkType);
647                             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder =
648                                     createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname,
649                                             dpdkIfType);
650                             Assert.assertTrue(
651                                     addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder));
652                         }
653
654                         // Verify that all DPDK ports are created
655                         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
656                         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
657                                 terminationPointIid);
658                         Assert.assertNotNull(terminationPointNode);
659
660                         // Verify that each termination point has the specific DPDK ifType
661                         for (String dpdkType : dpdkTypes) {
662                             String testPortname = "test"+dpdkType+"port";
663                             Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
664                                     .get(dpdkType);
665                             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
666                             for (TerminationPoint terminationPoint : terminationPoints) {
667                                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
668                                         .getAugmentation(OvsdbTerminationPointAugmentation.class);
669                                 if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) {
670                                     Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
671                                             .getInterfaceType();
672                                     Assert.assertEquals(dpdkIfType, opPort);
673                                 }
674                             }
675                         }
676                     }
677                 }
678                 break;
679             }
680         }
681     }
682
683     @Test
684     public void testOvsdbNodeOvsVersion() throws InterruptedException {
685         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
686         Assert.assertNotNull(ovsdbNodeAugmentation);
687         assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
688     }
689
690     @Test
691     public void testOvsdbNodeDbVersion() throws InterruptedException {
692         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
693         Assert.assertNotNull(ovsdbNodeAugmentation);
694         assertNotNull(ovsdbNodeAugmentation.getDbVersion());
695     }
696
697     @Test
698     public void testOpenVSwitchOtherConfig() throws InterruptedException {
699         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
700         Assert.assertNotNull(ovsdbNodeAugmentation);
701         List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
702         if (otherConfigsList != null) {
703             for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
704                 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
705                     LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
706                     break;
707                 } else {
708                     LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
709                 }
710             }
711         } else {
712             LOG.info("other_config is not present");
713         }
714     }
715
716     @Test
717     public void testOvsdbBridgeControllerInfo() throws InterruptedException {
718         ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
719         String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
720         assertNotNull("Failed to get controller target", controllerTarget);
721         List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
722         Uri setUri = new Uri(controllerTarget);
723         try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
724                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
725                 setControllerEntry, null)) {
726             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
727             Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME,  bridge);
728             Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
729                     bridge.getControllerEntry());
730             List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
731             for (ControllerEntry entry : getControllerEntries) {
732                 if (entry.getTarget() != null) {
733                     Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
734                 }
735                 if (entry.getMaxBackoff() != null) {
736                     Assert.assertEquals(entry.getMaxBackoff(), MAX_BACKOFF);
737                 }
738                 if (entry.getInactivityProbe() != null) {
739                     Assert.assertEquals(entry.getInactivityProbe(),INACTIVITY_PROBE);
740                 }
741             }
742         }
743     }
744
745     private List<ControllerEntry> createControllerEntry(String controllerTarget) {
746         List<ControllerEntry> controllerEntriesList = new ArrayList<>();
747         controllerEntriesList.add(new ControllerEntryBuilder()
748                 .setTarget(new Uri(controllerTarget))
749                 .setMaxBackoff(MAX_BACKOFF)
750                 .setInactivityProbe(INACTIVITY_PROBE)
751                 .build());
752         return controllerEntriesList;
753     }
754
755     private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
756                               final ConnectionInfo connectionInfo) {
757         InstanceIdentifier<Node> connectionNodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo);
758         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
759     }
760
761     private static List<ProtocolEntry> createMdsalProtocols() {
762         List<ProtocolEntry> protocolList = new ArrayList<>();
763         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
764                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
765         protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
766         return protocolList;
767     }
768
769     private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
770         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
771                 new OvsdbTerminationPointAugmentationBuilder();
772         ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
773                 new InterfaceTypeEntryBuilder()
774                         .setInterfaceType(
775                                 SouthboundMapper.createInterfaceType("internal"))
776                         .build().getInterfaceType());
777         return ovsdbTerminationPointAugmentationBuilder;
778     }
779
780     private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
781             final String portName) {
782         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
783                 createGenericOvsdbTerminationPointAugmentationBuilder();
784         ovsdbTerminationBuilder.setName(portName);
785         Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
786                 .get("dpdk");
787         ovsdbTerminationBuilder.setInterfaceType(ifType);
788         return ovsdbTerminationBuilder;
789     }
790
791     private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(
792             String testPortname,Class<? extends InterfaceTypeBase> dpdkIfType) {
793         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
794                 createGenericOvsdbTerminationPointAugmentationBuilder();
795         ovsdbTerminationBuilder.setName(testPortname);
796         ovsdbTerminationBuilder.setInterfaceType(dpdkIfType);
797         return ovsdbTerminationBuilder;
798     }
799
800     private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
801                                         final OvsdbTerminationPointAugmentationBuilder
802                                                 ovsdbTerminationPointAugmentationBuilder)
803             throws InterruptedException {
804
805         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
806         NodeBuilder portNodeBuilder = new NodeBuilder();
807         NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
808         portNodeBuilder.setNodeId(portNodeId);
809         TerminationPointBuilder entry = new TerminationPointBuilder();
810         entry.setKey(new TerminationPointKey(new TpId(portName)));
811         entry.addAugmentation(
812                 OvsdbTerminationPointAugmentation.class,
813                 ovsdbTerminationPointAugmentationBuilder.build());
814         portNodeBuilder.setTerminationPoint(Collections.singletonList(entry.build()));
815         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
816                 portIid, portNodeBuilder.build());
817         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
818         return result;
819     }
820
821     private static class TestBridge implements AutoCloseable {
822         private final ConnectionInfo connectionInfo;
823         private final String bridgeName;
824
825         /**
826          * Creates a test bridge which can be automatically removed when no longer necessary.
827          *
828          * @param connectionInfo The connection information.
829          * @param bridgeIid The bridge identifier; if {@code null}, one is created based on {@code bridgeName}.
830          * @param bridgeName The bridge name; must be provided.
831          * @param bridgeNodeId The bridge node identifier; if {@code null}, one is created based on {@code bridgeIid}.
832          * @param setProtocolEntries {@code true} to set default protocol entries for the bridge.
833          * @param failMode The fail mode to set for the bridge.
834          * @param setManagedBy {@code true} to specify {@code setManagedBy} for the bridge.
835          * @param dpType The datapath type.
836          * @param externalIds The external identifiers if any.
837          * @param otherConfigs The other configuration items if any.
838          */
839         public TestBridge(final ConnectionInfo connectionInfo, @Nullable InstanceIdentifier<Node> bridgeIid,
840                                   final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
841                                   final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
842                                   @Nullable final Class<? extends DatapathTypeBase> dpType,
843                                   @Nullable final List<BridgeExternalIds> externalIds,
844                                   @Nullable final List<ControllerEntry> controllerEntries,
845                                   @Nullable final List<BridgeOtherConfigs> otherConfigs) {
846             this.connectionInfo = connectionInfo;
847             this.bridgeName = bridgeName;
848             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
849             if (bridgeIid == null) {
850                 bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
851             }
852             if (bridgeNodeId == null) {
853                 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
854             }
855             bridgeNodeBuilder.setNodeId(bridgeNodeId);
856             OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
857             ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
858             if (setProtocolEntries) {
859                 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
860             }
861             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
862             if (setManagedBy) {
863                 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
864             }
865             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
866             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
867             ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
868             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
869             bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
870             LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder.toString());
871             Assert.assertTrue(
872                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build()));
873             try {
874                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
875             } catch (InterruptedException e) {
876                 LOG.warn("Sleep interrupted while waiting for bridge creation (bridge {})", bridgeName, e);
877             }
878         }
879
880         public TestBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
881             this(connectionInfo, null, bridgeName, null, true,
882                     SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
883         }
884
885         @Override
886         public void close() {
887             final InstanceIdentifier<Node> iid =
888                     SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
889             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
890             try {
891                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
892             } catch (InterruptedException e) {
893                 LOG.warn("Sleep interrupted while waiting for bridge deletion (bridge {})", bridgeName, e);
894             }
895         }
896     }
897
898     private static class TestAutoAttach implements AutoCloseable {
899         private final ConnectionInfo connectionInfo;
900         private final Uri autoattachId;
901         private final Uri bridgeId;
902
903         public TestAutoAttach (final ConnectionInfo connectionInfo,
904                 final Uri autoattachId,
905                 final Uri bridgeId,
906                 @Nullable final String systemName,
907                 @Nullable final String systemDescription,
908                 @Nullable final List<Mappings> mappings,
909                 @Nullable final List<AutoattachExternalIds> externalIds) {
910             this.connectionInfo = connectionInfo;
911             this.autoattachId = autoattachId;
912             this.bridgeId = bridgeId;
913
914             Autoattach aaEntry = new AutoattachBuilder()
915                     .setAutoattachId(autoattachId)
916                     .setBridgeId(bridgeId)
917                     .setSystemName(systemName)
918                     .setSystemDescription(systemDescription)
919                     .setMappings(mappings)
920                     .setAutoattachExternalIds(externalIds)
921                     .build();
922             InstanceIdentifier<Autoattach> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
923                     .augmentation(OvsdbNodeAugmentation.class)
924                     .child(Autoattach.class, aaEntry.getKey());
925             final NotifyingDataChangeListener aaOperationalListener =
926                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid);
927             aaOperationalListener.registerDataChangeListener();
928
929             Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, aaEntry));
930             try {
931                 aaOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
932             } catch (InterruptedException e) {
933                 LOG.warn("Sleep interrupted while waiting for queue {}", iid, e);
934             }
935         }
936         @Override
937         public void close() {
938             final InstanceIdentifier<Autoattach> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
939                     .augmentation(OvsdbNodeAugmentation.class)
940                     .child(Autoattach.class, new AutoattachKey(this.autoattachId));
941             final NotifyingDataChangeListener aaOperationalListener =
942                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid);
943             aaOperationalListener.registerDataChangeListener();
944
945             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
946             try {
947                 aaOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
948             } catch (InterruptedException e) {
949                 LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", iid, e);
950             }
951         }
952     }
953
954     @Test
955     public void testCRUDAutoAttach() throws InterruptedException {
956         final boolean isOldSchema = schemaVersion.compareTo(AUTOATTACH_FROM_VERSION) < 0;
957
958         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
959         String testAutoattachId = "testAutoattachEntry";
960         String testSystemName = "testSystemName";
961         String testSystemDescription = "testSystemDescription";
962         String testAutoattachExternalKey = "testAutoattachExternalKey";
963         String testAutoattachExternalValue = "testAutoattachExternalValue";
964
965         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
966             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
967             Assert.assertNotNull(bridge);
968
969             // CREATE: Create Autoattach table
970             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
971                     connectionInfo, bridge.getBridgeName()));
972             String bridgeId = nodeId.getValue();
973             try(TestAutoAttach testAutoattach = new TestAutoAttach(connectionInfo, new Uri(testAutoattachId),
974                     new Uri(bridgeId), testSystemName, testSystemDescription, null, null)) {
975                 // READ: Read md-sal operational datastore to see if the AutoAttach table was created
976                 // and if Bridge table was updated with AutoAttach Uuid
977                 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
978                         LogicalDatastoreType.OPERATIONAL);
979                 Autoattach operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId));
980
981                 // skip tests after verifying that Autoattach doesn't break with unsupported schema
982                 Assume.assumeFalse(isOldSchema);
983
984                 // FIXME: Remove once CRUD is supported
985                 Assume.assumeFalse(operAa == null);
986
987                 Assert.assertNotNull(operAa);
988                 Assert.assertEquals(testSystemName, operAa.getSystemName());
989                 bridge = getBridge(connectionInfo);
990                 Uuid aaUuid = new Uuid(operAa.getAutoattachUuid().getValue());
991                 Assert.assertEquals(aaUuid, bridge.getAutoAttach());
992
993                 // UPDATE: Update mappings column of AutoAttach table that was created
994                 List<Mappings> mappings = ImmutableList.of(new MappingsBuilder().setMappingsKey(100L).setMappingsValue(200).build());
995                 Autoattach updatedAa = new AutoattachBuilder()
996                         .setAutoattachId(new Uri(testAutoattachId))
997                         .setMappings(mappings)
998                         .build();
999                 InstanceIdentifier<Autoattach> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1000                         .augmentation(OvsdbNodeAugmentation.class)
1001                         .child(Autoattach.class, updatedAa.getKey());
1002                 final NotifyingDataChangeListener aaOperationalListener =
1003                         new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid);
1004                 aaOperationalListener.registerDataChangeListener();
1005                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa));
1006                 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
1007
1008                 // UPDATE: Update external_ids column of AutoAttach table that was created
1009                 List<AutoattachExternalIds> externalIds = new ArrayList<>();
1010                 externalIds.add(new AutoattachExternalIdsBuilder()
1011                         .setAutoattachExternalIdKey(testAutoattachExternalKey)
1012                         .setAutoattachExternalIdValue(testAutoattachExternalValue)
1013                         .build());
1014                 updatedAa = new AutoattachBuilder()
1015                         .setAutoattachId(new Uri(testAutoattachId))
1016                         .setAutoattachExternalIds(externalIds)
1017                         .build();
1018                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa));
1019                 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
1020
1021                 // READ: Read the updated AutoAttach table for latest mappings and external_ids column value
1022                 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1023                         LogicalDatastoreType.OPERATIONAL);
1024                 operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId));
1025                 Assert.assertNotNull(operAa);
1026                 List<Mappings> operMappingsList = operAa.getMappings();
1027                 for (Mappings operMappings: operMappingsList) {
1028                     Assert.assertEquals(mappings.get(operMappingsList.indexOf(operMappings)).getMappingsKey(), operMappings.getMappingsKey());
1029                     Assert.assertEquals(mappings.get(operMappingsList.indexOf(operMappings)).getMappingsValue(), operMappings.getMappingsValue());
1030                 }
1031                 List<AutoattachExternalIds> operExternalIds = operAa.getAutoattachExternalIds();
1032                 externalIds.add(new AutoattachExternalIdsBuilder()
1033                         .setAutoattachExternalIdKey(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY)
1034                         .setAutoattachExternalIdValue(operAa.getAutoattachId().getValue())
1035                         .build());
1036                 for (AutoattachExternalIds operExternalId : operExternalIds) {
1037                     Assert.assertEquals(externalIds.get(operExternalIds.indexOf(operExternalId)).getAutoattachExternalIdKey(),
1038                             operExternalId.getAutoattachExternalIdKey());
1039                     Assert.assertEquals(externalIds.get(operExternalIds.indexOf(operExternalId)).getAutoattachExternalIdValue(),
1040                             operExternalId.getAutoattachExternalIdValue());
1041                 }
1042
1043                 // DELETE: Delete AutoAttach table
1044                 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
1045                 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
1046                 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1047                         LogicalDatastoreType.OPERATIONAL);
1048                 operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId));
1049                 Assert.assertNull(operAa);
1050             } catch (AssumptionViolatedException e) {
1051                 LOG.warn("Skipped test for Autoattach due to unsupported schema", e);
1052             } catch (Exception e) {
1053                 fail("Unexpected exception in CRUD test for Autoattach table for schema:" + schemaVersion.toString() +". " + e);
1054             }
1055         }
1056     }
1057
1058     private Autoattach getAutoAttach(OvsdbNodeAugmentation ovsdbNodeAugmentation, Uri uri) {
1059         if (ovsdbNodeAugmentation.getAutoattach() != null
1060                 && !ovsdbNodeAugmentation.getAutoattach().isEmpty()) {
1061             for (Autoattach aa : ovsdbNodeAugmentation.getAutoattach()) {
1062                 if (aa.getKey().getAutoattachId().equals(uri)) {
1063                     return aa;
1064                 }
1065             }
1066         }
1067         return null;
1068     }
1069
1070     private static class TestQos implements AutoCloseable {
1071         private final ConnectionInfo connectionInfo;
1072         private final Uri qosId;
1073
1074         /**
1075          * Creates a test qos entry which can be automatically removed when no longer necessary.
1076          *
1077          * @param connectionInfo The connection information.
1078          * @param qosId The Qos identifier.
1079          * @param qosType The qos type.
1080          * @param externalIds The external identifiers if any.
1081          * @param otherConfigs The other configuration items if any.
1082          */
1083         public TestQos(final ConnectionInfo connectionInfo,
1084                                   final Uri qosId,
1085                                   final Class<? extends QosTypeBase> qosType,
1086                                   @Nullable final List<QosExternalIds> externalIds,
1087                                   @Nullable final List<QosOtherConfig> otherConfigs) {
1088             this.connectionInfo = connectionInfo;
1089             this.qosId = qosId;
1090
1091             QosEntries qosEntry = new QosEntriesBuilder()
1092                 .setQosId(qosId)
1093                 .setQosType(qosType)
1094                 .setQosExternalIds(externalIds)
1095                 .setQosOtherConfig(otherConfigs)
1096                 .build();
1097             InstanceIdentifier<QosEntries> qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1098                     .augmentation(OvsdbNodeAugmentation.class)
1099                     .child(QosEntries.class, qosEntry.getKey());
1100             final NotifyingDataChangeListener qosOperationalListener =
1101                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid);
1102             qosOperationalListener.registerDataChangeListener();
1103
1104             Assert.assertTrue(
1105                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1106                     qeIid, qosEntry));
1107
1108             try {
1109                 qosOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
1110             } catch (InterruptedException e) {
1111                 LOG.warn("Sleep interrupted while waiting for queue {}", qeIid, e);
1112             }
1113
1114         }
1115
1116         @Override
1117         public void close() {
1118             final InstanceIdentifier<QosEntries> qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1119                     .augmentation(OvsdbNodeAugmentation.class)
1120                     .child(QosEntries.class, new QosEntriesKey(this.qosId));
1121             final NotifyingDataChangeListener qosOperationalListener =
1122                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid);
1123             qosOperationalListener.registerDataChangeListener();
1124
1125             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qeIid));
1126             try {
1127                 qosOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
1128             } catch (InterruptedException e) {
1129                 LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", qeIid, e);
1130             }
1131         }
1132     }
1133
1134     private static class TestQueue implements AutoCloseable {
1135         private final ConnectionInfo connectionInfo;
1136         private final Uri queueId;
1137         private final InstanceIdentifier<Queues> qIid;
1138
1139         /**
1140          * Creates a test queue entry which can be automatically removed when no longer necessary.
1141          *
1142          * @param connectionInfo The connection information.
1143          * @param queueId The Queue identifier.
1144          * @param queueDscp The queue dscp value.
1145          * @param externalIds The external identifiers if any.
1146          * @param otherConfigs The other configuration items if any.
1147          */
1148         public TestQueue(final ConnectionInfo connectionInfo,
1149                                   final Uri queueId,
1150                                   final Short queueDscp,
1151                                   @Nullable final List<QueuesExternalIds> externalIds,
1152                                   @Nullable final List<QueuesOtherConfig> otherConfigs) {
1153             this.connectionInfo = connectionInfo;
1154             this.queueId = queueId;
1155
1156             Queues queue = new QueuesBuilder()
1157                 .setQueueId(queueId)
1158                 .setDscp(queueDscp)
1159                 .setQueuesExternalIds(externalIds)
1160                 .setQueuesOtherConfig(otherConfigs)
1161                 .build();
1162             qIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1163                     .augmentation(OvsdbNodeAugmentation.class)
1164                     .child(Queues.class, queue.getKey());
1165             final NotifyingDataChangeListener queueOperationalListener =
1166                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qIid);
1167             queueOperationalListener.registerDataChangeListener();
1168
1169             Assert.assertTrue(
1170                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1171                     qIid, queue));
1172
1173             try {
1174                 queueOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
1175             } catch (InterruptedException e) {
1176                 LOG.warn("Sleep interrupted while waiting for queue {}", queueId, e);
1177             }
1178         }
1179
1180         public InstanceIdentifier<Queues> getInstanceIdentifier() {
1181             return qIid;
1182         }
1183         @Override
1184         public void close() {
1185             InstanceIdentifier<Queues> qIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1186                     .augmentation(OvsdbNodeAugmentation.class)
1187                     .child(Queues.class, new QueuesKey(this.queueId));
1188             final NotifyingDataChangeListener queueOperationalListener =
1189                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qIid);
1190             queueOperationalListener.registerDataChangeListener();
1191
1192             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qIid));
1193             try {
1194                 queueOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
1195             } catch (InterruptedException e) {
1196                 LOG.warn("Sleep interrupted while waiting for queue deletion (queue {})", queueId, e);
1197             }
1198         }
1199     }
1200
1201     private OvsdbNodeAugmentation getOvsdbNode(ConnectionInfo connectionInfo, LogicalDatastoreType store) {
1202         InstanceIdentifier<Node> nodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
1203         Node node = mdsalUtils.read(store, nodeIid);
1204         Assert.assertNotNull(node);
1205         OvsdbNodeAugmentation ovsdbNodeAugmentation = node.getAugmentation(OvsdbNodeAugmentation.class);
1206         Assert.assertNotNull(ovsdbNodeAugmentation);
1207         return ovsdbNodeAugmentation;
1208     }
1209
1210     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
1211         return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1212     }
1213
1214     /**
1215      * Extract the <code>store</code> type data store contents for the particular bridge identified by
1216      * <code>bridgeName</code>.
1217      *
1218      * @param connectionInfo the connection information
1219      * @param bridgeName the bridge name
1220      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
1221      * @return <code>store</code> type data store contents
1222      */
1223     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
1224                                               LogicalDatastoreType store) {
1225         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
1226         Assert.assertNotNull(bridgeNode);
1227         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
1228         Assert.assertNotNull(ovsdbBridgeAugmentation);
1229         return ovsdbBridgeAugmentation;
1230     }
1231
1232     /**
1233      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
1234      * identified by <code>bridgeName</code>
1235      *
1236      * @param connectionInfo the connection information
1237      * @param bridgeName the bridge name
1238      * @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
1239      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
1240      */
1241     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
1242         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
1243     }
1244
1245     /**
1246      * Extract the node contents from <code>store</code> type data store for the
1247      * bridge identified by <code>bridgeName</code>
1248      *
1249      * @param connectionInfo the connection information
1250      * @param bridgeName the bridge name
1251      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
1252      * @return <code>store</code> type data store contents
1253      */
1254     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
1255         InstanceIdentifier<Node> bridgeIid =
1256                 SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
1257         return mdsalUtils.read(store, bridgeIid);
1258     }
1259
1260     /**
1261      * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
1262      * bridge identified by <code>bridgeName</code>
1263      *
1264      * @param connectionInfo the connection information
1265      * @param bridgeName the bridge name
1266      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
1267      */
1268     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
1269         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
1270     }
1271
1272     @Test
1273     public void testAddDeleteBridge() throws InterruptedException {
1274         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1275
1276         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1277             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1278             Assert.assertNotNull(bridge);
1279             LOG.info("bridge: {}", bridge);
1280         }
1281     }
1282
1283     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
1284         return SouthboundUtils.createInstanceIdentifier(connectionInfo, bridge.getBridgeName());
1285     }
1286
1287     /**
1288      * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
1289      * on <code>bridgeName</code>
1290      *
1291      * @param connectionInfo the connection information
1292      * @param bridgeName the bridge name
1293      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
1294      * @param index the index we're interested in
1295      * @return the augmentation (or {@code null} if none)
1296      */
1297     private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
1298             ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
1299
1300         List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
1301         if (tpList == null) {
1302             return null;
1303         }
1304         return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class);
1305     }
1306
1307     @Test
1308     public void testCRUDTerminationPointIfIndex() throws InterruptedException {
1309         final boolean isOldSchema = schemaVersion.compareTo(IF_INDEX_FROM_VERSION) < 0;
1310         Assume.assumeFalse(isOldSchema);
1311         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1312
1313         // Test create ifIndex
1314         try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME, null, true,
1315                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1316                 true, SouthboundMapper.createDatapathType("netdev"), null, null, null)) {
1317             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1318             Assert.assertNotNull(bridge);
1319             LOG.info("bridge: {}", bridge);
1320             NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1321                     connectionInfo, bridge.getBridgeName()));
1322             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1323                     createGenericOvsdbTerminationPointAugmentationBuilder();
1324             String portName = "testIfIndex";
1325             ovsdbTerminationBuilder.setName(portName);
1326
1327             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1328             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1329             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1330             Assert.assertNotNull(terminationPointNode);
1331
1332             // Test read ifIndex
1333             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1334             for (TerminationPoint terminationPoint : terminationPoints) {
1335                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1336                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1337                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1338                     Long ifIndex = ovsdbTerminationPointAugmentation.getIfindex();
1339                     Assert.assertNotNull(ifIndex);
1340                     LOG.info("ifIndex: {} for the port:{}", ifIndex, portName);
1341                 }
1342             }
1343         }
1344     }
1345
1346     @Test
1347     public void testCRDTerminationPointOfPort() throws InterruptedException {
1348         final Long OFPORT_EXPECTED = 45002L;
1349
1350         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1351
1352         // CREATE
1353         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1354             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1355             Assert.assertNotNull(bridge);
1356             LOG.info("bridge: {}", bridge);
1357             NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1358                     connectionInfo, bridge.getBridgeName()));
1359             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1360                     createGenericOvsdbTerminationPointAugmentationBuilder();
1361             String portName = "testOfPort";
1362             ovsdbTerminationBuilder.setName(portName);
1363
1364             ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
1365             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1366             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1367             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1368             Assert.assertNotNull(terminationPointNode);
1369
1370             // READ
1371             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1372             for (TerminationPoint terminationPoint : terminationPoints) {
1373                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1374                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1375                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1376                     Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
1377                     // if ephemeral port 45002 is in use, ofPort is set to 1
1378                     Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
1379                     LOG.info("ofPort: {}", ofPort);
1380                 }
1381             }
1382
1383             // UPDATE- Not Applicable.  From the OpenVSwitch Documentation:
1384             //   "A client should ideally set this column’s value in the same database transaction that it uses to create
1385             //   the interface."
1386
1387             // DELETE handled by TestBridge
1388         }
1389     }
1390
1391     @Test
1392     public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
1393         final Long OFPORT_EXPECTED = 45008L;
1394         final Long OFPORT_INPUT = 45008L;
1395
1396         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1397
1398         // CREATE
1399         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1400             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1401             Assert.assertNotNull(bridge);
1402             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1403                     connectionInfo, bridge.getBridgeName()));
1404             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1405                     createGenericOvsdbTerminationPointAugmentationBuilder();
1406             String portName = "testOfPortRequest";
1407             ovsdbTerminationBuilder.setName(portName);
1408             Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
1409             ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
1410             ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
1411             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1412             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1413             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1414             Assert.assertNotNull(terminationPointNode);
1415
1416             // READ
1417             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1418             for (TerminationPoint terminationPoint : terminationPoints) {
1419                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1420                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1421                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1422                     Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
1423                     // if ephemeral port 45008 is in use, ofPort is set to 1
1424                     Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
1425                     LOG.info("ofPort: {}", ofPort);
1426
1427                     Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
1428                     Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
1429                     LOG.info("ofPortRequest: {}", ofPortRequest);
1430                 }
1431             }
1432
1433             // UPDATE- Not Applicable.  From the OpenVSwitch documentation:
1434             //   "A client should ideally set this column’s value in the same database transaction that it uses to
1435             //   create the interface. "
1436
1437             // DELETE handled by TestBridge
1438         }
1439     }
1440
1441     private <T> void assertExpectedExist(List<T> expected, List<T> test) {
1442         if (expected != null && test != null) {
1443             for (T exp : expected) {
1444                 Assert.assertTrue("The retrieved values don't contain " + exp, test.contains(exp));
1445             }
1446         }
1447     }
1448
1449     private interface SouthboundTerminationPointHelper<T> {
1450         void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<T> values);
1451         List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
1452     }
1453
1454     /*
1455      * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1456      *
1457      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1458      */
1459     private <T> void testCRUDTerminationPoint(
1460             KeyValueBuilder<T> builder, String prefix, SouthboundTerminationPointHelper<T> helper)
1461             throws InterruptedException {
1462         final int TERMINATION_POINT_TEST_INDEX = 0;
1463
1464         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1465
1466         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1467         // the update has been performed.
1468         List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
1469         List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
1470
1471         for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
1472             for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
1473                 String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name);
1474
1475                 // CREATE: Create the test bridge
1476                 try (TestBridge testBridge = new TestBridge(connectionInfo, null, testBridgeAndPortName, null, true,
1477                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null,
1478                         null)) {
1479                     NodeId testBridgeNodeId = SouthboundUtils.createManagedNodeId(
1480                             SouthboundUtils.createInstanceIdentifier(connectionInfo,
1481                                     new OvsdbBridgeName(testBridgeAndPortName)));
1482                     OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1483                             createGenericOvsdbTerminationPointAugmentationBuilder();
1484                     tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
1485                     helper.writeValues(tpCreateAugmentationBuilder, updateFromTestCase.inputValues);
1486                     Assert.assertTrue(
1487                             addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
1488
1489                     // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1490                     // then repeat for OPERATIONAL data store
1491                     OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1492                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1493                                     LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1494                     if (updateFromConfigurationTerminationPointAugmentation != null) {
1495                         List<T> updateFromConfigurationValues =
1496                                 helper.readValues(updateFromConfigurationTerminationPointAugmentation);
1497                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
1498                     }
1499                     OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1500                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1501                                     LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1502                     if (updateFromOperationalTerminationPointAugmentation != null) {
1503                         List<T> updateFromOperationalValues =
1504                                 helper.readValues(updateFromOperationalTerminationPointAugmentation);
1505                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
1506                     }
1507
1508                     // UPDATE:  update the values
1509                     testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
1510                     OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1511                             new OvsdbTerminationPointAugmentationBuilder();
1512                     helper.writeValues(tpUpdateAugmentationBuilder, updateToTestCase.inputValues);
1513                     InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1514                     NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1515                     NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1516                     portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1517                     TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1518                     tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
1519                     tpUpdateBuilder.addAugmentation(
1520                             OvsdbTerminationPointAugmentation.class,
1521                             tpUpdateAugmentationBuilder.build());
1522                     portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1523                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1524                             portIid, portUpdateNodeBuilder.build()));
1525                     Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1526
1527                     // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1528                     // then repeat for OPERATIONAL data store
1529                     OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1530                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1531                                     LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1532                     if (updateToConfigurationTerminationPointAugmentation != null) {
1533                         List<T> updateToConfigurationValues =
1534                                 helper.readValues(updateToConfigurationTerminationPointAugmentation);
1535                         assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
1536                         assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues);
1537                     }
1538                     OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1539                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1540                                     LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1541                     if (updateToOperationalTerminationPointAugmentation != null) {
1542                         List<T> updateToOperationalValues =
1543                                 helper.readValues(updateToOperationalTerminationPointAugmentation);
1544                         if (updateFromTestCase.expectedValues != null) {
1545                             assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
1546                             assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues);
1547                         }
1548                     }
1549
1550                     // DELETE handled by TestBridge
1551                 }
1552             }
1553         }
1554     }
1555
1556     /*
1557      * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1558      *
1559      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1560      */
1561     @Test
1562     public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
1563         testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds",
1564                 new PortExternalIdsSouthboundHelper());
1565     }
1566
1567     /*
1568      * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1569      *
1570      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1571      */
1572     @Test
1573     public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
1574         testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds",
1575                 new InterfaceExternalIdsSouthboundHelper());
1576     }
1577
1578     /*
1579      * Tests the CRUD operations for <code>Interface</code> <code>lldp</code>.
1580      *
1581      * @see <code>SouthboundIT.generateInterfaceLldpTestCases()</code> for specific test case information
1582      */
1583     @Test
1584     public void testCRUDTerminationPointInterfaceLldp() throws InterruptedException {
1585         testCRUDTerminationPoint(new SouthboundInterfaceLldpBuilder(), "TPInterfaceLldp",
1586                 new InterfaceLldpSouthboundHelper());
1587     }
1588
1589     /*
1590      * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1591      *
1592      * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1593      */
1594     @Test
1595     public void testCRUDTerminationPointOptions() throws InterruptedException {
1596         testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper());
1597     }
1598
1599     /*
1600      * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1601      *
1602      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1603      */
1604     @Test
1605     public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1606         testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs",
1607                 new InterfaceOtherConfigsSouthboundHelper());
1608     }
1609
1610     /*
1611      * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1612      *
1613      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1614      */
1615     @Test
1616     public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1617         testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs",
1618                 new PortOtherConfigsSouthboundHelper());
1619     }
1620
1621     @Test
1622     public void testCRUDTerminationPoints() throws InterruptedException {
1623         String port1 = "vx1";
1624         String port2 = "vxlanport";
1625         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1626
1627         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1628             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1629             Assert.assertNotNull(bridge);
1630             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1631                     connectionInfo, bridge.getBridgeName()));
1632             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1633                     createGenericOvsdbTerminationPointAugmentationBuilder();
1634
1635             // add and delete a single port
1636             String portName = port1;
1637             ovsdbTerminationBuilder.setName(portName);
1638             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1639             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1640             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1641             Assert.assertNotNull(terminationPointNode);
1642
1643             SouthboundUtils.createInstanceIdentifier(connectionInfo,
1644                     new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
1645             portName = port1;
1646             InstanceIdentifier<TerminationPoint> nodePath =
1647                     SouthboundUtils.createInstanceIdentifier(connectionInfo,
1648                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1649                             .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1650
1651             Assert.assertTrue("failed to delete port " + portName,
1652                     mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1653             LOG.info("shague: waiting for delete {}", portName);
1654             Thread.sleep(1000);
1655             TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1656             Assert.assertNull(terminationPoint);
1657
1658             // add two ports, then delete them
1659             portName = port1;
1660             ovsdbTerminationBuilder.setName(portName);
1661             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1662             terminationPointIid = getTpIid(connectionInfo, bridge);
1663             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1664             Assert.assertNotNull(terminationPointNode);
1665
1666             portName = port2;
1667             ovsdbTerminationBuilder.setName(portName);
1668             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1669             terminationPointIid = getTpIid(connectionInfo, bridge);
1670             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1671             Assert.assertNotNull(terminationPointNode);
1672
1673             SouthboundUtils.createInstanceIdentifier(connectionInfo,
1674                     new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
1675             portName = port1;
1676             nodePath =
1677                     SouthboundUtils.createInstanceIdentifier(connectionInfo,
1678                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1679                             .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1680
1681             Assert.assertTrue("failed to delete port " + portName,
1682                     mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1683             LOG.info("shague: waiting for delete {}", portName);
1684             Thread.sleep(1000);
1685             terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1686             Assert.assertNull(terminationPoint);
1687
1688             portName = port2;
1689             nodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo,
1690                     new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1691                     .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1692
1693             Assert.assertTrue("failed to delete port " + portName,
1694                     mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1695             LOG.info("shague: waiting for delete {}", portName);
1696             Thread.sleep(1000);
1697             terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1698             Assert.assertNull(terminationPoint);
1699
1700             // DELETE handled by TestBridge
1701         }
1702     }
1703
1704     @Test
1705     public void testCRUDTerminationPointVlan() throws InterruptedException {
1706         final Integer CREATED_VLAN_ID = 4000;
1707         final Integer UPDATED_VLAN_ID = 4001;
1708
1709         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1710
1711         // CREATE
1712         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1713             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1714             Assert.assertNotNull(bridge);
1715             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1716                     connectionInfo, bridge.getBridgeName()));
1717             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1718                     createGenericOvsdbTerminationPointAugmentationBuilder();
1719             String portName = "testTerminationPointVlanId";
1720             ovsdbTerminationBuilder.setName(portName);
1721             ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
1722             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1723             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1724             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1725             Assert.assertNotNull(terminationPointNode);
1726
1727             // READ
1728             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1729             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1730             for (TerminationPoint terminationPoint : terminationPoints) {
1731                 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1732                         OvsdbTerminationPointAugmentation.class);
1733                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1734                     VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1735                     Assert.assertNotNull(actualVlanId);
1736                     Integer actualVlanIdInt = actualVlanId.getValue();
1737                     Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
1738                 }
1739             }
1740
1741             // UPDATE
1742             NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1743             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1744                     new OvsdbTerminationPointAugmentationBuilder();
1745             tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
1746             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1747             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1748             NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1749             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1750             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1751             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1752             tpUpdateBuilder.addAugmentation(
1753                     OvsdbTerminationPointAugmentation.class,
1754                     tpUpdateAugmentationBuilder.build());
1755             tpUpdateBuilder.setTpId(new TpId(portName));
1756             portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1757             Assert.assertTrue(
1758                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1759             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1760
1761             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1762             terminationPoints = terminationPointNode.getTerminationPoint();
1763             for (TerminationPoint terminationPoint : terminationPoints) {
1764                 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1765                         OvsdbTerminationPointAugmentation.class);
1766                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1767                     VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1768                     Assert.assertNotNull(actualVlanId);
1769                     Integer actualVlanIdInt = actualVlanId.getValue();
1770                     Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
1771                 }
1772             }
1773
1774             // DELETE handled by TestBridge
1775         }
1776     }
1777
1778     @Test
1779     public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1780         final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
1781         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1782         VlanMode []vlanModes = VlanMode.values();
1783         for (VlanMode vlanMode : vlanModes) {
1784             // CREATE
1785             try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1786                 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1787                 Assert.assertNotNull(bridge);
1788                 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1789                         connectionInfo, bridge.getBridgeName()));
1790                 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1791                         createGenericOvsdbTerminationPointAugmentationBuilder();
1792                 String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1793                 ovsdbTerminationBuilder.setName(portName);
1794                 ovsdbTerminationBuilder.setVlanMode(vlanMode);
1795                 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1796                 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1797                 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1798                 Assert.assertNotNull(terminationPointNode);
1799
1800                 // READ
1801                 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1802                 for (TerminationPoint terminationPoint : terminationPoints) {
1803                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1804                             terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1805                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1806                         //test
1807                         Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1808                     }
1809                 }
1810
1811                 // UPDATE
1812                 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1813                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1814                         new OvsdbTerminationPointAugmentationBuilder();
1815                 tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
1816                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1817                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1818                 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1819                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1820                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1821                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1822                 tpUpdateBuilder.addAugmentation(
1823                         OvsdbTerminationPointAugmentation.class,
1824                         tpUpdateAugmentationBuilder.build());
1825                 tpUpdateBuilder.setTpId(new TpId(portName));
1826                 portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1827                 Assert.assertTrue(
1828                         mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1829                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1830
1831                 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1832                 terminationPoints = terminationPointNode.getTerminationPoint();
1833                 for (TerminationPoint terminationPoint : terminationPoints) {
1834                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1835                             terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1836                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1837                         //test
1838                         Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
1839                     }
1840                 }
1841
1842                 // DELETE handled by TestBridge
1843             }
1844         }
1845     }
1846
1847     @SuppressWarnings("unchecked")
1848     private List<Set<Integer>> generateVlanSets() {
1849         int min = 0;
1850         int max = 4095;
1851         return Lists.newArrayList(
1852                 Collections.<Integer>emptySet(),
1853                 Collections.singleton(2222),
1854                 Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
1855     }
1856
1857     private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1858         List<Trunks> trunkList = new ArrayList<>();
1859         for (Integer trunk : trunkSet) {
1860             TrunksBuilder trunkBuilder = new TrunksBuilder();
1861             trunkBuilder.setTrunk(new VlanId(trunk));
1862             trunkList.add(trunkBuilder.build());
1863         }
1864         return trunkList;
1865     }
1866
1867     @Test
1868     public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1869         final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Collections.singleton(2011));
1870         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1871         Iterable<Set<Integer>> vlanSets = generateVlanSets();
1872         int testCase = 0;
1873         for (Set<Integer> vlanSet : vlanSets) {
1874             ++testCase;
1875             // CREATE
1876             try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1877                 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1878                 Assert.assertNotNull(bridge);
1879                 NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1880                 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1881                         createGenericOvsdbTerminationPointAugmentationBuilder();
1882                 String portName = "testTerminationPointVlanTrunks" + testCase;
1883                 ovsdbTerminationBuilder.setName(portName);
1884                 List<Trunks> trunks = buildTrunkList(vlanSet);
1885                 ovsdbTerminationBuilder.setTrunks(trunks);
1886                 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1887                 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1888                 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1889                 Assert.assertNotNull(terminationPointNode);
1890
1891                 // READ
1892                 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1893                 for (TerminationPoint terminationPoint : terminationPoints) {
1894                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1895                             terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1896                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1897                         List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1898                         for (Trunks trunk : trunks) {
1899                             Assert.assertTrue(actualTrunks.contains(trunk));
1900                         }
1901                     }
1902                 }
1903
1904
1905                 // UPDATE
1906                 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1907                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1908                         new OvsdbTerminationPointAugmentationBuilder();
1909                 tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
1910                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1911                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1912                 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1913                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1914                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1915                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1916                 tpUpdateBuilder.addAugmentation(
1917                         OvsdbTerminationPointAugmentation.class,
1918                         tpUpdateAugmentationBuilder.build());
1919                 tpUpdateBuilder.setTpId(new TpId(portName));
1920                 portUpdateNodeBuilder.setTerminationPoint(Collections.singletonList(tpUpdateBuilder.build()));
1921                 Assert.assertTrue(
1922                         mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1923                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1924
1925                 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1926                 terminationPoints = terminationPointNode.getTerminationPoint();
1927                 for (TerminationPoint terminationPoint : terminationPoints) {
1928                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1929                             terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1930                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1931                         //test
1932                         Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
1933                     }
1934                 }
1935
1936                 // DELETE handled by TestBridge
1937             }
1938         }
1939     }
1940
1941     /*
1942      * Tests setting and deleting <code>qos</code> field in a <code>port</code>.
1943      */
1944     @Test
1945     public void testCRUDTerminationPointQos() throws InterruptedException {
1946         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1947         String testQosId = "testQosEntry";
1948
1949         // CREATE
1950         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1951                 TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
1952                         SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HFSC), null, null)) {
1953             OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1954                     LogicalDatastoreType.OPERATIONAL);
1955             QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
1956             Assert.assertNotNull(operQos);
1957             Uuid qosUuid = new Uuid(operQos.getQosUuid().getValue());
1958
1959             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1960             Assert.assertNotNull(bridge);
1961             NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1962             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1963                     createGenericOvsdbTerminationPointAugmentationBuilder();
1964             String portName = "testTerminationPointQos";
1965             ovsdbTerminationBuilder.setName(portName);
1966             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1967
1968
1969            // READ and check that qos uuid has been added to the port
1970             InstanceIdentifier<TerminationPoint> tpEntryIid = getTpIid(connectionInfo, bridge)
1971                     .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1972             TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid);
1973             Assert.assertNotNull(terminationPoint);
1974
1975             // UPDATE - remove the qos entry from the port
1976             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1977                     new OvsdbTerminationPointAugmentationBuilder();
1978             tpUpdateAugmentationBuilder.setName(portName);
1979             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1980             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1981             tpUpdateBuilder.addAugmentation(
1982                     OvsdbTerminationPointAugmentation.class,
1983                     tpUpdateAugmentationBuilder.build());
1984             tpUpdateBuilder.setTpId(new TpId(portName));
1985
1986             Assert.assertTrue(
1987                     mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpEntryIid, tpUpdateBuilder.build()));
1988             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1989
1990             // READ and verify that qos uuid has been removed from port
1991             TerminationPoint terminationPointUpdate = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid);
1992             Assert.assertNotNull(terminationPointUpdate);
1993
1994             // DELETE handled by TestBridge
1995         }
1996     }
1997
1998     @Test
1999     public void testGetOvsdbNodes() throws InterruptedException {
2000         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2001         InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
2002                 .create(NetworkTopology.class)
2003                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
2004
2005         Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
2006         InstanceIdentifier<Node> expectedNodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
2007         NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class).getNodeId();
2008         Node foundNode = null;
2009         Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
2010         Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
2011         LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
2012         for (Node node : topology.getNode()) {
2013             if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
2014                 foundNode = node;
2015                 break;
2016             }
2017         }
2018         Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
2019     }
2020
2021     /*
2022      * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
2023      */
2024     @Test
2025     public void testCRUDBridgeOtherConfigs() throws InterruptedException {
2026         testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(),
2027                 new BridgeOtherConfigsSouthboundHelper());
2028     }
2029
2030     private interface SouthboundBridgeHelper<T> {
2031         void writeValues(OvsdbBridgeAugmentationBuilder builder, List<T> values);
2032         List<T> readValues(OvsdbBridgeAugmentation augmentation);
2033     }
2034
2035     private <T> void testCRUDBridge(String prefix, KeyValueBuilder<T> builder, SouthboundBridgeHelper<T> helper)
2036             throws InterruptedException {
2037         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2038         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2039         // the update has been performed.
2040         List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2041         List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2042         for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
2043             for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
2044                 String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name);
2045
2046                 // CREATE: Create the test bridge
2047                 final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName);
2048                 final InstanceIdentifier<Node> bridgeIid =
2049                         SouthboundUtils.createInstanceIdentifier(connectionInfo, ovsdbBridgeName);
2050                 final NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
2051                 final NodeBuilder bridgeCreateNodeBuilder = new NodeBuilder();
2052                 bridgeCreateNodeBuilder.setNodeId(bridgeNodeId);
2053                 OvsdbBridgeAugmentationBuilder bridgeCreateAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
2054                 bridgeCreateAugmentationBuilder.setBridgeName(ovsdbBridgeName);
2055                 bridgeCreateAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
2056                 bridgeCreateAugmentationBuilder.setFailMode(
2057                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
2058                 setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo);
2059                 helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues);
2060                 bridgeCreateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
2061                         bridgeCreateAugmentationBuilder.build());
2062                 LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder.toString());
2063                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2064                         bridgeCreateNodeBuilder.build()));
2065                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2066
2067                 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2068                 // then repeat for OPERATIONAL data store
2069                 List<T> updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
2070                         LogicalDatastoreType.CONFIGURATION));
2071                 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds);
2072                 List<T> updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
2073                 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds);
2074
2075                 // UPDATE:  update the values
2076                 final OvsdbBridgeAugmentationBuilder bridgeUpdateAugmentationBuilder =
2077                         new OvsdbBridgeAugmentationBuilder();
2078                 helper.writeValues(bridgeUpdateAugmentationBuilder, updateToTestCase.inputValues);
2079                 final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder();
2080                 final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
2081                 bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId());
2082                 bridgeUpdateNodeBuilder.setKey(bridgeNode.getKey());
2083                 bridgeUpdateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
2084                         bridgeUpdateAugmentationBuilder.build());
2085                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2086                         bridgeUpdateNodeBuilder.build()));
2087                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2088
2089                 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2090                 // then repeat for OPERATIONAL data store
2091                 List<T> updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
2092                         LogicalDatastoreType.CONFIGURATION));
2093                 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds);
2094                 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds);
2095                 List<T> updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
2096                 if (updateFromTestCase.expectedValues != null) {
2097                     assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds);
2098                     assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds);
2099                 }
2100
2101                 // DELETE
2102                 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid));
2103                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2104             }
2105         }
2106     }
2107
2108     /*
2109      * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
2110      */
2111     @Test
2112     public void testCRUDBridgeExternalIds() throws InterruptedException {
2113         testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(),
2114                 new BridgeExternalIdsSouthboundHelper());
2115     }
2116
2117     @Test
2118     public void testAddDeleteQos() throws InterruptedException {
2119         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2120         OvsdbNodeAugmentation ovsdbNodeAugmentation;
2121         Uri qosUri = new Uri("QOS-ROW");
2122         List<String> typeList = new ArrayList<>();
2123         typeList.add(SouthboundConstants.QOS_LINUX_HTB);
2124         typeList.add(SouthboundConstants.QOS_LINUX_HFSC);
2125
2126         for (String qosType : typeList) {
2127             try (TestQos testQos = new TestQos(connectionInfo, qosUri, SouthboundMapper.createQosType(qosType), null, null)) {
2128                 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2129                         LogicalDatastoreType.OPERATIONAL);
2130                 QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
2131                 Assert.assertNotNull(operQosHtb);
2132             }
2133             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2134                     LogicalDatastoreType.OPERATIONAL);
2135             QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
2136             Assert.assertNull(operQosHtb);
2137         }
2138     }
2139
2140     @Test
2141     public void testAddDeleteQueue() throws InterruptedException {
2142         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2143         Uri queueUri = new Uri("QUEUE-A1");
2144
2145         try (TestQueue testQueue = new TestQueue(connectionInfo, queueUri, new Short("25"), null, null)) {
2146             OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2147                     LogicalDatastoreType.OPERATIONAL);
2148             Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
2149             Assert.assertNotNull(operQueue);
2150         }
2151         OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2152                 LogicalDatastoreType.OPERATIONAL);
2153         Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
2154         Assert.assertNull(operQueue);
2155     }
2156
2157     private static class SouthboundQueuesExternalIdsHelper implements SouthboundQueueHelper<QueuesExternalIds> {
2158         @Override
2159         public void writeValues(QueuesBuilder builder, List<QueuesExternalIds> values) {
2160             builder.setQueuesExternalIds(values);
2161         }
2162
2163         @Override
2164         public List<QueuesExternalIds> readValues(Queues queue) {
2165             return queue.getQueuesExternalIds();
2166         }
2167     }
2168
2169     private static class SouthboundQueuesOtherConfigHelper implements SouthboundQueueHelper<QueuesOtherConfig> {
2170         @Override
2171         public void writeValues(QueuesBuilder builder, List<QueuesOtherConfig> values) {
2172             builder.setQueuesOtherConfig(values);
2173         }
2174
2175         @Override
2176         public List<QueuesOtherConfig> readValues(Queues queue) {
2177             return queue.getQueuesOtherConfig();
2178         }
2179     }
2180
2181     private interface SouthboundQueueHelper<T> {
2182         void writeValues(QueuesBuilder builder, List<T> values);
2183         List<T> readValues(Queues queue);
2184     }
2185
2186     private Queues getQueue(Uri queueId, OvsdbNodeAugmentation node) {
2187         for (Queues queue : node.getQueues()) {
2188             if (queue.getKey().getQueueId().getValue().equals(queueId.getValue()))
2189                 return queue;
2190         }
2191         return null;
2192     }
2193
2194     private static class SouthboundQosExternalIdsHelper implements SouthboundQosHelper<QosExternalIds> {
2195         @Override
2196         public void writeValues(QosEntriesBuilder builder, List<QosExternalIds> values) {
2197             builder.setQosExternalIds(values);
2198         }
2199
2200         @Override
2201         public List<QosExternalIds> readValues(QosEntries qos) {
2202             return qos.getQosExternalIds();
2203         }
2204     }
2205
2206     private static class SouthboundQosOtherConfigHelper implements SouthboundQosHelper<QosOtherConfig> {
2207         @Override
2208         public void writeValues(QosEntriesBuilder builder, List<QosOtherConfig> values) {
2209             builder.setQosOtherConfig(values);
2210         }
2211
2212         @Override
2213         public List<QosOtherConfig> readValues(QosEntries qos) {
2214             return qos.getQosOtherConfig();
2215         }
2216     }
2217
2218     private interface SouthboundQosHelper<T> {
2219         void writeValues(QosEntriesBuilder builder, List<T> values);
2220         List<T> readValues(QosEntries qos);
2221     }
2222
2223     private QosEntries getQos(Uri qosId, OvsdbNodeAugmentation node) {
2224         for (QosEntries qos : node.getQosEntries()) {
2225             if (qos.getKey().getQosId().equals(qosId))
2226                 return qos;
2227         }
2228         return null;
2229     }
2230
2231     private <T> void testCRUDQueue(
2232             KeyValueBuilder<T> builder, String prefix, SouthboundQueueHelper<T> helper)
2233             throws InterruptedException {
2234
2235         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2236
2237         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2238         // the update has been performed.
2239         List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2240         List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2241
2242         for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
2243             for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
2244                 String testQueueId = String.format("%s_%s", prefix, updateToTestCase.name);
2245
2246                 // CREATE: and update the test queue with starting values.
2247                 try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), new Short("45"), null, null)) {
2248                     QueuesBuilder queuesBuilder = new QueuesBuilder();
2249                     queuesBuilder.setQueueId(new Uri(testQueueId));
2250                     InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2251                             .augmentation(OvsdbNodeAugmentation.class)
2252                             .child(Queues.class, queuesBuilder.build().getKey());
2253                     final NotifyingDataChangeListener queueConfigurationListener =
2254                             new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, queueIid);
2255                     queueConfigurationListener.registerDataChangeListener();
2256                     final NotifyingDataChangeListener queueOperationalListener =
2257                             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
2258                     queueOperationalListener.registerDataChangeListener();
2259
2260                     helper.writeValues(queuesBuilder, updateFromTestCase.inputValues);
2261                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2262                             queueIid, queuesBuilder.build()));
2263                     queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2264
2265                     // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
2266                     // then repeat for OPERATIONAL data store
2267                     OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2268                             LogicalDatastoreType.CONFIGURATION);
2269                     Queues queueFromConfig = getQueue(new Uri(testQueueId), updateFromConfigurationOvsdbNodeAugmentation);
2270                     if (queueFromConfig != null) {
2271                         List<T> updateFromConfigurationValues =
2272                                 helper.readValues(queueFromConfig);
2273                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
2274                     }
2275
2276                     queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2277                     OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2278                             LogicalDatastoreType.OPERATIONAL);
2279                     Queues queueFromOper = getQueue(new Uri(testQueueId), updateFromOperationalOvsdbNodeAugmentation);
2280                     if (queueFromOper != null) {
2281                         List<T> updateFromOperationalValues =
2282                                 helper.readValues(queueFromOper);
2283                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
2284                     }
2285
2286                     // UPDATE:  update the values
2287                     QueuesBuilder queuesUpdateBuilder = new QueuesBuilder();
2288                     queuesUpdateBuilder.setQueueId(new Uri(testQueueId));
2289                     helper.writeValues(queuesUpdateBuilder, updateToTestCase.inputValues);
2290                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2291                             queueIid, queuesUpdateBuilder.build()));
2292                     queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2293
2294                     // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
2295                     // then repeat for OPERATIONAL data store
2296                     OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2297                             LogicalDatastoreType.CONFIGURATION);
2298                     Queues queueToConfig = getQueue(new Uri(testQueueId), updateToConfigurationOvsdbNodeAugmentation);
2299                     if (queueToConfig != null) {
2300                         List<T> updateToConfigurationValues =
2301                                 helper.readValues(queueToConfig);
2302                         assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
2303                     }
2304
2305                     queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2306                     OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2307                             LogicalDatastoreType.OPERATIONAL);
2308                     Queues queueToOper = getQueue(new Uri(testQueueId), updateToOperationalOvsdbNodeAugmentation);
2309                     if (queueToOper != null) {
2310                         List<T> updateToOperationalValues =
2311                                 helper.readValues(queueToOper);
2312                         assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
2313                     }
2314
2315                     // DELETE handled by TestQueue
2316                 }
2317             }
2318         }
2319     }
2320
2321     @Test
2322     public void testCRUDQueueExternalIds() throws InterruptedException {
2323         testCRUDQueue(new SouthboundQueuesExternalIdsBuilder(), "QueueExternalIds",
2324                 new SouthboundQueuesExternalIdsHelper());
2325     }
2326
2327     @Test
2328     public void testCRUDQueueOtherConfig() throws InterruptedException {
2329         testCRUDQueue(new SouthboundQueuesOtherConfigBuilder(), "QueueOtherConfig",
2330                 new SouthboundQueuesOtherConfigHelper());
2331     }
2332
2333     @Test
2334     public void testCRUDQueueDscp() throws InterruptedException {
2335         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2336         String testQueueId = "testQueueDscp";
2337
2338         // CREATE: and update the test queue with starting values.
2339         try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), new Short("0"), null, null)) {
2340             for (Short dscp = 1; dscp < 64; dscp++) {
2341                 QueuesBuilder queuesBuilder = new QueuesBuilder();
2342                 queuesBuilder.setQueueId(new Uri(testQueueId));
2343                 InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2344                         .augmentation(OvsdbNodeAugmentation.class)
2345                         .child(Queues.class, queuesBuilder.build().getKey());
2346                 final NotifyingDataChangeListener queueOperationalListener =
2347                         new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
2348                 queueOperationalListener.registerDataChangeListener();
2349
2350                 queuesBuilder.setDscp(dscp);
2351                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2352                         queueIid, queuesBuilder.build()));
2353                 queueOperationalListener.waitForUpdate(OVSDB_ROUNDTRIP_TIMEOUT);
2354
2355                 // READ: Read the test queue and ensure changes are propagated to the OPERATIONAL data store
2356                 // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2357                 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2358                         LogicalDatastoreType.OPERATIONAL);
2359                 Queues operQueue = getQueue(new Uri(testQueueId), ovsdbNodeAugmentation);
2360                 Assert.assertNotNull(operQueue);
2361                 Short operDscp = operQueue.getDscp();
2362                 Assert.assertNotNull(operDscp);
2363                 Assert.assertEquals(dscp, operDscp);
2364             }
2365
2366             // DELETE handled by TestQueue
2367         }
2368
2369     }
2370
2371     private <T> void testCRUDQos(
2372             KeyValueBuilder<T> builder, String prefix, SouthboundQosHelper<T> helper)
2373             throws InterruptedException {
2374
2375         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2376
2377         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2378         // the update has been performed.
2379         List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2380         List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2381
2382         for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
2383             for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
2384                 String testQosId = String.format("%s_%s", prefix, updateToTestCase.name);
2385
2386                 // CREATE: and update the test qos with starting values.
2387                 try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId), SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null)) {
2388                     QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
2389                     qosBuilder.setQosId(new Uri(testQosId));
2390                     InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2391                             .augmentation(OvsdbNodeAugmentation.class)
2392                             .child(QosEntries.class, qosBuilder.build().getKey());
2393                     final NotifyingDataChangeListener qosConfigurationListener =
2394                             new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, qosIid);
2395                     qosConfigurationListener.registerDataChangeListener();
2396                     final NotifyingDataChangeListener qosOperationalListener =
2397                             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
2398                     qosOperationalListener.registerDataChangeListener();
2399
2400                     helper.writeValues(qosBuilder, updateFromTestCase.inputValues);
2401                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2402                             qosIid, qosBuilder.build()));
2403                     qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2404
2405                     // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
2406                     // then repeat for OPERATIONAL data store
2407                     OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2408                             LogicalDatastoreType.CONFIGURATION);
2409                     QosEntries qosFromConfig = getQos(new Uri(testQosId), updateFromConfigurationOvsdbNodeAugmentation);
2410                     if (qosFromConfig != null) {
2411                         List<T> updateFromConfigurationValues =
2412                                 helper.readValues(qosFromConfig);
2413                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
2414                     }
2415
2416                     qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2417                     OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2418                             LogicalDatastoreType.OPERATIONAL);
2419                     QosEntries qosFromOper = getQos(new Uri(testQosId), updateFromOperationalOvsdbNodeAugmentation);
2420                     if (qosFromOper != null) {
2421                         List<T> updateFromOperationalValues =
2422                                 helper.readValues(qosFromOper);
2423                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
2424                     }
2425
2426                     // UPDATE:  update the values
2427                     QosEntriesBuilder qosUpdateBuilder = new QosEntriesBuilder();
2428                     qosUpdateBuilder.setQosId(new Uri(testQosId));
2429                     helper.writeValues(qosUpdateBuilder, updateToTestCase.inputValues);
2430                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2431                             qosIid, qosUpdateBuilder.build()));
2432                     qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2433
2434                     // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
2435                     // then repeat for OPERATIONAL data store
2436                     OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2437                             LogicalDatastoreType.CONFIGURATION);
2438                     QosEntries qosToConfig = getQos(new Uri(testQosId), updateToConfigurationOvsdbNodeAugmentation);
2439                     if (qosToConfig != null) {
2440                         List<T> updateToConfigurationValues =
2441                                 helper.readValues(qosToConfig);
2442                         assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
2443                     }
2444
2445                     qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2446                     OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2447                             LogicalDatastoreType.OPERATIONAL);
2448                     QosEntries qosToOper = getQos(new Uri(testQosId), updateToOperationalOvsdbNodeAugmentation);
2449                     if (qosToOper != null) {
2450                         List<T> updateToOperationalValues =
2451                                 helper.readValues(qosToOper);
2452                         assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
2453                     }
2454
2455                     // DELETE handled by TestQueue
2456                 }
2457             }
2458         }
2459     }
2460
2461     @Test
2462     public void testCRUDQosExternalIds() throws InterruptedException {
2463         testCRUDQos(new SouthboundQosExternalIdsBuilder(), "QosExternalIds",
2464                 new SouthboundQosExternalIdsHelper());
2465     }
2466
2467     @Test
2468     public void testCRUDQosOtherConfig() throws InterruptedException {
2469         testCRUDQos(new SouthboundQosOtherConfigBuilder(), "QosOtherConfig",
2470                 new SouthboundQosOtherConfigHelper());
2471     }
2472     @Test
2473     public void testCRUDQosQueues() throws InterruptedException {
2474         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2475         String testQosId = "testQosQueues";
2476
2477         // CREATE: and update the test queue with starting values.
2478         try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
2479                 SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null);
2480                 TestQueue testQueue1 = new TestQueue(connectionInfo, new Uri("queue1"), new Short("12"), null, null);
2481                 TestQueue testQueue2 = new TestQueue(connectionInfo, new Uri("queue2"), new Short("35"), null, null)) {
2482             QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
2483             qosBuilder.setQosId(new Uri(testQosId));
2484             InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2485                     .augmentation(OvsdbNodeAugmentation.class)
2486                     .child(QosEntries.class, qosBuilder.build().getKey());
2487             final NotifyingDataChangeListener qosOperationalListener =
2488                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
2489             qosOperationalListener.registerDataChangeListener();
2490
2491             // READ, UPDATE:  Read the UUIDs of the Queue rows and add them to the
2492             // configuration of the Qos row.
2493             OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2494                     LogicalDatastoreType.OPERATIONAL);
2495
2496             Queues operQueue1 = getQueue(new Uri("queue1"), ovsdbNodeAugmentation);
2497
2498             Assert.assertNotNull(operQueue1);
2499
2500             InstanceIdentifier<Queues> queue1Iid = testQueue1.getInstanceIdentifier();
2501             OvsdbQueueRef queue1Ref = new OvsdbQueueRef(queue1Iid);
2502
2503             Queues operQueue2 = getQueue(new Uri("queue2"), ovsdbNodeAugmentation);
2504             Assert.assertNotNull(operQueue2);
2505             InstanceIdentifier<Queues> queue2Iid = testQueue2.getInstanceIdentifier();
2506             OvsdbQueueRef queue2Ref = new OvsdbQueueRef(queue2Iid);
2507
2508             List<QueueList> queueList = new ArrayList<>();
2509             queueList.add(new QueueListBuilder().setQueueNumber(new Long("1")).setQueueRef(queue1Ref).build());
2510             queueList.add(new QueueListBuilder().setQueueNumber(new Long("2")).setQueueRef(queue2Ref).build());
2511
2512             qosBuilder.setQueueList(queueList);
2513
2514             Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2515                     qosIid, qosBuilder.build()));
2516             qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2517
2518             // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
2519             // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2520             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2521                     LogicalDatastoreType.OPERATIONAL);
2522             QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2523             Assert.assertNotNull(operQos);
2524             List<QueueList> operQueueList = operQos.getQueueList();
2525             Assert.assertNotNull(operQueueList);
2526             for (QueueList queueEntry : queueList) {
2527                 Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
2528             }
2529
2530             // DELETE one queue from queue list and check that one remains
2531             KeyedInstanceIdentifier<QueueList, QueueListKey> qosQueueIid = qosIid
2532                     .child(QueueList.class, new QueueListKey(new Long("1")));
2533             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
2534             qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2535
2536             // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
2537             // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2538             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2539                     LogicalDatastoreType.OPERATIONAL);
2540             operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2541             Assert.assertNotNull(operQos);
2542             operQueueList = operQos.getQueueList();
2543             Assert.assertNotNull(operQueueList);
2544
2545             for (QueueList queueEntry : queueList) {
2546                 if (queueEntry.getQueueRef().equals(queue2Ref)) {
2547                     Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
2548                 } else if (queueEntry.getQueueRef().equals(queue1Ref)) {
2549                     Assert.assertFalse(isQueueInList(operQueueList, queueEntry));
2550                 } else {
2551                     Assert.assertTrue("Unknown queue entry in qos queue list", false);
2552                 }
2553             }
2554
2555             // DELETE  queue list and check that list is empty
2556             qosQueueIid = qosIid
2557                     .child(QueueList.class, new QueueListKey(new Long("1")));
2558             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
2559             qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2560
2561             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2562                     LogicalDatastoreType.OPERATIONAL);
2563             operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2564             Assert.assertNotNull(operQos);
2565             operQueueList = operQos.getQueueList();
2566             Assert.assertNotNull(operQueueList);
2567             Assert.assertTrue(operQueueList.isEmpty());
2568         }
2569     }
2570
2571
2572
2573     private Boolean isQueueInList(List<QueueList> queueList, QueueList queue) {
2574         for (QueueList queueEntry : queueList) {
2575             if (queueEntry.getQueueNumber().equals(queue.getQueueNumber())&& queueEntry.getQueueRef().equals(queue.getQueueRef())) {
2576                 return true;
2577             }
2578         }
2579         return false;
2580     }
2581
2582     /**
2583      * <p>
2584      * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
2585      * expected values. The input values are provided to the augmentation builder, and the expected values are checked
2586      * against the output of the resulting augmentation.
2587      * </p>
2588      * <p>
2589      * Instances of this class are immutable.
2590      * </p>
2591      *
2592      * @param <T> The type of data used for the test case.
2593      */
2594     private static final class SouthboundTestCase<T> {
2595         private final String name;
2596         private final List<T> inputValues;
2597         private final List<T> expectedValues;
2598
2599         /**
2600          * Creates an instance of a southbound test case.
2601          *
2602          * @param name The test case's name.
2603          * @param inputValues The input values (provided as input to the underlying augmentation builder).
2604          * @param expectedValues The expected values (checked against the output of the underlying augmentation).
2605          */
2606         public SouthboundTestCase(
2607                 final String name, final List<T> inputValues, final List<T> expectedValues) {
2608             this.name = name;
2609             this.inputValues = inputValues;
2610             this.expectedValues = expectedValues;
2611         }
2612     }
2613
2614     /**
2615      * Southbound test case builder.
2616      *
2617      * @param <T> The type of data used for the test case.
2618      */
2619     private static final class SouthboundTestCaseBuilder<T> {
2620         private String name;
2621         private List<T> inputValues;
2622         private List<T> expectedValues;
2623
2624         /**
2625          * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
2626          * builders. There are no default values.
2627          */
2628         public SouthboundTestCaseBuilder() {
2629             // Nothing to do
2630         }
2631
2632         /**
2633          * Sets the test case's name.
2634          *
2635          * @param name The test case's name.
2636          * @return The builder.
2637          */
2638         public SouthboundTestCaseBuilder<T> name(final String name) {
2639             this.name = name;
2640             return this;
2641         }
2642
2643         /**
2644          * Sets the input values.
2645          *
2646          * @param inputValues The input values.
2647          * @return The builder.
2648          */
2649         @SafeVarargs
2650         public final SouthboundTestCaseBuilder<T> input(final T... inputValues) {
2651             this.inputValues = Lists.newArrayList(inputValues);
2652             return this;
2653         }
2654
2655         /**
2656          * Indicates that the provided input values should be expected as output values.
2657          *
2658          * @return The builder.
2659          */
2660         public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
2661             this.expectedValues = this.inputValues;
2662             return this;
2663         }
2664
2665         /**
2666          * Indicates that no output should be expected.
2667          *
2668          * @return The builder.
2669          */
2670         public SouthboundTestCaseBuilder<T> expectNoOutput() {
2671             this.expectedValues = null;
2672             return this;
2673         }
2674
2675         /**
2676          * Builds an immutable instance representing the test case.
2677          *
2678          * @return The test case.
2679          */
2680         @SuppressWarnings("unchecked")
2681         public SouthboundTestCase<T> build() {
2682             return new SouthboundTestCase<>(name, inputValues, expectedValues);
2683         }
2684     }
2685
2686     private abstract static class KeyValueBuilder<T> {
2687         private static final int COUNTER_START = 0;
2688         private int counter = COUNTER_START;
2689
2690         protected abstract Builder<T> builder();
2691
2692         protected abstract void setKey(Builder<T> builder, String key);
2693
2694         protected abstract void setValue(Builder<T> builder, String value);
2695
2696         protected abstract boolean isValueMandatory();
2697
2698         public final T build(final String testName, final String key, final String value) {
2699             final Builder<T> builder = builder();
2700             this.counter++;
2701             if (key != null) {
2702                 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
2703             }
2704             if (value != null) {
2705                 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
2706             }
2707             return builder.build();
2708         }
2709
2710         public final void reset() {
2711             this.counter = COUNTER_START;
2712         }
2713     }
2714
2715     private static final class SouthboundQueuesExternalIdsBuilder extends KeyValueBuilder<QueuesExternalIds> {
2716         @Override
2717         protected Builder<QueuesExternalIds> builder() {
2718             return new QueuesExternalIdsBuilder();
2719         }
2720
2721         @Override
2722         protected void setKey(Builder<QueuesExternalIds> builder, String key) {
2723             ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdKey(key);
2724         }
2725
2726         @Override
2727         protected void setValue(Builder<QueuesExternalIds> builder, String value) {
2728             ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdValue(value);
2729         }
2730
2731         @Override
2732         protected boolean isValueMandatory() {
2733             return true;
2734         }
2735     }
2736
2737     private static final class SouthboundQueuesOtherConfigBuilder extends KeyValueBuilder<QueuesOtherConfig> {
2738         @Override
2739         protected Builder<QueuesOtherConfig> builder() {
2740             return new QueuesOtherConfigBuilder();
2741         }
2742
2743         @Override
2744         protected void setKey(Builder<QueuesOtherConfig> builder, String key) {
2745             ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigKey(key);
2746         }
2747
2748         @Override
2749         protected void setValue(Builder<QueuesOtherConfig> builder, String value) {
2750             ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigValue(value);
2751         }
2752
2753         @Override
2754         protected boolean isValueMandatory() {
2755             return false;
2756         }
2757     }
2758
2759     private static final class SouthboundQosExternalIdsBuilder extends KeyValueBuilder<QosExternalIds> {
2760         @Override
2761         protected Builder<QosExternalIds> builder() {
2762             return new QosExternalIdsBuilder();
2763         }
2764
2765         @Override
2766         protected void setKey(Builder<QosExternalIds> builder, String key) {
2767             ((QosExternalIdsBuilder) builder).setQosExternalIdKey(key);
2768         }
2769
2770         @Override
2771         protected void setValue(Builder<QosExternalIds> builder, String value) {
2772             ((QosExternalIdsBuilder) builder).setQosExternalIdValue(value);
2773         }
2774
2775         @Override
2776         protected boolean isValueMandatory() {
2777             return true;
2778         }
2779     }
2780
2781     private static final class SouthboundQosOtherConfigBuilder extends KeyValueBuilder<QosOtherConfig> {
2782         @Override
2783         protected Builder<QosOtherConfig> builder() {
2784             return new QosOtherConfigBuilder();
2785         }
2786
2787         @Override
2788         protected void setKey(Builder<QosOtherConfig> builder, String key) {
2789             ((QosOtherConfigBuilder) builder).setOtherConfigKey(key);
2790         }
2791
2792         @Override
2793         protected void setValue(Builder<QosOtherConfig> builder, String value) {
2794             ((QosOtherConfigBuilder) builder).setOtherConfigValue(value);
2795         }
2796
2797         @Override
2798         protected boolean isValueMandatory() {
2799             return false;
2800         }
2801     }
2802
2803     private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
2804         @Override
2805         protected Builder<PortExternalIds> builder() {
2806             return new PortExternalIdsBuilder();
2807         }
2808
2809         @Override
2810         protected void setKey(Builder<PortExternalIds> builder, String key) {
2811             ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
2812         }
2813
2814         @Override
2815         protected void setValue(Builder<PortExternalIds> builder, String value) {
2816             ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
2817         }
2818
2819         @Override
2820         protected boolean isValueMandatory() {
2821             return true;
2822         }
2823     }
2824
2825     private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
2826         @Override
2827         protected Builder<InterfaceExternalIds> builder() {
2828             return new InterfaceExternalIdsBuilder();
2829         }
2830
2831         @Override
2832         protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
2833             ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
2834         }
2835
2836         @Override
2837         protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
2838             ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
2839         }
2840
2841         @Override
2842         protected boolean isValueMandatory() {
2843             return true;
2844         }
2845     }
2846
2847     private static final class SouthboundInterfaceLldpBuilder extends KeyValueBuilder<InterfaceLldp> {
2848         @Override
2849         protected Builder<InterfaceLldp> builder() {
2850             return new InterfaceLldpBuilder();
2851         }
2852
2853         @Override
2854         protected void setKey(Builder<InterfaceLldp> builder, String key) {
2855             ((InterfaceLldpBuilder) builder).setLldpKey((key));
2856         }
2857
2858         @Override
2859         protected void setValue(Builder<InterfaceLldp> builder, String value) {
2860             ((InterfaceLldpBuilder) builder).setLldpValue(value);
2861         }
2862
2863         @Override
2864         protected boolean isValueMandatory() {
2865             return true;
2866         }
2867     }
2868
2869     private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
2870         @Override
2871         protected Builder<Options> builder() {
2872             return new OptionsBuilder();
2873         }
2874
2875         @Override
2876         protected void setKey(Builder<Options> builder, String key) {
2877             ((OptionsBuilder) builder).setOption(key);
2878         }
2879
2880         @Override
2881         protected void setValue(Builder<Options> builder, String value) {
2882             ((OptionsBuilder) builder).setValue(value);
2883         }
2884
2885         @Override
2886         protected boolean isValueMandatory() {
2887             return false;
2888         }
2889     }
2890
2891     private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
2892         @Override
2893         protected Builder<InterfaceOtherConfigs> builder() {
2894             return new InterfaceOtherConfigsBuilder();
2895         }
2896
2897         @Override
2898         protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
2899             ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
2900         }
2901
2902         @Override
2903         protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
2904             ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
2905         }
2906
2907         @Override
2908         protected boolean isValueMandatory() {
2909             return false;
2910         }
2911     }
2912
2913     private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
2914         @Override
2915         protected Builder<PortOtherConfigs> builder() {
2916             return new PortOtherConfigsBuilder();
2917         }
2918
2919         @Override
2920         protected void setKey(Builder<PortOtherConfigs> builder, String key) {
2921             ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
2922         }
2923
2924         @Override
2925         protected void setValue(Builder<PortOtherConfigs> builder, String value) {
2926             ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
2927         }
2928
2929         @Override
2930         protected boolean isValueMandatory() {
2931             return false;
2932         }
2933     }
2934
2935     private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
2936         @Override
2937         protected Builder<BridgeOtherConfigs> builder() {
2938             return new BridgeOtherConfigsBuilder();
2939         }
2940
2941         @Override
2942         protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
2943             ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
2944         }
2945
2946         @Override
2947         protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
2948             ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
2949         }
2950
2951         @Override
2952         protected boolean isValueMandatory() {
2953             return false;
2954         }
2955     }
2956
2957     private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
2958         @Override
2959         protected Builder<BridgeExternalIds> builder() {
2960             return new BridgeExternalIdsBuilder();
2961         }
2962
2963         @Override
2964         protected void setKey(Builder<BridgeExternalIds> builder, String key) {
2965             ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
2966         }
2967
2968         @Override
2969         protected void setValue(Builder<BridgeExternalIds> builder, String value) {
2970             ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
2971         }
2972
2973         @Override
2974         protected boolean isValueMandatory() {
2975             return true;
2976         }
2977     }
2978
2979     /*
2980      * Generates the test cases involved in testing key-value-based data.  See inline comments for descriptions of
2981      * the particular cases considered.
2982      */
2983     private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
2984             KeyValueBuilder<T> builder, String testName) {
2985         List<SouthboundTestCase<T>> testCases = new ArrayList<>();
2986
2987         final String GOOD_KEY = "GoodKey";
2988         final String GOOD_VALUE = "GoodValue";
2989         final String NO_VALUE_FOR_KEY = "NoValueForKey";
2990
2991         final String idKey = testName + "Key";
2992         final String idValue = testName + "Value";
2993
2994         // Test Case 1:  TestOne
2995         // Test Type:    Positive
2996         // Description:  Create a termination point with one value
2997         // Expected:     A port is created with the single value specified below
2998         final String testOneName = "TestOne" + testName;
2999         testCases.add(new SouthboundTestCaseBuilder<T>()
3000                 .name(testOneName)
3001                 .input(builder.build(testOneName, idKey, idValue))
3002                 .expectInputAsOutput()
3003                 .build());
3004         builder.reset();
3005
3006         // Test Case 2:  TestFive
3007         // Test Type:    Positive
3008         // Description:  Create a termination point with multiple (five) values
3009         // Expected:     A port is created with the five values specified below
3010         final String testFiveName = "TestFive" + testName;
3011         testCases.add(new SouthboundTestCaseBuilder<T>()
3012                 .name(testFiveName)
3013                 .input(
3014                         builder.build(testFiveName, idKey, idValue),
3015                         builder.build(testFiveName, idKey, idValue),
3016                         builder.build(testFiveName, idKey, idValue),
3017                         builder.build(testFiveName, idKey, idValue),
3018                         builder.build(testFiveName, idKey, idValue))
3019                 .expectInputAsOutput()
3020                 .build());
3021         builder.reset();
3022
3023         if (!builder.isValueMandatory()) {
3024             // Test Case 3:  TestOneGoodOneMalformedValue
3025             // Test Type:    Negative
3026             // Description:
3027             //     One perfectly fine input
3028             //        (TestOneGoodOneMalformedValue_GoodKey_1,
3029             //        TestOneGoodOneMalformedValue_GoodValue_1)
3030             //     and one malformed input which only has key specified
3031             //        (TestOneGoodOneMalformedValue_NoValueForKey_2,
3032             //        UNSPECIFIED)
3033             // Expected:     A port is created without any values
3034             final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName;
3035             testCases.add(new SouthboundTestCaseBuilder<T>()
3036                     .name(testOneGoodOneMalformedValueName)
3037                     .input(
3038                             builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
3039                             builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null))
3040                     .expectNoOutput()
3041                     .build());
3042             builder.reset();
3043         } else {
3044             LOG.info("generateKeyValueTestCases: skipping test case 3 for {}", builder.getClass().getSimpleName());
3045         }
3046
3047         return testCases;
3048     }
3049
3050     private static class PortExternalIdsSouthboundHelper implements SouthboundTerminationPointHelper<PortExternalIds> {
3051         @Override
3052         public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<PortExternalIds> values) {
3053             builder.setPortExternalIds(values);
3054         }
3055
3056         @Override
3057         public List<PortExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
3058             return augmentation.getPortExternalIds();
3059         }
3060     }
3061
3062     private static class InterfaceExternalIdsSouthboundHelper implements
3063             SouthboundTerminationPointHelper<InterfaceExternalIds> {
3064         @Override
3065         public void writeValues(
3066                 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceExternalIds> values) {
3067             builder.setInterfaceExternalIds(values);
3068         }
3069
3070         @Override
3071         public List<InterfaceExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
3072             return augmentation.getInterfaceExternalIds();
3073         }
3074     }
3075
3076     private static class InterfaceLldpSouthboundHelper implements
3077     SouthboundTerminationPointHelper<InterfaceLldp> {
3078         @Override
3079         public void writeValues(
3080                 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceLldp> values) {
3081             builder.setInterfaceLldp(values);
3082         }
3083
3084         @Override
3085         public List<InterfaceLldp> readValues(OvsdbTerminationPointAugmentation augmentation) {
3086             return augmentation.getInterfaceLldp();
3087         }
3088     }
3089
3090     private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper<Options> {
3091         @Override
3092         public void writeValues(
3093                 OvsdbTerminationPointAugmentationBuilder builder, List<Options> values) {
3094             builder.setOptions(values);
3095         }
3096
3097         @Override
3098         public List<Options> readValues(OvsdbTerminationPointAugmentation augmentation) {
3099             return augmentation.getOptions();
3100         }
3101     }
3102
3103     private static class InterfaceOtherConfigsSouthboundHelper implements
3104             SouthboundTerminationPointHelper<InterfaceOtherConfigs> {
3105         @Override
3106         public void writeValues(
3107                 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceOtherConfigs> values) {
3108             builder.setInterfaceOtherConfigs(values);
3109         }
3110
3111         @Override
3112         public List<InterfaceOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
3113             return augmentation.getInterfaceOtherConfigs();
3114         }
3115     }
3116
3117     private static class PortOtherConfigsSouthboundHelper implements
3118             SouthboundTerminationPointHelper<PortOtherConfigs> {
3119         @Override
3120         public void writeValues(
3121                 OvsdbTerminationPointAugmentationBuilder builder, List<PortOtherConfigs> values) {
3122             builder.setPortOtherConfigs(values);
3123         }
3124
3125         @Override
3126         public List<PortOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
3127             return augmentation.getPortOtherConfigs();
3128         }
3129     }
3130
3131     private static class BridgeExternalIdsSouthboundHelper implements SouthboundBridgeHelper<BridgeExternalIds> {
3132         @Override
3133         public void writeValues(
3134                 OvsdbBridgeAugmentationBuilder builder, List<BridgeExternalIds> values) {
3135             builder.setBridgeExternalIds(values);
3136         }
3137
3138         @Override
3139         public List<BridgeExternalIds> readValues(OvsdbBridgeAugmentation augmentation) {
3140             return augmentation.getBridgeExternalIds();
3141         }
3142     }
3143
3144     private static class BridgeOtherConfigsSouthboundHelper implements SouthboundBridgeHelper<BridgeOtherConfigs> {
3145         @Override
3146         public void writeValues(
3147                 OvsdbBridgeAugmentationBuilder builder, List<BridgeOtherConfigs> values) {
3148             builder.setBridgeOtherConfigs(values);
3149         }
3150
3151         @Override
3152         public List<BridgeOtherConfigs> readValues(OvsdbBridgeAugmentation augmentation) {
3153             return augmentation.getBridgeOtherConfigs();
3154         }
3155     }
3156 }