Bug 376: Added explicit wait for schema when generating augmentation codec. 09/4809/2
authorTony Tkacik <ttkacik@cisco.com>
Sun, 26 Jan 2014 16:55:03 +0000 (17:55 +0100)
committerRobert Varga <rovarga@cisco.com>
Sun, 26 Jan 2014 17:39:03 +0000 (18:39 +0100)
Change-Id: Ica7ecd53725f8e77fc0f7637e8deed6514b5a313
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/LazyGeneratedCodecRegistry.java
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/RuntimeGeneratedMappingServiceImpl.xtend
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/SchemaLock.java [new file with mode: 0644]

index 7ba9a90ec115d4044358da83128b072068d114d6..b9efd0eee14b4fdf75a71a62b603f9dba14e4601 100644 (file)
@@ -74,8 +74,18 @@ public class LazyGeneratedCodecRegistry implements //
     private static final Map<List<QName>, Type> pathToInstantiatedType = new ConcurrentHashMap<>();
     private static final Map<Type, QName> typeToQname = new ConcurrentHashMap<>();
 
+    private final SchemaLock lock;
+
     private SchemaContext currentSchema;
 
+    LazyGeneratedCodecRegistry(SchemaLock lock) {
+        this.lock = Preconditions.checkNotNull(lock);
+    }
+
+    public SchemaLock getLock() {
+        return lock;
+    }
+
     public TransformerGenerator getGenerator() {
         return generator;
     }
@@ -98,6 +108,7 @@ public class LazyGeneratedCodecRegistry implements //
             codec = potentialCodec;
         } else
             try {
+                lock.waitForSchema(object);
                 Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentRawCodec = generator
                         .augmentationTransformerFor(object);
                 BindingCodec<Map<QName, Object>, Object> rawCodec = augmentRawCodec.newInstance();
index f14b15eba756d965a496d1f9527f77ea29992e0d..23a9cd00443341f178651ddc2fc5ec834f367b03 100644 (file)
@@ -53,8 +53,9 @@ import java.util.Set
 import org.opendaylight.yangtools.yang.common.QName
 import com.google.common.collect.FluentIterable
 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
+import java.util.HashMap
 
-class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, AutoCloseable {
+class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, SchemaLock, AutoCloseable {
 
     @Property
     ClassPool pool;
@@ -81,7 +82,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
 
     val promisedTypeDefinitions = HashMultimap.<Type, SettableFuture<GeneratedTypeBuilder>>create;
 
-    val promisedSchemas = HashMultimap.<Type, SettableFuture<SchemaNode>>create;
+    val promisedTypes = HashMultimap.<Type, SettableFuture<Type>>create;
 
     //ServiceRegistration<SchemaServiceListener> listenerRegistration
 
@@ -127,8 +128,10 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
             for (augmentation : augmentations) {
                 binding.typeToDefinition.put(augmentation, augmentation);
             }
-
             binding.typeToAugmentation.putAll(context.typeToAugmentation);
+            for(augmentation : augmentations) {
+                updatePromisedSchemas(augmentation);
+            }
         }
     }
 
@@ -192,13 +195,8 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
         return ret as CompositeNode;
     }
 
-    private def void waitForSchema(Class<? extends DataContainer> class1) {
-        if(Augmentation.isAssignableFrom(class1)) {
-            /*  FIXME: We should wait also for augmentations. Currently YANGTools does not provide correct
-             *  mapping between java Augmentation classes and augmentations.
-             */
-            return;
-        }
+    override waitForSchema(Class class1) {
+
         if(registry.isCodecAvailable(class1)) {
             return;
         }
@@ -248,7 +246,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
             typeToDefinition.put(typeRef, entry.value);
             if (schemaNode != null) {
                 typeToSchemaNode.put(typeRef, schemaNode);
-                updatePromisedSchemas(typeRef, schemaNode);
+                updatePromisedSchemas(entry.value);
             }
 
         }
@@ -256,7 +254,7 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
 
     public def void init() {
         binding = new TransformerGenerator(pool);
-        registry = new LazyGeneratedCodecRegistry()
+        registry = new LazyGeneratedCodecRegistry(this)
         registry.generator = binding
 
         //binding.staticFieldsInitializer = registry
@@ -273,31 +271,30 @@ class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingSer
         return serviceTypeToRpc.get(new ReferencedTypeImpl(service.package.name,service.simpleName));
     }
 
-    private def getSchemaWithRetry(Type type) {
-        val typeDef = typeToSchemaNode.get(type);
-        if (typeDef !== null) {
-            return typeDef;
+    private def void getSchemaWithRetry(Type type) {
+        if (typeToDefinition.containsKey(type)) {
+            return;
         }
         LOG.trace("Thread blocked waiting for schema for: {}",type.fullyQualifiedName)
-        return type.getSchemaInFuture.get();
+        type.waitForTypeDefinition.get();
     }
 
-    private def Future<SchemaNode> getSchemaInFuture(Type type) {
-        val future = SettableFuture.<SchemaNode>create()
-        promisedSchemas.put(type, future);
+    private def Future<Type> waitForTypeDefinition(Type type) {
+        val future = SettableFuture.<Type>create()
+        promisedTypes.put(type, future);
         return future;
     }
 
-    private def void updatePromisedSchemas(Type builder, SchemaNode schema) {
+    private def void updatePromisedSchemas(Type builder) {
         val ref = new ReferencedTypeImpl(builder.packageName, builder.name);
-        val futures = promisedSchemas.get(ref);
+        val futures = promisedTypes.get(ref);
         if (futures === null || futures.empty) {
             return;
         }
         for (future : futures) {
-            future.set(schema);
+            future.set(builder);
         }
-        promisedSchemas.removeAll(builder);
+        promisedTypes.removeAll(builder);
     }
 
     override close() throws Exception {
diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/SchemaLock.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/SchemaLock.java
new file mode 100644 (file)
index 0000000..be0bb45
--- /dev/null
@@ -0,0 +1,7 @@
+package org.opendaylight.yangtools.sal.binding.generator.impl;
+
+public interface SchemaLock {
+
+    public void waitForSchema(Class<?> cls);
+    
+}