From 4e32d91d1e1e9d6831e33f660b7930b430a9908e Mon Sep 17 00:00:00 2001 From: Jakub Toth Date: Mon, 19 Jun 2017 15:38:57 +0200 Subject: [PATCH] Binding v2 runtime - adapters - impl - operations invoker * added marker for operations Change-Id: I7bf7144bf35882694c7223d6b3e5e2196757bd12 Signed-off-by: Jakub Toth (cherry picked from commit 76cea2ee405a4edcec07788a21fb9c4848676554) --- .../AbstractMappedOperationInvoker.java | 60 ++++++++++++ .../ClassBasedOperationServiceInvoker.java | 56 ++++++++++++ .../LocalNameOperationServiceInvoker.java | 45 +++++++++ .../invoker/OperationMethodInvoker.java | 51 +++++++++++ .../OperationMethodInvokerWithInput.java | 37 ++++++++ .../OperationMethodInvokerWithoutInput.java | 37 ++++++++ .../invoker/OperationServiceInvoker.java | 91 +++++++++++++++++++ .../invoker/QNameOperationServiceInvoker.java | 30 ++++++ ...ndingDOMOperationAdapterRegistration.java} | 14 ++- .../BindingDOMRpcAdapterRegistration.java | 35 ------- .../util/BindingSchemaContextUtils.java | 2 +- .../reflection/BindingReflections.java | 38 ++++---- .../reflection/BindingReflectionsTest.java | 8 +- .../binding/javav2/spec/base/Action.java | 3 +- .../binding/javav2/spec/base/ListAction.java | 3 +- .../binding/javav2/spec/base/Operation.java | 18 ++++ .../mdsal/binding/javav2/spec/base/Rpc.java | 2 +- 17 files changed, 459 insertions(+), 71 deletions(-) create mode 100644 binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/AbstractMappedOperationInvoker.java create mode 100644 binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/ClassBasedOperationServiceInvoker.java create mode 100644 binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/LocalNameOperationServiceInvoker.java create mode 100644 binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvoker.java create mode 100644 binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithInput.java create mode 100644 binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithoutInput.java create mode 100644 binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationServiceInvoker.java create mode 100644 binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/QNameOperationServiceInvoker.java rename binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/{BindingDOMActionAdapterRegistration.java => BindingDOMOperationAdapterRegistration.java} (65%) delete mode 100644 binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMRpcAdapterRegistration.java create mode 100644 binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Operation.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 index 0000000000..fe7068e551 --- /dev/null +++ b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/AbstractMappedOperationInvoker.java @@ -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 extends OperationServiceInvoker { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractMappedOperationInvoker.class); + private final Map map; + + protected AbstractMappedOperationInvoker(final Map map) { + final Builder b = ImmutableMap.builder(); + + for (final Entry 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 Future> 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 index 0000000000..9d9e9db50d --- /dev/null +++ b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/ClassBasedOperationServiceInvoker.java @@ -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 { + + private static final LoadingCache, OperationServiceInvoker> INVOKERS = CacheBuilder + .newBuilder().weakKeys().build(new CacheLoader, OperationServiceInvoker>() { + @Nonnull + @Override + public OperationServiceInvoker load(@Nonnull final Class key) { + final Map ret = new HashMap<>(); + for (final Method m : key.getMethods()) { + ret.put(m.getName(), m); + } + + return new ClassBasedOperationServiceInvoker(ret); + } + }); + + ClassBasedOperationServiceInvoker(final Map ret) { + super(ret); + } + + @Override + protected String qnameToKey(final QName qname) { + return JavaIdentifierNormalizer.normalizeSpecificIdentifier(qname.getLocalName(), JavaIdentifier.METHOD); + } + + static OperationServiceInvoker instanceFor(final Class 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 index 0000000000..9e2c3773dc --- /dev/null +++ b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/LocalNameOperationServiceInvoker.java @@ -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 { + private final QNameModule module; + + private LocalNameOperationServiceInvoker(final QNameModule module, final Map map) { + super(map); + this.module = Preconditions.checkNotNull(module); + } + + static OperationServiceInvoker instanceFor(final QNameModule module, final Map qnameToMethod) { + final Map map = new HashMap<>(); + for (final Entry 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 index 0000000000..17f4f817cb --- /dev/null +++ b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvoker.java @@ -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 Future> invokeOn(T impl, Instantiable input); + + protected static OperationMethodInvoker from(final Method method) { + final Optional>> 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> invoking(final MethodHandle handle, final Object... args) { + try { + return (Future>) 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 index 0000000000..f1fa21b41a --- /dev/null +++ b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithInput.java @@ -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 Future> 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 index 0000000000..7316fc7f80 --- /dev/null +++ b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationMethodInvokerWithoutInput.java @@ -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 Future> 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 index 0000000000..52b473e12e --- /dev/null +++ b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/OperationServiceInvoker.java @@ -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. + * + *

+ * 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 type) { + return ClassBasedOperationServiceInvoker.instanceFor(type); + } + + /** + * Creates an OperationServiceInvoker for specified QName-<Method mapping. + * + * @param qnameToMethod + * translation mapping, must not be null nor empty. + * @return An {@link OperationMethodInvoker} instance. + */ + public static OperationServiceInvoker from(final Map 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 + * - 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 Future> 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 index 0000000000..726c6d5c76 --- /dev/null +++ b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/operation/invoker/QNameOperationServiceInvoker.java @@ -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 { + + private QNameOperationServiceInvoker(final Map qnameToMethod) { + super(qnameToMethod); + } + + static OperationServiceInvoker instanceFor(final Map qnameToMethod) { + return new QNameOperationServiceInvoker(qnameToMethod); + } + + @Override + protected QName qnameToKey(final QName qname) { + return qname; + } +} \ 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/BindingDOMActionAdapterRegistration.java b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMOperationAdapterRegistration.java similarity index 65% rename from binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMActionAdapterRegistration.java rename to binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMOperationAdapterRegistration.java index 5644bbd5c0..f30a550d00 100644 --- a/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMActionAdapterRegistration.java +++ b/binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/registration/BindingDOMOperationAdapterRegistration.java @@ -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 - * - {@link Action} type + * - {@link Operation} type */ @Beta -public class BindingDOMActionAdapterRegistration> - extends AbstractObjectRegistration { +public class BindingDOMOperationAdapterRegistration extends AbstractObjectRegistration { 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 - * - {@link Rpc} type - */ -@Beta -public class BindingDOMRpcAdapterRegistration> extends AbstractObjectRegistration { - - 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 diff --git a/binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/context/util/BindingSchemaContextUtils.java b/binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/context/util/BindingSchemaContextUtils.java index 5defa72f29..3050d60d85 100644 --- a/binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/context/util/BindingSchemaContextUtils.java +++ b/binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/context/util/BindingSchemaContextUtils.java @@ -63,7 +63,7 @@ public final class BindingSchemaContextUtils { Optional 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(); diff --git a/binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflections.java b/binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflections.java index d40a6eed79..c19e62d82a 100644 --- a/binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflections.java +++ b/binding2/mdsal-binding2-runtime/src/main/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflections.java @@ -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> resolveRpcOutputClass(final Method targetMethod) { - checkState(isRpcOrActionMethod(targetMethod), "Supplied method is not a RPC or Action invocation method"); + public static Optional> 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>> resolveRpcInputClass(final Method targetMethod) { + public static Optional>> 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 targetType) { + public static boolean isOperationType(final Class 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(); diff --git a/binding2/mdsal-binding2-runtime/src/test/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflectionsTest.java b/binding2/mdsal-binding2-runtime/src/test/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflectionsTest.java index 157b70911d..36146d55a4 100644 --- a/binding2/mdsal-binding2-runtime/src/test/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflectionsTest.java +++ b/binding2/mdsal-binding2-runtime/src/test/java/org/opendaylight/mdsal/binding/javav2/runtime/reflection/BindingReflectionsTest.java @@ -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")); } diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Action.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Action.java index bbda46ed2b..ce35462807 100644 --- a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Action.java +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Action.java @@ -24,7 +24,8 @@ package org.opendaylight.mdsal.binding.javav2.spec.base; * */ @FunctionalInterface -public interface Action

& Instantiable, O extends Output & Instantiable> { +public interface Action

& Instantiable, O extends Output & Instantiable> + 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/ListAction.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/ListAction.java index 5ff26e16f7..79a6a8605f 100644 --- a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/ListAction.java +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/ListAction.java @@ -26,7 +26,8 @@ package org.opendaylight.mdsal.binding.javav2.spec.base; * */ @FunctionalInterface -public interface ListAction

& Instantiable, O extends Output & Instantiable> { +public interface ListAction

& Instantiable, + O extends Output & Instantiable> 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 index 0000000000..4b2d5f5ae2 --- /dev/null +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Operation.java @@ -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 { + +} diff --git a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Rpc.java b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Rpc.java index 08d7fb1520..c5003900a9 100644 --- a/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Rpc.java +++ b/binding2/mdsal-binding2-spec/src/main/java/org/opendaylight/mdsal/binding/javav2/spec/base/Rpc.java @@ -17,7 +17,7 @@ package org.opendaylight.mdsal.binding.javav2.spec.base; * */ @FunctionalInterface -public interface Rpc & Instantiable, O extends Output & Instantiable> { +public interface Rpc & Instantiable, O extends Output & Instantiable> extends Operation { /** * @param input Rpc input schema node -- 2.36.6