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