Binding v2 runtime - adapters - impl - operations invoker 35/59235/2
authorJakub Toth <jakub.toth@pantheon.tech>
Mon, 19 Jun 2017 13:38:57 +0000 (15:38 +0200)
committerMartin Ciglan <martin.ciglan@pantheon.tech>
Tue, 20 Jun 2017 13:57:18 +0000 (13:57 +0000)
  * added marker for operations

Change-Id: I7bf7144bf35882694c7223d6b3e5e2196757bd12
Signed-off-by: Jakub Toth <jakub.toth@pantheon.tech>
(cherry picked from commit 76cea2ee405a4edcec07788a21fb9c4848676554)

17 files changed:
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/AbstractMappedOperationInvoker.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/ClassBasedOperationServiceInvoker.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/LocalNameOperationServiceInvoker.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvoker.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithInput.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithoutInput.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationServiceInvoker.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/QNameOperationServiceInvoker.java [new file with mode: 0644]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMOperationAdapterRegistration.java [moved from binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMActionAdapterRegistration.java with 65% similarity]
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMRpcAdapterRegistration.java [deleted file]
binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/context/util/BindingSchemaContextUtils.java
binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflections.java
binding2/mdsal-binding2-runtime/src/test/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflectionsTest.java
binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Action.java
binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/ListAction.java
binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Operation.java [new file with mode: 0644]
binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Rpc.java

diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/AbstractMappedOperationInvoker.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/AbstractMappedOperationInvoker.java
new file mode 100644 (file)
index 0000000..fe7068e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.Future;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Beta
+abstract class AbstractMappedOperationInvoker<T> extends OperationServiceInvoker {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractMappedOperationInvoker.class);
+    private final Map<T, OperationMethodInvoker> map;
+
+    protected AbstractMappedOperationInvoker(final Map<T, Method> map) {
+        final Builder<T, OperationMethodInvoker> b = ImmutableMap.builder();
+
+        for (final Entry<T, Method> e : map.entrySet()) {
+            if (BindingReflections.isOperationMethod(e.getValue())) {
+                b.put(e.getKey(), OperationMethodInvoker.from(e.getValue()));
+            } else {
+                LOG.debug("Method {} is not an operation method, ignoring it", e.getValue());
+            }
+        }
+
+        this.map = b.build();
+    }
+
+    protected abstract T qnameToKey(QName qname);
+
+    @Override
+    public final <I extends Operation> Future<RpcResult<?>> invoke(@Nonnull final I impl,
+            @Nonnull final QName operationName, @Nullable final Instantiable<?> input) {
+
+        Preconditions.checkNotNull(impl, "Implementation must be supplied");
+
+        final OperationMethodInvoker invoker = map.get(qnameToKey(operationName));
+        Preconditions.checkArgument(invoker != null, "Supplied operation is not valid for implementation %s", impl);
+        return invoker.invokeOn(impl, input);
+    }
+}
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/ClassBasedOperationServiceInvoker.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/ClassBasedOperationServiceInvoker.java
new file mode 100644 (file)
index 0000000..9d9e9db
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
+import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.yangtools.yang.common.QName;
+
+@Beta
+final class ClassBasedOperationServiceInvoker extends AbstractMappedOperationInvoker<String> {
+
+    private static final LoadingCache<Class<? extends Operation>, OperationServiceInvoker> INVOKERS = CacheBuilder
+            .newBuilder().weakKeys().build(new CacheLoader<Class<? extends Operation>, OperationServiceInvoker>() {
+                @Nonnull
+                @Override
+                public OperationServiceInvoker load(@Nonnull final Class<? extends Operation> key) {
+                    final Map<String, Method> ret = new HashMap<>();
+                    for (final Method m : key.getMethods()) {
+                        ret.put(m.getName(), m);
+                    }
+
+                    return new ClassBasedOperationServiceInvoker(ret);
+                }
+            });
+
+    ClassBasedOperationServiceInvoker(final Map<String, Method> ret) {
+        super(ret);
+    }
+
+    @Override
+    protected String qnameToKey(final QName qname) {
+        return JavaIdentifierNormalizer.normalizeSpecificIdentifier(qname.getLocalName(), JavaIdentifier.METHOD);
+    }
+
+    static OperationServiceInvoker instanceFor(final Class<? extends Operation> type) {
+        Preconditions.checkArgument(type.isInterface());
+        Preconditions.checkArgument(BindingReflections.isBindingClass(type));
+        return INVOKERS.getUnchecked(type);
+    }
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/LocalNameOperationServiceInvoker.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/LocalNameOperationServiceInvoker.java
new file mode 100644 (file)
index 0000000..9e2c377
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+
+@Beta
+final class LocalNameOperationServiceInvoker extends AbstractMappedOperationInvoker<String> {
+    private final QNameModule module;
+
+    private LocalNameOperationServiceInvoker(final QNameModule module, final Map<String, Method> map) {
+        super(map);
+        this.module = Preconditions.checkNotNull(module);
+    }
+
+    static OperationServiceInvoker instanceFor(final QNameModule module, final Map<QName, Method> qnameToMethod) {
+        final Map<String, Method> map = new HashMap<>();
+        for (final Entry<QName, Method> e : qnameToMethod.entrySet()) {
+            map.put(e.getKey().getLocalName(), e.getValue());
+        }
+        return new LocalNameOperationServiceInvoker(module, map);
+    }
+
+    @Override
+    protected String qnameToKey(final QName qname) {
+        if (module.equals(qname.getModule())) {
+            return qname.getLocalName();
+        } else {
+            return null;
+        }
+    }
+}
+
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvoker.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvoker.java
new file mode 100644 (file)
index 0000000..17f4f81
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.base.Throwables;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.reflect.Method;
+import java.util.concurrent.Future;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+@Beta
+abstract class OperationMethodInvoker {
+
+    private static final Lookup LOOKUP = MethodHandles.publicLookup();
+
+    protected abstract <T extends Operation> Future<RpcResult<?>> invokeOn(T impl, Instantiable<?> input);
+
+    protected static OperationMethodInvoker from(final Method method) {
+        final Optional<Class<? extends Instantiable<?>>> input = BindingReflections.resolveOperationInputClass(method);
+        try {
+            final MethodHandle methodHandle = LOOKUP.unreflect(method);
+            if (input.isPresent()) {
+                return new OperationMethodInvokerWithInput(methodHandle);
+            }
+            return new OperationMethodInvokerWithoutInput(methodHandle);
+        } catch (final IllegalAccessException e) {
+            throw new IllegalStateException("Lookup on public method failed.", e);
+        }
+    }
+
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    protected Future<RpcResult<?>> invoking(final MethodHandle handle, final Object... args) {
+        try {
+            return (Future<RpcResult<?>>) handle.invokeExact(args);
+        } catch (final Throwable e) {
+            throw Throwables.propagate(e);
+        }
+    }
+}
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithInput.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithInput.java
new file mode 100644 (file)
index 0000000..f1fa21b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.Future;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.ListAction;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+@Beta
+class OperationMethodInvokerWithInput extends OperationMethodInvoker {
+
+    private static final MethodType INVOCATION_SIGNATURE =
+            MethodType.methodType(Future.class, Rpc.class, Action.class, ListAction.class, Instantiable.class);
+
+    private final MethodHandle handle;
+
+    OperationMethodInvokerWithInput(final MethodHandle methodHandle) {
+        this.handle = methodHandle.asType(INVOCATION_SIGNATURE);
+    }
+
+    @Override
+    public <T extends Operation> Future<RpcResult<?>> invokeOn(final T impl, final Instantiable<?> input) {
+        return invoking(handle, impl, input);
+    }
+}
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithoutInput.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithoutInput.java
new file mode 100644 (file)
index 0000000..7316fc7
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.Future;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.ListAction;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+@Beta
+class OperationMethodInvokerWithoutInput extends OperationMethodInvoker {
+
+    private static final MethodType INVOCATION_SIGNATURE =
+            MethodType.methodType(Future.class, Rpc.class, Action.class, ListAction.class);
+
+    private final MethodHandle handle;
+
+    OperationMethodInvokerWithoutInput(final MethodHandle methodHandle) {
+        this.handle = methodHandle.asType(INVOCATION_SIGNATURE);
+    }
+
+    @Override
+    public <T extends Operation> Future<RpcResult<?>> invokeOn(final T impl, final Instantiable<?> input) {
+        return invoking(handle, impl);
+    }
+}
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationServiceInvoker.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationServiceInvoker.java
new file mode 100644 (file)
index 0000000..52b473e
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.Future;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides single method invocation of operations on supplied instance.
+ *
+ * <p>
+ * Operation Service invoker provides common invocation interface for any subtype of operation. via
+ * {@link #invoke(Operation, QName, Instantiable)} method.
+ */
+@Beta
+public abstract class OperationServiceInvoker {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OperationServiceInvoker.class);
+
+    /**
+     * Creates OperationServiceInvoker for specified operation type.
+     *
+     * @param type
+     *            operation interface, which was generated from model.
+     * @return Cached instance of {@link OperationServiceInvoker} for supplied operation type.
+     *
+     */
+    public static OperationServiceInvoker from(final Class<? extends Operation> type) {
+        return ClassBasedOperationServiceInvoker.instanceFor(type);
+    }
+
+    /**
+     * Creates an OperationServiceInvoker for specified QName-&lt;Method mapping.
+     *
+     * @param qnameToMethod
+     *            translation mapping, must not be null nor empty.
+     * @return An {@link OperationMethodInvoker} instance.
+     */
+    public static OperationServiceInvoker from(final Map<QName, Method> qnameToMethod) {
+        Preconditions.checkArgument(!qnameToMethod.isEmpty());
+        QNameModule module = null;
+
+        for (final QName qname : qnameToMethod.keySet()) {
+            if (module != null) {
+                if (!module.equals(qname.getModule())) {
+                    LOG.debug("QNames from different modules {} and {}, falling back to QName map", module,
+                            qname.getModule());
+                    return QNameOperationServiceInvoker.instanceFor(qnameToMethod);
+                }
+            } else {
+                module = qname.getModule();
+            }
+        }
+
+        // All module are equal, which means we can use localName only
+        return LocalNameOperationServiceInvoker.instanceFor(module, qnameToMethod);
+    }
+
+    /**
+     * Invokes supplied operation on provided implementation of Operation Service.
+     *
+     * @param <T>
+     *            - operation type
+     * @param impl
+     *            Implementation on which operation should be invoked.
+     * @param operationName
+     *            Name of operation to be invoked.
+     * @param input
+     *            Input data for operation.
+     * @return Future which will complete once operation processing is finished.
+     */
+    public abstract <T extends Operation> Future<RpcResult<?>> invoke(@Nonnull T impl, @Nonnull QName operationName,
+            @Nullable Instantiable<?> input);
+}
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/QNameOperationServiceInvoker.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/QNameOperationServiceInvoker.java
new file mode 100644 (file)
index 0000000..726c6d5
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.adapter.impl.operation.invoker;
+
+import com.google.common.annotations.Beta;
+import java.lang.reflect.Method;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
+
+@Beta
+final class QNameOperationServiceInvoker extends AbstractMappedOperationInvoker<QName> {
+
+    private QNameOperationServiceInvoker(final Map<QName, Method> qnameToMethod) {
+        super(qnameToMethod);
+    }
+
+    static OperationServiceInvoker instanceFor(final Map<QName, Method> qnameToMethod) {
+        return new QNameOperationServiceInvoker(qnameToMethod);
+    }
+
+    @Override
+    protected QName qnameToKey(final QName qname) {
+        return qname;
+    }
+}
\ No newline at end of file
@@ -8,25 +8,23 @@
 package org.opendaylight.mdsal.binding.javav2.dom.adapter.registration;
 
 import com.google.common.annotations.Beta;
-import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
-import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
 import org.opendaylight.mdsal.dom.api.DOMRpcImplementationRegistration;
 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 
 /**
- * Registration of Binding - DOM Action adapter.
+ * Registration of Binding - DOM Operation adapter.
  *
  * @param <T>
- *            - {@link Action} type
+ *            - {@link Operation} type
  */
 @Beta
-public class BindingDOMActionAdapterRegistration<T extends Action<? extends TreeNode, ?, ?>>
-        extends AbstractObjectRegistration<T> {
+public class BindingDOMOperationAdapterRegistration<T extends Operation> extends AbstractObjectRegistration<T> {
 
     private final DOMRpcImplementationRegistration<?> reg;
 
     // FIXME : DOM part doesn't work with Yang 1.1 - Action registration isn't implemented yet.
-    public BindingDOMActionAdapterRegistration(final T instance, final DOMRpcImplementationRegistration<?> reg) {
+    public BindingDOMOperationAdapterRegistration(final T instance, final DOMRpcImplementationRegistration<?> reg) {
         super(instance);
         this.reg = reg;
     }
@@ -35,4 +33,4 @@ public class BindingDOMActionAdapterRegistration<T extends Action<? extends Tree
     protected void removeRegistration() {
         reg.close();
     }
-}
+}
\ No newline at end of file
diff --git a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMRpcAdapterRegistration.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMRpcAdapterRegistration.java
deleted file mode 100644 (file)
index 41663a8..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.adapter.registration;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementationRegistration;
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
-
-/**
- * Registration of Binding - DOM RPC adapter.
- *
- * @param <T>
- *            - {@link Rpc} type
- */
-@Beta
-public class BindingDOMRpcAdapterRegistration<T extends Rpc<?, ?>> extends AbstractObjectRegistration<T> {
-
-    private final DOMRpcImplementationRegistration<?> reg;
-
-    public BindingDOMRpcAdapterRegistration(final T instance, final DOMRpcImplementationRegistration<?> reg) {
-        super(instance);
-        this.reg = reg;
-    }
-
-    @Override
-    protected void removeRegistration() {
-        reg.close();
-    }
-}
\ No newline at end of file
index 5defa72f2944c66c5360acf7f93138364f5590cf..3050d60d85166aef4afbd6776467403f4a36f8e3 100644 (file)
@@ -63,7 +63,7 @@ public final class BindingSchemaContextUtils {
         Optional<DataNodeContainer> currentContainer = Optional.absent();
         if (BindingReflections.isNotification(currentArg.getType())) {
             currentContainer = findNotification(ctx, currentQName);
-        } else if (BindingReflections.isRpcOrActionType(currentArg.getType())) {
+        } else if (BindingReflections.isOperationType(currentArg.getType())) {
             currentContainer = findFirstDataNodeContainerInRpcOrAction(ctx, currentArg.getType());
             if(currentQName == null && currentContainer.isPresent()) {
                 currentQName = ((DataSchemaNode) currentContainer.get()).getQName();
index d40a6eed794dc71c1ad5df5a8e5da58e0876beb1..c19e62d82aa7c7a4f8b337a77eea7fc569d62abe 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.mdsal.binding.javav2.runtime.reflection;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
-
 import com.google.common.annotations.Beta;
 import com.google.common.base.Optional;
 import com.google.common.cache.CacheBuilder;
@@ -34,11 +33,10 @@ import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import javax.annotation.Nonnull;
-import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
 import org.opendaylight.mdsal.binding.javav2.spec.base.BaseIdentity;
 import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
 import org.opendaylight.mdsal.binding.javav2.spec.base.Notification;
-import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
 import org.opendaylight.mdsal.binding.javav2.spec.runtime.YangModelBindingProvider;
 import org.opendaylight.mdsal.binding.javav2.spec.runtime.YangModuleInfo;
@@ -58,7 +56,7 @@ public final class BindingReflections {
 
     private static final long EXPIRATION_TIME = 60;
     private static final String QNAME_STATIC_FIELD_NAME = "QNAME";
-    private static final String RPC_ACTION_OUTPUT_SUFFIX = "Output";
+    private static final String OPERATION_ACTION_OUTPUT_SUFFIX = "Output";
     private static final String MODULE_INFO_CLASS_NAME = "$YangModuleInfoImpl";
     private static final String PACKAGE_PREFIX = "org.opendaylight.mdsal.gen.javav2";
     private static final String ROOT_PACKAGE_PATTERN_STRING =
@@ -127,13 +125,13 @@ public final class BindingReflections {
      *            - method to check
      * @return true if method is RPC or Action invocation, false otherwise.
      */
-    public static boolean isRpcOrActionMethod(final Method possibleMethod) {
-        return possibleMethod != null && (Rpc.class.isAssignableFrom(possibleMethod.getDeclaringClass())
-                || Action.class.isAssignableFrom(possibleMethod.getDeclaringClass()))
+    public static boolean isOperationMethod(final Method possibleMethod) {
+        return possibleMethod != null && Operation.class.isAssignableFrom(possibleMethod.getDeclaringClass())
                 && Future.class.isAssignableFrom(possibleMethod.getReturnType())
-                // length <= 2: it seemed to be impossible to get correct RpcMethodInvoker because of
-                // resolveRpcInputClass() check.While RpcMethodInvoker counts with one argument for
-                // non input type and two arguments for input type, resolveRpcInputClass() counting
+                // length <= 2: it seemed to be impossible to get correct OperationMethodInvoker because of
+                // resolveOperationInputClass() check.While OperationMethodInvoker counts with one argument
+                // for
+                // non input type and two arguments for input type, resolveOperationInputClass() counting
                 // with zero for non input and one for input type
                 && possibleMethod.getParameterTypes().length <= 2;
     }
@@ -147,13 +145,13 @@ public final class BindingReflections {
      *         is Void.
      */
     @SuppressWarnings("rawtypes")
-    public static Optional<Class<?>> resolveRpcOutputClass(final Method targetMethod) {
-        checkState(isRpcOrActionMethod(targetMethod), "Supplied method is not a RPC or Action invocation method");
+    public static Optional<Class<?>> resolveOperationOutputClass(final Method targetMethod) {
+        checkState(isOperationMethod(targetMethod), "Supplied method is not a RPC or Action invocation method");
         final Type futureType = targetMethod.getGenericReturnType();
-        final Type rpcResultType = ClassLoaderUtils.getFirstGenericParameter(futureType);
-        final Type rpcResultArgument = ClassLoaderUtils.getFirstGenericParameter(rpcResultType);
-        if (rpcResultArgument instanceof Class && !Void.class.equals(rpcResultArgument)) {
-            return Optional.of((Class) rpcResultArgument);
+        final Type operationResultType = ClassLoaderUtils.getFirstGenericParameter(futureType);
+        final Type operationResultArgument = ClassLoaderUtils.getFirstGenericParameter(operationResultType);
+        if (operationResultArgument instanceof Class && !Void.class.equals(operationResultArgument)) {
+            return Optional.of((Class) operationResultArgument);
         }
         return Optional.absent();
     }
@@ -167,7 +165,7 @@ public final class BindingReflections {
      *         otherwise.
      */
     @SuppressWarnings({ "rawtypes", "unchecked" })
-    public static Optional<Class<? extends Instantiable<?>>> resolveRpcInputClass(final Method targetMethod) {
+    public static Optional<Class<? extends Instantiable<?>>> resolveOperationInputClass(final Method targetMethod) {
         for (final Class clazz : targetMethod.getParameterTypes()) {
             if (Instantiable.class.isAssignableFrom(clazz)) {
                 return Optional.of(clazz);
@@ -403,7 +401,7 @@ public final class BindingReflections {
      *            - class to be checked
      * @return true if class represents RPC or Action input/output class
      */
-    public static boolean isRpcOrActionType(final Class<? extends TreeNode> targetType) {
+    public static boolean isOperationType(final Class<? extends TreeNode> targetType) {
         return Instantiable.class.isAssignableFrom(targetType) && !TreeChildNode.class.isAssignableFrom(targetType)
                 && !Notification.class.isAssignableFrom(targetType)
                 && (targetType.getName().endsWith("Input") || targetType.getName().endsWith("Output"));
@@ -564,9 +562,9 @@ public final class BindingReflections {
                 final QName module = getModuleQName(moduleInfo).intern();
                 if (Augmentation.class.isAssignableFrom(key)) {
                     return module;
-                } else if (isRpcOrActionType(key)) {
+                } else if (isOperationType(key)) {
                     final String className = key.getSimpleName();
-                    if (className.endsWith(RPC_ACTION_OUTPUT_SUFFIX)) {
+                    if (className.endsWith(OPERATION_ACTION_OUTPUT_SUFFIX)) {
                         return QName.create(module, "output").intern();
                     } else {
                         return QName.create(module, "input").intern();
index 157b70911d492fae38bc60d804e4cc99c312cb18..36146d55a4dac89ca0f7641689371456dd587107 100644 (file)
@@ -38,7 +38,7 @@ public class BindingReflectionsTest {
         assertEquals("ModuleInfoClassName should be equal to string", "test.$YangModuleInfoImpl",
                 BindingReflections.getModuleInfoClassName("test"));
         assertEquals("Module info should be empty Set", Collections.EMPTY_SET, BindingReflections.loadModuleInfos());
-        assertFalse("Should not be RpcType", BindingReflections.isRpcOrActionType(TreeNode.class));
+        assertFalse("Should not be RpcType", BindingReflections.isOperationType(TreeNode.class));
         assertFalse("Should not be AugmentationChild", BindingReflections.isAugmentationChild(TreeNode.class));
         assertTrue("Should be BindingClass", BindingReflections.isBindingClass(TreeNode.class));
         assertFalse("Should not be Notification", BindingReflections.isNotification(TreeNode.class));
@@ -47,13 +47,13 @@ public class BindingReflectionsTest {
 
         assertEquals(GroupingFoo.class, BindingReflections.findHierarchicalParent(FooChild.class));
 
-        assertTrue(BindingReflections.isRpcOrActionMethod(TestImplementation.class.getDeclaredMethod("rpcMethodTest")));
+        assertTrue(BindingReflections.isOperationMethod(TestImplementation.class.getDeclaredMethod("rpcMethodTest")));
         assertEquals(TestImplementation.class, BindingReflections.findAugmentationTarget(TestImplementation.class));
 
         assertEquals(Object.class, BindingReflections
-                .resolveRpcOutputClass(TestImplementation.class.getDeclaredMethod("rpcMethodTest")).get());
+                .resolveOperationOutputClass(TestImplementation.class.getDeclaredMethod("rpcMethodTest")).get());
         assertFalse(BindingReflections
-                .resolveRpcOutputClass(TestImplementation.class.getDeclaredMethod("rpcMethodTest2")).isPresent());
+                .resolveOperationOutputClass(TestImplementation.class.getDeclaredMethod("rpcMethodTest2")).isPresent());
 
         assertTrue(BindingReflections.getQName(TestImplementation.class).toString().equals("test"));
     }
index bbda46ed2b93d2a500138fc1f0037d4251a825dd..ce35462807e5cef2fa6343f1b064bc77ac9859d0 100644 (file)
@@ -24,7 +24,8 @@ package org.opendaylight.mdsal.binding.javav2.spec.base;
  *
  */
 @FunctionalInterface
-public interface Action<P extends TreeNode, I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>> {
+public interface Action<P extends TreeNode, I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>>
+        extends Operation {
 
     /**
      * @param input Action input schema node
index 5ff26e16f7a75755ca087b8a7c6dbc40908f0cc7..79a6a8605f498b99a4a7e1996c9cc6287b7e5007 100644 (file)
@@ -26,7 +26,8 @@ package org.opendaylight.mdsal.binding.javav2.spec.base;
  *
  */
 @FunctionalInterface
-public interface ListAction<P extends TreeNode, I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>> {
+public interface ListAction<P extends TreeNode, I extends Input<I> & Instantiable<I>,
+        O extends Output<O> & Instantiable<O>> extends Operation {
 
     /**
      * @param input Action input schema node
diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Operation.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Operation.java
new file mode 100644 (file)
index 0000000..4b2d5f5
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.spec.base;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Marker interface for tagging operations - RPC, Action and ListAction.
+ */
+@Beta
+public interface Operation {
+
+}
index 08d7fb1520c606aa28082308a7343c3ba761aff3..c5003900a92ab88b39199232bf5147037d8c599a 100644 (file)
@@ -17,7 +17,7 @@ package org.opendaylight.mdsal.binding.javav2.spec.base;
  *
  */
 @FunctionalInterface
-public interface Rpc<I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>> {
+public interface Rpc<I extends Input<I> & Instantiable<I>, O extends Output<O> & Instantiable<O>> extends Operation {
 
     /**
      * @param input Rpc input schema node