Cleanup BindingRuntimeHelpers 10/89310/4
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 23 Apr 2020 11:38:04 +0000 (13:38 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 23 Apr 2020 12:24:11 +0000 (14:24 +0200)
We need to differentiate between testing (static context) and dynamic
contexts. This makes it possible to use these helpers in OSGi if we
inject the right set of services.

Change-Id: Ibc22b1597320956408217b98d44c9ea3fdd98c32
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/ActionLookupTest.java
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/query/binding/adapter/QueryBuilderTest.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/AbstractBindingRuntimeTest.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/AugmentationClassDiscoveredAfterCodecTest.java
binding/mdsal-binding-dom-codec/src/test/java/org/opendaylight/mdsal/binding/dom/codec/impl/ExceptionReportingTest.java
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/binding/runtime/spi/BindingRuntimeHelpers.java
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/binding/runtime/spi/ServiceLoaderState.java [new file with mode: 0644]

index 04c0f6aa999b118321292e491e0051d585c15092..aacfa951fdbce9f932f1ca2636cd85dd841179b9 100644 (file)
@@ -12,7 +12,6 @@ import static org.junit.Assert.assertEquals;
 import org.junit.Test;
 import org.opendaylight.binding.runtime.spi.BindingRuntimeHelpers;
 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingCodecContext;
-import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
 import org.opendaylight.yang.gen.v1.urn.odl.actions.norev.Cont;
 import org.opendaylight.yang.gen.v1.urn.odl.actions.norev.Grpcont;
 import org.opendaylight.yang.gen.v1.urn.odl.actions.norev.Othercont;
@@ -24,7 +23,7 @@ public class ActionLookupTest {
     @Test
     public void testActionSchemaPath() {
         CurrentAdapterSerializer codec = new CurrentAdapterSerializer(new BindingCodecContext(
-            BindingRuntimeHelpers.createRuntimeContext(new DefaultBindingRuntimeGenerator())));
+            BindingRuntimeHelpers.createRuntimeContext()));
 
         assertEquals(SchemaPath.create(true, Cont.QNAME, Foo.QNAME), codec.getActionPath(Foo.class));
         assertEquals(SchemaPath.create(true, Grpcont.QNAME, Bar.QNAME), codec.getActionPath(Bar.class));
index 23d9b0c3d9b7ca1126ee1cdf2bb2d21a93965e15..67f8c8b4e6bf74c78a894fcc237d37736e837927 100644 (file)
@@ -15,7 +15,6 @@ import org.opendaylight.mdsal.binding.api.query.QueryFactory;
 import org.opendaylight.mdsal.binding.api.query.QueryStructureException;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
 import org.opendaylight.mdsal.binding.dom.codec.impl.DefaultBindingCodecTreeFactory;
-import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
 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.top.level.list.NestedList;
@@ -28,8 +27,7 @@ public class QueryBuilderTest {
 
     @BeforeClass
     public static void beforeClass() {
-        CODEC = new DefaultBindingCodecTreeFactory().create(BindingRuntimeHelpers.createRuntimeContext(
-            new DefaultBindingRuntimeGenerator()));
+        CODEC = new DefaultBindingCodecTreeFactory().create(BindingRuntimeHelpers.createRuntimeContext());
     }
 
     @Test
index 9401a1913549f008e6dbe22c883bc029ee1d0636..3340fec8a230ce7db95358cf0ec8e5a7f396d291 100644 (file)
@@ -11,14 +11,13 @@ import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.opendaylight.binding.runtime.api.BindingRuntimeContext;
 import org.opendaylight.binding.runtime.spi.BindingRuntimeHelpers;
-import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
 
 public abstract class AbstractBindingRuntimeTest {
     private static BindingRuntimeContext runtimeContext;
 
     @BeforeClass
     public static void beforeClass() {
-        runtimeContext = BindingRuntimeHelpers.createRuntimeContext(new DefaultBindingRuntimeGenerator());
+        runtimeContext = BindingRuntimeHelpers.createRuntimeContext();
     }
 
     @AfterClass
index b3586c124f837c591389e56d09b7a8734bf4c1b1..f854662ccae1228531604c9c3d8cdf7f57ca6aed 100644 (file)
@@ -21,7 +21,6 @@ import org.opendaylight.binding.runtime.api.DefaultBindingRuntimeContext;
 import org.opendaylight.binding.runtime.spi.BindingRuntimeHelpers;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.mdsal.binding.dom.codec.api.MissingClassInLoadingStrategyException;
-import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
 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.augment.rev140709.TreeLeafOnlyAugmentBuilder;
@@ -47,8 +46,7 @@ public class AugmentationClassDiscoveredAfterCodecTest {
     @Before
     public void setup() {
         // Baseline state: strategy is cognizant of the classes
-        final BindingRuntimeContext delegate = BindingRuntimeHelpers.createRuntimeContext(
-            new DefaultBindingRuntimeGenerator());
+        final BindingRuntimeContext delegate = BindingRuntimeHelpers.createRuntimeContext();
 
         // Class loading filter, manipulated by tests
         filter = new FilteringClassLoadingStrategy(delegate.getStrategy());
index 831eccb20e4db58989ac4423bf807373e609fc37..ae09d5ac575ecbdac2130d241740f31a34c765e3 100644 (file)
@@ -13,7 +13,6 @@ import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSeriali
 import org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException;
 import org.opendaylight.mdsal.binding.dom.codec.api.MissingSchemaException;
 import org.opendaylight.mdsal.binding.dom.codec.api.MissingSchemaForClassException;
-import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
 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;
@@ -73,7 +72,6 @@ public class ExceptionReportingTest {
     }
 
     private static BindingNormalizedNodeSerializer codec(final Class<?>... classes) {
-        return new BindingCodecContext(BindingRuntimeHelpers.createRuntimeContext(
-            new DefaultBindingRuntimeGenerator(), classes));
+        return new BindingCodecContext(BindingRuntimeHelpers.createRuntimeContext(classes));
     }
 }
index c5ccd7483540de4eac04844f40abee7ffb8427e6..2c0b0a9fe7489a4e942de5df21a900f3dbe35253 100644 (file)
@@ -8,7 +8,9 @@
 package org.opendaylight.binding.runtime.spi;
 
 import com.google.common.annotations.Beta;
+import com.google.common.base.Throwables;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.stream.Collectors;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.binding.runtime.api.BindingRuntimeContext;
@@ -17,6 +19,7 @@ import org.opendaylight.binding.runtime.api.DefaultBindingRuntimeContext;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
 
 /**
  * Simple helpers to help with reconstruction of BindingRuntimeContext from generated binding classes. These involve
@@ -37,18 +40,34 @@ public final class BindingRuntimeHelpers {
 
     public static @NonNull EffectiveModelContext createEffectiveModel(
             final Iterable<? extends YangModuleInfo> moduleInfos) {
-        return prepareContext(moduleInfos).tryToCreateModelContext().orElseThrow();
+        return createEffectiveModel(ServiceLoaderState.ParserFactory.INSTANCE, moduleInfos);
     }
 
-    public static @NonNull BindingRuntimeContext createRuntimeContext(final BindingRuntimeGenerator generator) {
-        final ModuleInfoBackedContext ctx = prepareContext(BindingReflections.loadModuleInfos());
-        return DefaultBindingRuntimeContext.create(generator.generateTypeMapping(
+    public static @NonNull EffectiveModelContext createEffectiveModel(final YangParserFactory parserFactory,
+            final Iterable<? extends YangModuleInfo> moduleInfos) {
+        return prepareContext(parserFactory, moduleInfos).tryToCreateModelContext().orElseThrow();
+    }
+
+    public static @NonNull BindingRuntimeContext createRuntimeContext() {
+        final ModuleInfoBackedContext ctx = prepareContext(ServiceLoaderState.ParserFactory.INSTANCE,
+            BindingReflections.loadModuleInfos());
+        return DefaultBindingRuntimeContext.create(ServiceLoaderState.Generator.INSTANCE.generateTypeMapping(
             ctx.tryToCreateModelContext().orElseThrow()), ctx);
     }
 
-    public static @NonNull BindingRuntimeContext createRuntimeContext(final BindingRuntimeGenerator generator,
-            final Class<?>... classes) {
-        final ModuleInfoBackedContext ctx = prepareContext(Arrays.stream(classes)
+    public static @NonNull BindingRuntimeContext createRuntimeContext(final Class<?>... classes) {
+        return createRuntimeContext(ServiceLoaderState.ParserFactory.INSTANCE, ServiceLoaderState.Generator.INSTANCE,
+            classes);
+    }
+
+    public static @NonNull BindingRuntimeContext createRuntimeContext(final YangParserFactory parserFactory,
+            final BindingRuntimeGenerator generator, final Class<?>... classes) {
+        return createRuntimeContext(parserFactory, generator, Arrays.asList(classes));
+    }
+
+    public static @NonNull BindingRuntimeContext createRuntimeContext(final YangParserFactory parserFactory,
+            final BindingRuntimeGenerator generator, final Collection<Class<?>> classes) {
+        final ModuleInfoBackedContext ctx = prepareContext(parserFactory, classes.stream()
             .map(BindingRuntimeHelpers::extractYangModuleInfo)
             .collect(Collectors.toList()));
         return DefaultBindingRuntimeContext.create(
@@ -60,12 +79,14 @@ public final class BindingRuntimeHelpers {
         try {
             return BindingReflections.getModuleInfo(clazz);
         } catch (Exception e) {
+            Throwables.throwIfUnchecked(e);
             throw new IllegalStateException("Failed to extract module info from " + clazz, e);
         }
     }
 
-    private static ModuleInfoBackedContext prepareContext(final Iterable<? extends YangModuleInfo> moduleInfos) {
-        final ModuleInfoBackedContext ctx = ModuleInfoBackedContext.create();
+    private static @NonNull ModuleInfoBackedContext prepareContext(final YangParserFactory parserFactory,
+            final Iterable<? extends YangModuleInfo> moduleInfos) {
+        final ModuleInfoBackedContext ctx = ModuleInfoBackedContext.create("helper", parserFactory);
         ctx.registerModuleInfos(moduleInfos);
         return ctx;
     }
diff --git a/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/binding/runtime/spi/ServiceLoaderState.java b/binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/binding/runtime/spi/ServiceLoaderState.java
new file mode 100644 (file)
index 0000000..10f62b6
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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.binding.runtime.spi;
+
+import java.util.ServiceLoader;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.binding.runtime.api.BindingRuntimeGenerator;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
+
+/**
+ * State derived from ServiceLoader. We statically bind to this state. If you need more dynamics, you should not be
+ * showing up here at all.
+ */
+@NonNullByDefault
+final class ServiceLoaderState {
+    static final class Generator {
+        static final BindingRuntimeGenerator INSTANCE = ServiceLoader.load(BindingRuntimeGenerator.class).findFirst()
+                .orElseThrow(() -> new ExceptionInInitializerError("No BindingRuntimeGenerator found"));
+    }
+
+    static final class ParserFactory {
+        static final YangParserFactory INSTANCE = ServiceLoader.load(YangParserFactory.class).findFirst()
+                .orElseThrow(() -> new ExceptionInInitializerError("No YangParserFactory found"));
+    }
+}