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