From c17e57f8fbb159edbe41a886663e549ae120df11 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Sun, 10 Sep 2017 09:18:07 +0200 Subject: [PATCH] Fix wait for schema in BindingToNormalizedNodeCodec The wait for schema mechanism does not work. A few issues were fixed: - FutureSchema did not add the FutureSchemaPredicate instances to the postponedOperations list so they always timed out. - The waitForSchema method in BindingToNormalizedNodeCodec checked for !futureSchema.waitForSchema so it only successfully returned on failure. - There was a timing issue in FutureSchema where a context update could occur just prior to adding a postponed operation to the list, in which case the operation may timeout if the new update contained the postponed criteria and another update didn't occur in time. To alleviate this, the sychronization was tighted up and runtime context is now stored in FutureSchema instead of BindingToNormalizedNodeCodec. - The runtimeContext field needs to be volatile. I also added a wait if the runtimeContext was null b/c onGlobalContextUpdated hadn't been initially notified yet. Added unit tests to cover the wait for schema mechanism. Change-Id: I7155dae021453d085f89d13dfd4b069178dd2fc8 Signed-off-by: Tom Pantelis Signed-off-by: Robert Varga --- .../adapter/BindingToNormalizedNodeCodec.java | 44 ++-- .../binding/dom/adapter/FutureSchema.java | 161 +++++++++------ .../adapter/BindingNormalizedCodecTest.java | 192 ++++++++++++++++++ .../binding/dom/adapter/FutureSchemaTest.java | 2 +- .../test/BindingNormalizedCodecTest.java | 71 ------- 5 files changed, 316 insertions(+), 154 deletions(-) create mode 100644 binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/BindingNormalizedCodecTest.java delete mode 100644 binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/BindingNormalizedCodecTest.java diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java index d6fb13202e..5e5905ec47 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java @@ -83,8 +83,6 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto private final ClassLoadingStrategy classLoadingStrategy; private final FutureSchema futureSchema; - private volatile BindingRuntimeContext runtimeContext; - public BindingToNormalizedNodeCodec(final ClassLoadingStrategy classLoadingStrategy, final BindingNormalizedNodeCodecRegistry codecRegistry) { this(classLoadingStrategy, codecRegistry, false); @@ -94,7 +92,7 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto final BindingNormalizedNodeCodecRegistry codecRegistry, final boolean waitForSchema) { this.classLoadingStrategy = Preconditions.checkNotNull(classLoadingStrategy, "classLoadingStrategy"); this.codecRegistry = Preconditions.checkNotNull(codecRegistry, "codecRegistry"); - this.futureSchema = waitForSchema ? new FutureSchema(WAIT_DURATION_SEC, TimeUnit.SECONDS) : null; + this.futureSchema = FutureSchema.create(WAIT_DURATION_SEC, TimeUnit.SECONDS, waitForSchema); } YangInstanceIdentifier toYangInstanceIdentifierBlocking(final InstanceIdentifier binding) { @@ -217,13 +215,12 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto * InstanceIdentifier has definition InstanceIdentifier, * this means '?' is always  . Eclipse compiler * is able to determine this relationship and treats - * Entry,DataObject> and Entry + * Entry, DataObject> and Entry * as assignable. However openjdk / oracle javac treats this two types * as incompatible and issues a compile error. * *

- * It is safe to loose generic information and cast it to other generic signature. - * + * It is safe to lose generic information and cast it to other generic signature. */ @SuppressWarnings("unchecked") final Entry, DataObject> binding = Entry.class.cast( @@ -236,11 +233,9 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto @Override public void onGlobalContextUpdated(final SchemaContext context) { - runtimeContext = BindingRuntimeContext.create(classLoadingStrategy, context); + final BindingRuntimeContext runtimeContext = BindingRuntimeContext.create(classLoadingStrategy, context); codecRegistry.onBindingRuntimeContextUpdated(runtimeContext); - if (futureSchema != null) { - futureSchema.onRuntimeContextUpdated(runtimeContext); - } + futureSchema.onRuntimeContextUpdated(runtimeContext); } public Function>, Optional> @@ -294,11 +289,11 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto final QNameModule moduleName = BindingReflections.getQNameModule(modeledClass); final URI namespace = moduleName.getNamespace(); final Date revision = moduleName.getRevision(); - BindingRuntimeContext localRuntimeContext = runtimeContext; + BindingRuntimeContext localRuntimeContext = runtimeContext(); Module module = localRuntimeContext == null ? null : localRuntimeContext.getSchemaContext().findModuleByNamespaceAndRevision(namespace, revision); - if (module == null && futureSchema != null && futureSchema.waitForSchema(namespace,revision)) { - localRuntimeContext = runtimeContext; + if (module == null && futureSchema.waitForSchema(namespace,revision)) { + localRuntimeContext = runtimeContext(); Preconditions.checkState(localRuntimeContext != null, "BindingRuntimeContext is not available."); module = localRuntimeContext.getSchemaContext().findModuleByNamespaceAndRevision(namespace, revision); } @@ -307,21 +302,18 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto } private void waitForSchema(final Collection> binding, final MissingSchemaException exception) { - if (futureSchema != null) { - LOG.warn("Blocking thread to wait for schema convergence updates for {} {}", - futureSchema.getDuration(), futureSchema.getUnit()); - if (!futureSchema.waitForSchema(binding)) { - return; - } + LOG.warn("Blocking thread to wait for schema convergence updates for {} {}", futureSchema.getDuration(), + futureSchema.getUnit()); + if (!futureSchema.waitForSchema(binding)) { + throw exception; } - throw exception; } private Method findRpcMethod(final Class key, final RpcDefinition rpcDef) throws NoSuchMethodException { final String methodName = BindingMapping.getMethodName(rpcDef.getQName()); if (rpcDef.getInput() != null && isExplicitStatement(rpcDef.getInput())) { - final Class inputClz = runtimeContext.getClassForSchema(rpcDef.getInput()); + final Class inputClz = runtimeContext().getClassForSchema(rpcDef.getInput()); return key.getMethod(methodName, inputClz); } return key.getMethod(methodName); @@ -360,8 +352,8 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto @SuppressWarnings("unchecked") public Set> getNotificationClasses(final Set interested) { final Set> result = new HashSet<>(); - final Set knownNotifications = runtimeContext.getSchemaContext().getNotifications(); - for (final NotificationDefinition notification : knownNotifications) { + final BindingRuntimeContext runtimeContext = runtimeContext(); + for (final NotificationDefinition notification : runtimeContext.getSchemaContext().getNotifications()) { if (interested.contains(notification.getPath())) { try { result.add((Class) runtimeContext.getClassForSchema(notification)); @@ -374,12 +366,16 @@ public final class BindingToNormalizedNodeCodec implements BindingCodecTreeFacto return result; } + private BindingRuntimeContext runtimeContext() { + return futureSchema.runtimeContext(); + } + private static Collection> decompose(final InstanceIdentifier path) { return ImmutableSet.copyOf(Iterators.transform(path.getPathArguments().iterator(), PathArgument::getType)); } protected NormalizedNode instanceIdentifierToNode(final YangInstanceIdentifier parentPath) { - return ImmutableNodes.fromInstanceId(runtimeContext.getSchemaContext(), parentPath); + return ImmutableNodes.fromInstanceId(runtimeContext().getSchemaContext(), parentPath); } public NormalizedNode getDefaultNodeFor(final YangInstanceIdentifier parentMapPath) { diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/FutureSchema.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/FutureSchema.java index 537ab1f72a..0dfa8419e1 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/FutureSchema.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/FutureSchema.java @@ -8,34 +8,105 @@ package org.opendaylight.mdsal.binding.dom.adapter; -import com.google.common.base.Predicate; +import static java.util.Objects.requireNonNull; + import com.google.common.util.concurrent.SettableFuture; import java.net.URI; import java.util.Collection; +import java.util.Collections; import java.util.Date; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Predicate; +import javax.annotation.concurrent.GuardedBy; import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext; import org.opendaylight.yangtools.yang.binding.Augmentation; -class FutureSchema implements AutoCloseable { +abstract class FutureSchema implements AutoCloseable { + private static final class Waiting extends FutureSchema { + Waiting(final long time, final TimeUnit unit) { + super(time, unit); + } + } + + private static final class NonWaiting extends FutureSchema { + NonWaiting(final long time, final TimeUnit unit) { + super(time, unit); + } + + @Override + boolean addPostponedOpAndWait(final FutureSchemaPredicate postponedOp) { + return false; + } + } + + private abstract class FutureSchemaPredicate implements Predicate { + private final SettableFuture schemaPromise = SettableFuture.create(); + + final boolean waitForSchema() { + try { + schemaPromise.get(FutureSchema.this.duration, FutureSchema.this.unit); + return true; + } catch (final InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } catch (final TimeoutException e) { + return false; + } finally { + synchronized (FutureSchema.this.postponedOperations) { + FutureSchema.this.postponedOperations.remove(this); + } + } + } + + final void unlockIfPossible(final BindingRuntimeContext context) { + if (!schemaPromise.isDone() && test(context)) { + schemaPromise.set(null); + } + } + + final void cancel() { + schemaPromise.cancel(true); + } + } - private final List postponedOperations = new CopyOnWriteArrayList<>(); - private final SettableFuture schemaPromise = SettableFuture.create(); + @GuardedBy("postponedOperations") + private final Set postponedOperations = new LinkedHashSet<>(); private final long duration; private final TimeUnit unit; - protected FutureSchema(final long time, final TimeUnit unit) { + private volatile BindingRuntimeContext runtimeContext; + + FutureSchema(final long time, final TimeUnit unit) { this.duration = time; - this.unit = unit; + this.unit = requireNonNull(unit); + } + + static FutureSchema create(final long time, final TimeUnit unit, final boolean waitEnabled) { + return waitEnabled ? new Waiting(time, unit) : new NonWaiting(time, unit); + } + + BindingRuntimeContext runtimeContext() { + final BindingRuntimeContext localRuntimeContext = runtimeContext; + if (localRuntimeContext != null) { + return localRuntimeContext; + } + + if (waitForSchema(Collections.emptyList())) { + return runtimeContext; + } + + throw new IllegalStateException("No SchemaContext is available"); } void onRuntimeContextUpdated(final BindingRuntimeContext context) { - for (final FutureSchemaPredicate op : postponedOperations) { - op.unlockIfPossible(context); + synchronized (postponedOperations) { + runtimeContext = context; + for (final FutureSchemaPredicate op : postponedOperations) { + op.unlockIfPossible(context); + } } } @@ -49,72 +120,46 @@ class FutureSchema implements AutoCloseable { @Override public void close() { - for (final FutureSchemaPredicate op : postponedOperations) { - op.cancel(); - } - } - - private static boolean isSchemaAvailable(final Class clz, final BindingRuntimeContext context) { - final Object schema; - if (Augmentation.class.isAssignableFrom(clz)) { - schema = context.getAugmentationDefinition(clz); - } else { - schema = context.getSchemaDefinition(clz); + synchronized (postponedOperations) { + postponedOperations.forEach(FutureSchemaPredicate::cancel); } - return schema != null; } boolean waitForSchema(final URI namespace, final Date revision) { - final FutureSchemaPredicate postponedOp = new FutureSchemaPredicate() { - + return addPostponedOpAndWait(new FutureSchemaPredicate() { @Override - public boolean apply(final BindingRuntimeContext input) { + public boolean test(final BindingRuntimeContext input) { return input.getSchemaContext().findModuleByNamespaceAndRevision(namespace, revision) != null; } - }; - return postponedOp.waitForSchema(); + }); } boolean waitForSchema(final Collection> bindingClasses) { - final FutureSchemaPredicate postponedOp = new FutureSchemaPredicate() { - + return addPostponedOpAndWait(new FutureSchemaPredicate() { @Override - public boolean apply(final BindingRuntimeContext context) { - for (final Class clz : bindingClasses) { - if (!isSchemaAvailable(clz, context)) { - return false; + public boolean test(final BindingRuntimeContext context) { + return bindingClasses.stream().allMatch(clz -> { + if (Augmentation.class.isAssignableFrom(clz)) { + return context.getAugmentationDefinition(clz) != null; } - } - return true; + + return context.getSchemaDefinition(clz) != null; + }); } - }; - return postponedOp.waitForSchema(); + }); } - private abstract class FutureSchemaPredicate implements Predicate { + boolean addPostponedOpAndWait(final FutureSchemaPredicate postponedOp) { + synchronized (postponedOperations) { + postponedOperations.add(postponedOp); - final boolean waitForSchema() { - try { - schemaPromise.get(duration, unit); - return true; - } catch (final InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } catch (final TimeoutException e) { - return false; - } finally { - postponedOperations.remove(this); + // If the runtimeContext changed, this op may now be satisfied so check it. + final BindingRuntimeContext context = runtimeContext; + if (context != null) { + postponedOp.unlockIfPossible(context); } } - final void unlockIfPossible(final BindingRuntimeContext context) { - if (!schemaPromise.isDone() && apply(context)) { - schemaPromise.set(null); - } - } - - final void cancel() { - schemaPromise.cancel(true); - } + return postponedOp.waitForSchema(); } - } diff --git a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/BindingNormalizedCodecTest.java b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/BindingNormalizedCodecTest.java new file mode 100644 index 0000000000..686f4bc92c --- /dev/null +++ b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/BindingNormalizedCodecTest.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.mdsal.binding.dom.adapter; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.Multimaps; +import com.google.common.collect.SetMultimap; +import com.google.common.util.concurrent.Uninterruptibles; +import java.lang.reflect.Method; +import java.net.URI; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import javassist.ClassPool; +import org.junit.Test; +import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractSchemaAwareTest; +import org.opendaylight.mdsal.binding.dom.codec.gen.impl.DataObjectSerializerGenerator; +import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator; +import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry; +import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy; +import org.opendaylight.mdsal.binding.generator.util.JavassistUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.bi.ba.rpcservice.rev140701.OpendaylightTestRpcServiceService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeComplexUsesAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeLeafOnlyAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.util.AbstractSchemaContext; + +public class BindingNormalizedCodecTest extends AbstractSchemaAwareTest { + + private static final TopLevelListKey TOP_FOO_KEY = new TopLevelListKey("foo"); + private static final InstanceIdentifier BA_TOP_LEVEL_LIST = InstanceIdentifier + .builder(Top.class).child(TopLevelList.class, TOP_FOO_KEY).build(); + private static final InstanceIdentifier BA_TREE_LEAF_ONLY = BA_TOP_LEVEL_LIST + .augmentation(TreeLeafOnlyAugment.class); + private static final InstanceIdentifier BA_TREE_COMPLEX_USES = BA_TOP_LEVEL_LIST + .augmentation(TreeComplexUsesAugment.class); + private static final QName SIMPLE_VALUE_QNAME = QName.create(TreeComplexUsesAugment.QNAME, "simple-value"); + private static final QName NAME_QNAME = QName.create(Top.QNAME, "name"); + private static final YangInstanceIdentifier BI_TOP_LEVEL_LIST = YangInstanceIdentifier.builder().node(Top.QNAME) + .node(TopLevelList.QNAME).nodeWithKey(TopLevelList.QNAME, NAME_QNAME, TOP_FOO_KEY.getName()).build(); + + private BindingToNormalizedNodeCodec codec; + private SchemaContext context; + + @Override + protected void setupWithSchema(final SchemaContext context) { + this.context = context; + final DataObjectSerializerGenerator streamWriter = StreamWriterGenerator.create(JavassistUtils.forClassPool( + ClassPool.getDefault())); + final BindingNormalizedNodeCodecRegistry registry = new BindingNormalizedNodeCodecRegistry(streamWriter); + this.codec = new BindingToNormalizedNodeCodec(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), + registry, true); + } + + @Test + public void testComplexAugmentationSerialization() { + this.codec.onGlobalContextUpdated(this.context); + final PathArgument lastArg = this.codec.toYangInstanceIdentifier(BA_TREE_COMPLEX_USES).getLastPathArgument(); + assertTrue(lastArg instanceof AugmentationIdentifier); + } + + + @Test + public void testLeafOnlyAugmentationSerialization() { + this.codec.onGlobalContextUpdated(this.context); + final PathArgument leafOnlyLastArg = this.codec.toYangInstanceIdentifier(BA_TREE_LEAF_ONLY) + .getLastPathArgument(); + assertTrue(leafOnlyLastArg instanceof AugmentationIdentifier); + assertTrue(((AugmentationIdentifier) leafOnlyLastArg).getPossibleChildNames().contains(SIMPLE_VALUE_QNAME)); + } + + @Test + @SuppressWarnings("checkstyle:illegalCatch") + public void testToYangInstanceIdentifierBlocking() { + this.codec.onGlobalContextUpdated(new EmptySchemaContext()); + + final CountDownLatch done = new CountDownLatch(1); + final AtomicReference yangId = new AtomicReference<>(); + final AtomicReference error = new AtomicReference<>(); + new Thread(() -> { + try { + yangId.set(BindingNormalizedCodecTest.this.codec.toYangInstanceIdentifierBlocking(BA_TOP_LEVEL_LIST)); + } catch (final RuntimeException e) { + error.set(e); + } finally { + done.countDown(); + } + }).start(); + + Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS); + this.codec.onGlobalContextUpdated(this.context); + + assertTrue("toYangInstanceIdentifierBlocking completed", + Uninterruptibles.awaitUninterruptibly(done, 3, TimeUnit.SECONDS)); + if (error.get() != null) { + throw error.get(); + } + + assertEquals("toYangInstanceIdentifierBlocking", BI_TOP_LEVEL_LIST, yangId.get()); + } + + @Test + public void testGetRpcMethodToSchemaPathWithNoInitialSchemaContext() { + testGetRpcMethodToSchemaPath(); + } + + @Test + public void testGetRpcMethodToSchemaPathBlocking() { + this.codec.onGlobalContextUpdated(new EmptySchemaContext()); + testGetRpcMethodToSchemaPath(); + } + + @SuppressWarnings("checkstyle:illegalCatch") + private void testGetRpcMethodToSchemaPath() { + final CountDownLatch done = new CountDownLatch(1); + final AtomicReference> retMap = new AtomicReference<>(); + final AtomicReference error = new AtomicReference<>(); + new Thread(() -> { + try { + retMap.set(BindingNormalizedCodecTest.this.codec.getRpcMethodToSchemaPath( + OpendaylightTestRpcServiceService.class)); + } catch (final RuntimeException e) { + error.set(e); + } finally { + done.countDown(); + } + }).start(); + + Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS); + this.codec.onGlobalContextUpdated(this.context); + + assertTrue("getRpcMethodToSchemaPath completed", + Uninterruptibles.awaitUninterruptibly(done, 3, TimeUnit.SECONDS)); + if (error.get() != null) { + throw error.get(); + } + + for (final Method method : retMap.get().keySet()) { + if (method.getName().equals("rockTheHouse")) { + return; + } + } + + fail("rockTheHouse RPC method not found"); + } + + static class EmptySchemaContext extends AbstractSchemaContext { + @Override + public Set getModules() { + return Collections.emptySet(); + } + + @Override + protected Map getIdentifiersToSources() { + return Collections.emptyMap(); + } + + @Override + protected SetMultimap getNamespaceToModules() { + return Multimaps.forMap(Collections.emptyMap()); + } + + @Override + protected SetMultimap getNameToModules() { + return Multimaps.forMap(Collections.emptyMap()); + } + } +} diff --git a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/FutureSchemaTest.java b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/FutureSchemaTest.java index d688599692..fa4574f290 100644 --- a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/FutureSchemaTest.java +++ b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/FutureSchemaTest.java @@ -21,7 +21,7 @@ public class FutureSchemaTest { @Test public void basicTest() throws Exception { - final FutureSchema futureSchema = new FutureSchema(0, TimeUnit.MICROSECONDS); + final FutureSchema futureSchema = FutureSchema.create(0, TimeUnit.MICROSECONDS, true); assertNotNull(futureSchema); assertFalse(futureSchema.waitForSchema(new URI("test"), new Date(0))); assertFalse(futureSchema.waitForSchema(ImmutableSet.of())); diff --git a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/BindingNormalizedCodecTest.java b/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/BindingNormalizedCodecTest.java deleted file mode 100644 index 3fd92be849..0000000000 --- a/binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/test/BindingNormalizedCodecTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.mdsal.binding.dom.adapter.test; - -import static org.junit.Assert.assertTrue; - -import javassist.ClassPool; -import org.junit.Test; -import org.opendaylight.mdsal.binding.dom.adapter.BindingToNormalizedNodeCodec; -import org.opendaylight.mdsal.binding.dom.codec.gen.impl.DataObjectSerializerGenerator; -import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator; -import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry; -import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy; -import org.opendaylight.mdsal.binding.generator.util.JavassistUtils; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeComplexUsesAugment; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeLeafOnlyAugment; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -public class BindingNormalizedCodecTest extends AbstractSchemaAwareTest { - - private static final TopLevelListKey TOP_FOO_KEY = new TopLevelListKey("foo"); - private static final InstanceIdentifier BA_TOP_LEVEL_LIST = InstanceIdentifier - .builder(Top.class).child(TopLevelList.class, TOP_FOO_KEY).toInstance(); - private static final InstanceIdentifier BA_TREE_LEAF_ONLY - = BA_TOP_LEVEL_LIST.augmentation(TreeLeafOnlyAugment.class); - private static final InstanceIdentifier BA_TREE_COMPLEX_USES - = BA_TOP_LEVEL_LIST.augmentation(TreeComplexUsesAugment.class); - private static final QName SIMPLE_VALUE_QNAME = QName.create(TreeComplexUsesAugment.QNAME, "simple-value"); - - - private BindingToNormalizedNodeCodec codec; - - @Override - protected void setupWithSchema(final SchemaContext context) { - final DataObjectSerializerGenerator streamWriter - = StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault())); - final BindingNormalizedNodeCodecRegistry registry = new BindingNormalizedNodeCodecRegistry(streamWriter); - codec = new BindingToNormalizedNodeCodec(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), registry); - codec.onGlobalContextUpdated(context); - } - - @Test - public void testComplexAugmentationSerialization() { - - final PathArgument lastArg = codec.toYangInstanceIdentifier(BA_TREE_COMPLEX_USES).getLastPathArgument(); - assertTrue(lastArg instanceof AugmentationIdentifier); - } - - - @Test - public void testLeafOnlyAugmentationSerialization() { - - final PathArgument leafOnlyLastArg = codec.toYangInstanceIdentifier(BA_TREE_LEAF_ONLY).getLastPathArgument(); - assertTrue(leafOnlyLastArg instanceof AugmentationIdentifier); - assertTrue(((AugmentationIdentifier) leafOnlyLastArg).getPossibleChildNames().contains(SIMPLE_VALUE_QNAME)); - } - -} -- 2.36.6