Rework BindingDOMRpcImplementationAdapter instantiation 81/22081/3
authorRobert Varga <rovarga@cisco.com>
Wed, 27 May 2015 11:45:07 +0000 (13:45 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 8 Jun 2015 11:29:29 +0000 (11:29 +0000)
Move the SchemaPath/Method map closer to where we instantiate invokers.
This has the benefit of speeding up registration code very slightly,
but more importantly it allows instantiating more efficient invokers, as
we have the SchemaPath->Method map readily available.

Change-Id: Iefc0faadcfd7df6c40240ce1f78c7b734f06c618
Signed-off-by: Robert Varga <rovarga@cisco.com>
(cherry picked from commit 99783448ed6bbcad04b66379db638241c58e3ec8)

opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcImplementationAdapter.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingDOMRpcProviderServiceAdapter.java

index fac13fb2818a8a8f007ce1686dd223da555b841d..c81cce5a4b752e998b7b1b07015be77e24f60da5 100644 (file)
@@ -7,9 +7,16 @@
  */
 package org.opendaylight.controller.md.sal.binding.impl;
 
+import com.google.common.base.Preconditions;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.JdkFutureAdapters;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
@@ -28,15 +35,27 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
 public class BindingDOMRpcImplementationAdapter implements DOMRpcImplementation {
 
+    private static final Cache<Class<?>, RpcServiceInvoker> SERVICE_INVOKERS = CacheBuilder.newBuilder().weakKeys().build();
+
     private final BindingNormalizedNodeCodecRegistry codec;
     private final RpcServiceInvoker invoker;
     private final RpcService delegate;
     private final QNameModule module;
 
-    public <T extends RpcService> BindingDOMRpcImplementationAdapter(final BindingNormalizedNodeCodecRegistry codec, final Class<T> type ,final T delegate) {
-        this.codec = codec;
-        this.delegate = delegate;
-        invoker = RpcServiceInvoker.from(type);
+    public <T extends RpcService> BindingDOMRpcImplementationAdapter(final BindingNormalizedNodeCodecRegistry codec, final Class<T> type, final Map<SchemaPath, Method> localNameToMethod, final T delegate) {
+        try {
+            this.invoker = SERVICE_INVOKERS.get(type, new Callable<RpcServiceInvoker>() {
+                @Override
+                public RpcServiceInvoker call() {
+                    return RpcServiceInvoker.from(type);
+                }
+            });
+        } catch (ExecutionException e) {
+            throw new IllegalArgumentException("Failed to create invokers for type " + type, e);
+        }
+
+        this.codec = Preconditions.checkNotNull(codec);
+        this.delegate = Preconditions.checkNotNull(delegate);
         module = BindingReflections.getQNameModule(type);
     }
 
@@ -53,7 +72,7 @@ public class BindingDOMRpcImplementationAdapter implements DOMRpcImplementation
     }
 
     private DataObject deserilialize(final SchemaPath rpcPath, final NormalizedNode<?, ?> input) {
-        if(input instanceof LazySerializedContainerNode) {
+        if (input instanceof LazySerializedContainerNode) {
             return ((LazySerializedContainerNode) input).bindingData();
         }
         final SchemaPath inputSchemaPath = rpcPath.createChild(QName.create(module,"input"));
@@ -67,7 +86,7 @@ public class BindingDOMRpcImplementationAdapter implements DOMRpcImplementation
 
     private CheckedFuture<DOMRpcResult, DOMRpcException> transformResult(final SchemaPath schemaPath,
             final ListenableFuture<RpcResult<?>> bindingResult) {
-        return LazyDOMRpcResultFuture.create(codec,bindingResult);
+        return LazyDOMRpcResultFuture.create(codec, bindingResult);
     }
 
 }
index ca8733030837aed2aad1f6a003b657b6bb05abf6..f9cbe272318d64b86f1ef60a5d403a63e6ec687a 100644 (file)
@@ -8,7 +8,11 @@
 package org.opendaylight.controller.md.sal.binding.impl;
 
 import com.google.common.collect.ImmutableSet;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
@@ -32,44 +36,38 @@ public class BindingDOMRpcProviderServiceAdapter {
 
     public <S extends RpcService, T extends S> ObjectRegistration<T> registerRpcImplementation(final Class<S> type,
             final T implementation) {
-        return register(type,implementation,createDomRpcIdentifiers(type,GLOBAL));
+        return register(type, implementation, GLOBAL);
     }
 
     public <S extends RpcService, T extends S> ObjectRegistration<T> registerRpcImplementation(final Class<S> type,
             final T implementation, final Set<InstanceIdentifier<?>> paths) {
-        return register(type,implementation,createDomRpcIdentifiers(type,toYangInstanceIdentifiers(paths)));
+        return register(type, implementation, toYangInstanceIdentifiers(paths));
     }
 
-    private <S extends RpcService, T extends S> ObjectRegistration<T> register(final Class<S> type, final T implementation, final Set<DOMRpcIdentifier> domRpcs) {
-        final BindingDOMRpcImplementationAdapter adapter = new BindingDOMRpcImplementationAdapter(codec.getCodecRegistry(), type, implementation);
-
+    private <S extends RpcService, T extends S> ObjectRegistration<T> register(final Class<S> type, final T implementation, final Collection<YangInstanceIdentifier> rpcContextPaths) {
+        final Map<SchemaPath, Method> rpcs = codec.getRpcMethodToSchemaPath(type).inverse();
 
+        final BindingDOMRpcImplementationAdapter adapter = new BindingDOMRpcImplementationAdapter(codec.getCodecRegistry(), type, rpcs, implementation);
+        final Set<DOMRpcIdentifier> domRpcs = createDomRpcIdentifiers(rpcs.keySet(), rpcContextPaths);
         final DOMRpcImplementationRegistration<?> domReg = domRpcRegistry.registerRpcImplementation(adapter, domRpcs);
         return new BindingRpcAdapterRegistration<>(implementation, domReg);
     }
 
-    private Set<DOMRpcIdentifier> createDomRpcIdentifiers(final Class<? extends RpcService> type, final Set<YangInstanceIdentifier> paths) {
-        final Set<SchemaPath> rpcs = getRpcSchemaPaths(type);
-
+    private static Set<DOMRpcIdentifier> createDomRpcIdentifiers(final Set<SchemaPath> rpcs, final Collection<YangInstanceIdentifier> paths) {
         final Set<DOMRpcIdentifier> ret = new HashSet<>();
-        for(final YangInstanceIdentifier path : paths) {
-            for(final SchemaPath rpc : rpcs) {
+        for (final YangInstanceIdentifier path : paths) {
+            for (final SchemaPath rpc : rpcs) {
                 ret.add(DOMRpcIdentifier.create(rpc, path));
             }
         }
         return ret;
     }
 
-    private Set<YangInstanceIdentifier> toYangInstanceIdentifiers(final Set<InstanceIdentifier<?>> identifiers) {
-        final Set<YangInstanceIdentifier> ret = new HashSet<>();
-        for(final InstanceIdentifier<?> binding: identifiers) {
+    private Collection<YangInstanceIdentifier> toYangInstanceIdentifiers(final Set<InstanceIdentifier<?>> identifiers) {
+        final Collection<YangInstanceIdentifier> ret = new ArrayList<>(identifiers.size());
+        for (final InstanceIdentifier<?> binding : identifiers) {
             ret.add(codec.toYangInstanceIdentifierCached(binding));
         }
         return ret;
     }
-
-    private Set<SchemaPath> getRpcSchemaPaths(final Class<? extends RpcService> type) {
-        return codec.getRpcMethodToSchemaPath(type).values();
-    }
-
 }