From 2ebaf41bbbd58e07807278c142b454bc6d547f94 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 29 Jan 2024 12:02:01 +0100 Subject: [PATCH 1/2] Bump upstreams Adopt: - yangtools-13.0.1 - mdsal-13.0.0 - controller-9.0.0 - aaa-0.19.1 - netconf-7.0.0 Since this project has failed to make progress in migrating its use of yang.binding.RpcService, this patch is rather massive, as we deal with that as well. Change-Id: I85c3db7ef3d85e3e0cb6ff3b9efd795ecb34c72a Signed-off-by: Robert Varga --- binding-adapter/pom.xml | 2 +- .../jsonrpc/binding/AbstractHandler.java | 69 ++--------- .../ControllerRpcInvocationAdapter.java | 18 ++- .../binding/EmbeddedRpcInvocationAdapter.java | 14 +-- .../jsonrpc/binding/InboundHandler.java | 91 ++++++-------- .../jsonrpc/binding/MultiModelBuilder.java | 10 +- .../jsonrpc/binding/MultiModelProxy.java | 24 ++-- .../binding/MultiModelRequestDispatcher.java | 8 +- .../jsonrpc/binding/OutboundHandler.java | 11 +- .../jsonrpc/binding/ProxyContext.java | 12 +- .../jsonrpc/binding/RpcInvocationAdapter.java | 10 +- .../binding/SchemaAwareTransportFactory.java | 47 ++++---- .../binding/SchemaChangeAwareConverter.java | 6 +- .../jsonrpc/binding/TestModelServiceTest.java | 70 ++++++----- .../jsonrpc/dom/codec/AbstractCodec.java | 4 +- .../jsonrpc/dom/codec/DataCodec.java | 11 +- .../dom/codec/JsonRpcCodecFactory.java | 2 +- .../jsonrpc/dom/codec/NotificationCodec.java | 4 +- .../jsonrpc/dom/codec/RpcCodec.java | 10 +- .../jsonrpc/dom/codec/AbstractCodecTest.java | 6 +- .../jsonrpc/dom/codec/DataCodecTest.java | 5 +- .../src/main/feature/feature.xml | 2 +- .../src/main/feature/feature.xml | 4 +- .../src/main/feature/feature.xml | 4 +- .../src/main/feature/feature.xml | 2 +- parent/pom.xml | 6 +- provider/cluster/pom.xml | 11 +- .../cluster/impl/ClusterDependencies.java | 12 +- .../provider/cluster/impl/ClusterUtil.java | 19 ++- .../cluster/impl/JsonRpcPeerListManager.java | 57 +++++---- .../cluster/impl/ProxyDOMDataBroker.java | 13 +- .../cluster/impl/ProxyDOMRpcService.java | 4 +- .../cluster/impl/RemotePeerContext.java | 6 +- .../cluster/impl/SlavePeerContext.java | 25 ++-- .../cluster/tx/ActorProxyTransaction.java | 46 +++---- .../cluster/tx/FailedProxyTransaction.java | 25 ++-- .../cluster/tx/ProxyReadWriteTransaction.java | 22 ++-- .../blueprint/cluster-provider-wiring.xml | 13 +- .../provider/cluster/MountpointTest.java | 37 +++--- .../provider/cluster/TestCustomizer.java | 2 +- provider/common/pom.xml | 4 +- .../impl/DataChangeListenerRegistration.java | 19 +-- .../impl/EnsureParentTransactionFactory.java | 4 +- .../jsonrpc/impl/JsonRPCDataBroker.java | 47 ++++---- .../impl/JsonRPCNotificationService.java | 8 +- .../opendaylight/jsonrpc/impl/JsonRPCTx.java | 18 ++- .../jsonrpc/impl/JsonRPCtoRPCBridge.java | 20 ++- .../jsonrpc/impl/JsonRpcDOMSchemaService.java | 31 ++--- .../jsonrpc/impl/RemoteControlProvider.java | 23 ++-- .../opendaylight/jsonrpc/impl/TxChain.java | 23 ++-- .../model/StringYangTextSchemaSource.java | 48 -------- .../GovernanceSchemaContextProvider.java | 36 +++--- .../InbandModelsSchemaContextProvider.java | 7 +- .../provider/common/MappedPeerContext.java | 2 - .../provider/common/AbstractJsonRpcTest.java | 4 +- .../JsonRPCNotificationServiceTest.java | 6 +- .../provider/common/JsonRPCTE2ETest.java | 54 ++++----- .../provider/common/JsonRPCTxTest.java | 4 +- .../common/JsonRPCtoRPCBridgeTest.java | 20 +-- .../provider/common/RemoteControlTest.java | 4 +- .../RemoteNotificationPublisherTest.java | 23 ++-- .../provider/common/RemoteRpcInvokerTest.java | 34 ++++-- .../jsonrpc/provider/common/TxChainTest.java | 21 ++-- provider/pom.xml | 2 +- provider/single/pom.xml | 2 +- .../provider/single/JsonRPCProvider.java | 26 ++-- .../provider/single/JsonRPCProviderTest.java | 2 +- .../jsonrpc/test/TestErrorMethod.java | 24 ++++ .../jsonrpc/test/TestFactorial.java | 30 +++++ .../jsonrpc/test/TestModelServiceImpl.java | 114 ------------------ .../jsonrpc/test/TestMultiplyList.java | 34 ++++++ .../jsonrpc/test/TestRemoveCoffeePot.java | 30 +++++ .../jsonrpc/test/TestSimpleMethod.java | 23 ++++ .../jsonrpc/tool/test/DatastoreImpl.java | 18 +-- .../jsonrpc/tool/test/GovernanceImpl.java | 18 ++- 75 files changed, 730 insertions(+), 797 deletions(-) delete mode 100644 provider/common/src/main/java/org/opendaylight/jsonrpc/model/StringYangTextSchemaSource.java create mode 100644 test-model/src/test/java/org/opendaylight/jsonrpc/test/TestErrorMethod.java create mode 100644 test-model/src/test/java/org/opendaylight/jsonrpc/test/TestFactorial.java delete mode 100644 test-model/src/test/java/org/opendaylight/jsonrpc/test/TestModelServiceImpl.java create mode 100644 test-model/src/test/java/org/opendaylight/jsonrpc/test/TestMultiplyList.java create mode 100644 test-model/src/test/java/org/opendaylight/jsonrpc/test/TestRemoveCoffeePot.java create mode 100644 test-model/src/test/java/org/opendaylight/jsonrpc/test/TestSimpleMethod.java diff --git a/binding-adapter/pom.xml b/binding-adapter/pom.xml index 32a40da5..be3634f7 100644 --- a/binding-adapter/pom.xml +++ b/binding-adapter/pom.xml @@ -91,7 +91,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.mdsal - mdsal-singleton-common-api + mdsal-singleton-api org.opendaylight.jsonrpc.bus diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/AbstractHandler.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/AbstractHandler.java index e4bce478..00180565 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/AbstractHandler.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/AbstractHandler.java @@ -7,20 +7,11 @@ */ package org.opendaylight.jsonrpc.binding; -import com.google.common.collect.BiMap; -import com.google.common.collect.ImmutableBiMap; import com.google.common.reflect.AbstractInvocationHandler; +import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import java.util.AbstractMap; import java.util.Objects; -import java.util.stream.Collector; -import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext; -import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.binding.contract.Naming; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.QNameModule; -import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.binding.Rpc; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; /** @@ -29,55 +20,21 @@ import org.opendaylight.yangtools.yang.model.api.RpcDefinition; * @author Richard Kosegi * @since Sep 20, 2018 */ -abstract class AbstractHandler extends AbstractInvocationHandler { - protected final BiMap rpcMethodMap; - protected final RpcInvocationAdapter adapter; +abstract class AbstractHandler> extends AbstractInvocationHandler { + final RpcInvocationAdapter adapter; + final RpcDefinition rpcDef; - AbstractHandler(final Class type, RpcInvocationAdapter adapter) { + AbstractHandler(final Class type, final RpcInvocationAdapter adapter) { this.adapter = Objects.requireNonNull(adapter); - rpcMethodMap = getRpcMethodToSchemaPath(type).entrySet() - .stream() - .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), - adapter.schemaContext() - .getOperations() - .stream() - .filter(r -> r.getQName().equals(e.getValue())) - .findFirst() - .orElseThrow())) - .collect(Collector.of(ImmutableBiMap::builder, - (builder, entry) -> builder.put(entry.getKey(), entry.getValue()), - (k, v) -> k.putAll(v.build()), ImmutableBiMap.Builder::build)); + this.rpcDef = (RpcDefinition) adapter.getRuntimeContext().getRpcDefinition(type).statement(); } - ImmutableBiMap getRpcMethodToSchemaPath(final Class key) { - final Module module = getModule(key); - final ImmutableBiMap.Builder ret = ImmutableBiMap.builder(); - try { - for (final RpcDefinition rpcDef : module.getRpcs()) { - final Method method = findRpcMethod(key, rpcDef); - ret.put(method, rpcDef.getQName()); - } - } catch (final NoSuchMethodException e) { - throw new IllegalStateException("Rpc defined in model does not have representation in generated class.", e); - } - return ret.build(); + @Override + protected final Object handleInvocation(final Object proxy, final Method method, final Object[] args) + throws Throwable { + return method.isDefault() ? InvocationHandler.invokeDefault(proxy, method, args) + : doHandleInvocation(proxy, method, args); } - private Method findRpcMethod(final Class key, final RpcDefinition rpcDef) - throws NoSuchMethodException { - final String methodName = Naming.getRpcMethodName(rpcDef.getQName()); - final Class inputClz = adapter.getRuntimeContext().getRpcInput(rpcDef.getQName()); - return key.getMethod(methodName, inputClz); - } - - private Module getModule(final Class modeledClass) { - final QNameModule moduleName = BindingReflections.getQNameModule(modeledClass); - final BindingRuntimeContext localRuntimeContext = adapter.getRuntimeContext(); - final Module module = localRuntimeContext.getEffectiveModelContext().findModule(moduleName).orElse(null); - if (module != null) { - return module; - } - throw new IllegalStateException(String.format("Schema for %s is not available; expected module name: %s; " - + "full BindingRuntimeContext available in trace log", modeledClass, moduleName)); - } + abstract Object doHandleInvocation(Object proxy, Method method, Object[] args); } diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/ControllerRpcInvocationAdapter.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/ControllerRpcInvocationAdapter.java index 4c89e710..9d0cdaa0 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/ControllerRpcInvocationAdapter.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/ControllerRpcInvocationAdapter.java @@ -11,10 +11,9 @@ import java.util.Objects; import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext; import org.opendaylight.mdsal.dom.api.DOMSchemaService; -import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; -import org.opendaylight.yangtools.concepts.ObjectRegistration; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.Rpc; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; /** * Implementation of {@link RpcInvocationAdapter} used within ODL controller. @@ -44,17 +43,14 @@ public class ControllerRpcInvocationAdapter implements RpcInvocationAdapter { } @Override - public ObjectRegistration registerImpl(Class type, T impl) { - return new AbstractObjectRegistration<>(impl) { - @Override - protected void removeRegistration() { - // NOOP - } + public Registration registerImpl(Rpc impl) { + return () -> { + // NOOP }; } @Override - public SchemaContext schemaContext() { + public EffectiveModelContext schemaContext() { return schemaService.getGlobalContext(); } diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/EmbeddedRpcInvocationAdapter.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/EmbeddedRpcInvocationAdapter.java index 1441e713..1bc7b562 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/EmbeddedRpcInvocationAdapter.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/EmbeddedRpcInvocationAdapter.java @@ -15,8 +15,8 @@ import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext; import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers; import org.opendaylight.mdsal.dom.broker.DOMRpcRouter; import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService; -import org.opendaylight.yangtools.concepts.ObjectRegistration; -import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.Rpc; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; /** @@ -36,11 +36,11 @@ public final class EmbeddedRpcInvocationAdapter implements RpcInvocationAdapter private EmbeddedRpcInvocationAdapter() { final var runtimeContext = BindingRuntimeHelpers.createRuntimeContext(); codec = new BindingCodecContext(runtimeContext); - final var schemaService = FixedDOMSchemaService.of(runtimeContext.getEffectiveModelContext()); + final var schemaService = new FixedDOMSchemaService(runtimeContext.modelContext()); converter = new SchemaChangeAwareConverter(schemaService); rpcService = new DOMRpcRouter(schemaService); rpcAdapter = new BindingDOMRpcProviderServiceAdapter(new ConstantAdapterContext(codec), - rpcService.getRpcProviderService()); + rpcService.rpcProviderService()); } @Override @@ -54,13 +54,13 @@ public final class EmbeddedRpcInvocationAdapter implements RpcInvocationAdapter } @Override - public ObjectRegistration registerImpl(Class type, T impl) { - return rpcAdapter.registerRpcImplementation(type, impl); + public Registration registerImpl(Rpc impl) { + return rpcAdapter.registerRpcImplementation(impl); } @Override public EffectiveModelContext schemaContext() { - return getRuntimeContext().getEffectiveModelContext(); + return getRuntimeContext().modelContext(); } @Override diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/InboundHandler.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/InboundHandler.java index c797fe11..308f993b 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/InboundHandler.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/InboundHandler.java @@ -15,24 +15,19 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import java.io.IOException; import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Map.Entry; import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.Future; import org.opendaylight.jsonrpc.bus.jsonrpc.JsonRpcErrorObject; import org.opendaylight.jsonrpc.bus.jsonrpc.JsonRpcReplyMessage.Builder; import org.opendaylight.jsonrpc.bus.jsonrpc.JsonRpcRequestMessage; import org.opendaylight.jsonrpc.bus.messagelib.RequestMessageHandler; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ResponseErrorCode; -import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.binding.Rpc; +import org.opendaylight.yangtools.yang.binding.RpcInput; +import org.opendaylight.yangtools.yang.binding.RpcOutput; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,52 +39,45 @@ import org.slf4j.LoggerFactory; * @author Richard Kosegi * @since Sep 20, 2018 */ -public class InboundHandler extends AbstractHandler implements RequestMessageHandler { +public class InboundHandler> extends AbstractHandler implements RequestMessageHandler { private static final Logger LOG = LoggerFactory.getLogger(InboundHandler.class); - private final T impl; + private final Rpc impl; - public InboundHandler(Class type, RpcInvocationAdapter adapter, T impl) { - super(type, adapter); + public InboundHandler(RpcInvocationAdapter adapter, T impl) { + super((Class) impl.implementedInterface(), adapter); this.impl = Objects.requireNonNull(impl); } - private Optional> findMethod(String methodName) { - return rpcMethodMap.inverse() - .entrySet() - .stream() - .filter(e -> e.getKey().getQName().getLocalName().equals(methodName)) - .findFirst(); - } - @SuppressWarnings("checkstyle:IllegalCatch") @Override public void handleRequest(JsonRpcRequestMessage request, Builder replyBuilder) { + final var method = request.getMethod(); + if (!hasMethod(method)) { + logRpcInvocationFailure(new NoSuchMethodError(method)); + replyBuilder.error(new JsonRpcErrorObject(ResponseErrorCode.MethodNotFound.getIntValue(), + "No such method : " + method, JsonNull.INSTANCE)); + return; + } + try { - final Entry rpcDefEntry = findMethod(request.getMethod()) - .orElseThrow(() -> new NoSuchMethodError(request.getMethod())); - final Method method = rpcDefEntry.getValue(); - final Object[] args = convertArguments(rpcDefEntry, request.getParams(), method); + final var arg = convertArguments(request.getParams()); @SuppressWarnings("unchecked") - final Future> output = (Future>) method.invoke(impl, args); + final var output = ((Rpc) impl).invoke(arg); LOG.debug("Output : {}", output); - final RpcResult rpcResult = Futures.getUnchecked(output); + final var rpcResult = Futures.getUnchecked(output); if (rpcResult.isSuccessful()) { - if (rpcResult.getResult() != null) { - final ContainerNode domData = adapter.codec() - .toNormalizedNodeRpcData((DataContainer) rpcResult.getResult()); + final var result = rpcResult.getResult(); + if (result != null) { + final ContainerNode domData = adapter.codec().toNormalizedNodeRpcData(result); final JsonElement reply = adapter.converter() .get() - .rpcOutputCodec(rpcDefEntry.getKey()) + .rpcOutputCodec(rpcDef) .serialize(domData); replyBuilder.result(reply); } } else { mapRpcError(replyBuilder, rpcResult); } - } catch (NoSuchMethodError e) { - logRpcInvocationFailure(e); - replyBuilder.error(new JsonRpcErrorObject(ResponseErrorCode.MethodNotFound.getIntValue(), - "No such method : " + e.getMessage(), JsonNull.INSTANCE)); } catch (IllegalArgumentException e) { logRpcInvocationFailure(e); replyBuilder.error(new JsonRpcErrorObject(ResponseErrorCode.InvalidParams.getIntValue(), e.getMessage(), @@ -102,8 +90,8 @@ public class InboundHandler extends AbstractHandler imp } } - private static void mapRpcError(Builder replyBuilder, final RpcResult rpcResult) { - final Collection errors = rpcResult.getErrors(); + private static void mapRpcError(Builder replyBuilder, final RpcResult rpcResult) { + final var errors = rpcResult.getErrors(); if (errors.isEmpty()) { replyBuilder.error(new JsonRpcErrorObject(new JsonPrimitive("No error info available"))); } else if (errors.size() == 1) { @@ -116,24 +104,15 @@ public class InboundHandler extends AbstractHandler imp } } - private Object[] convertArguments(final Entry rpcDefEntry, final JsonElement wrapper, - final Method method) throws IOException { - final Object[] args; - if (method.getParameterCount() == 1) { - final NormalizedNode nn = adapter.converter() - .get() - .rpcInputCodec(rpcDefEntry.getKey()) - .deserialize(wrapper); - final DataObject dataObject = adapter.codec() - .fromNormalizedNodeRpcData( - Absolute.of(rpcDefEntry.getKey().getQName(), rpcDefEntry.getKey().getInput().getQName()), - (ContainerNode) nn); - LOG.debug("Input : {}", dataObject); - args = new Object[] { dataObject }; - } else { - args = null; - } - return args; + private RpcInput convertArguments(final JsonElement wrapper) throws IOException { + final ContainerNode nn = adapter.converter() + .get() + .rpcInputCodec(rpcDef) + .deserialize(wrapper); + final DataObject dataObject = adapter.codec() + .fromNormalizedNodeRpcData(Absolute.of(rpcDef.getQName(), rpcDef.getInput().getQName()), nn); + LOG.debug("Input : {}", dataObject); + return RpcInput.class.cast(dataObject); } private static void logRpcInvocationFailure(Throwable cause) { @@ -151,7 +130,7 @@ public class InboundHandler extends AbstractHandler imp } @Override - protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable { + protected Object doHandleInvocation(Object proxy, Method method, Object[] args) { // NOOP, not used return null; } @@ -160,6 +139,6 @@ public class InboundHandler extends AbstractHandler imp * Used by MultiModelRequestDispatcher */ boolean hasMethod(String methodName) { - return findMethod(methodName).isPresent(); + return rpcDef.getQName().getLocalName().equals(methodName); } } diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelBuilder.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelBuilder.java index 06bb6055..cb4c38a1 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelBuilder.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelBuilder.java @@ -11,7 +11,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ClassToInstanceMap; import com.google.common.collect.ImmutableClassToInstanceMap; import com.google.common.collect.MutableClassToInstanceMap; -import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.binding.Rpc; /** * Builder for convenient way to define multiple RpcService implementations. @@ -20,7 +20,7 @@ import org.opendaylight.yangtools.yang.binding.RpcService; * @since Oct 16, 2018 */ public final class MultiModelBuilder { - private final ClassToInstanceMap services = MutableClassToInstanceMap.create(); + private final ClassToInstanceMap> services = MutableClassToInstanceMap.create(); private MultiModelBuilder() { // no direct instantiation @@ -30,12 +30,12 @@ public final class MultiModelBuilder { return new MultiModelBuilder(); } - public MultiModelBuilder addService(Class type, T impl) { - services.put(type, impl); + public MultiModelBuilder addService(Rpc impl) { + services.put(impl.implementedInterface(), impl); return this; } - public ClassToInstanceMap build() { + public ClassToInstanceMap> build() { Preconditions.checkState(!services.isEmpty(), "No services defined"); return ImmutableClassToInstanceMap.copyOf(services); } diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelProxy.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelProxy.java index c5c924c0..5882a069 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelProxy.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelProxy.java @@ -7,12 +7,11 @@ */ package org.opendaylight.jsonrpc.binding; -import com.google.common.collect.ClassToInstanceMap; import com.google.common.collect.ImmutableClassToInstanceMap; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.binding.Rpc; /** * Proxy context for remote RPC service which implements multiple yang models. @@ -21,13 +20,13 @@ import org.opendaylight.yangtools.yang.binding.RpcService; * @since Oct 16, 2018 */ public class MultiModelProxy implements AutoCloseable { - private final ClassToInstanceMap proxyMap; - private final Set> proxies; + private final ImmutableClassToInstanceMap> proxyMap; + private final Set> proxies; - public MultiModelProxy(Set> proxies) { + public MultiModelProxy(Set> proxies) { this.proxies = proxies; - proxyMap = ImmutableClassToInstanceMap - .copyOf(proxies.stream().collect(Collectors.toMap(ProxyContext::getType, ProxyContext::getProxy))); + proxyMap = ImmutableClassToInstanceMap.copyOf(proxies.stream() + .collect(Collectors.toMap(ProxyContext::getType, ProxyContext::getProxy))); } @Override @@ -36,14 +35,13 @@ public class MultiModelProxy implements AutoCloseable { } /** - * Get RPC proxy for particular {@link RpcService}. + * Get RPC proxy for particular {@link Rpc}. * - * @param type subtype of {@link RpcService} to get proxy for + * @param type subtype of {@link Rpc} to get proxy for * @return proxy for given RpcService subtype */ - @SuppressWarnings("unchecked") - public T getRpcService(Class type) { - return (T) Objects.requireNonNull(proxyMap.get(type), - "Service is not supported by this requester instance : " + type); + public > T getRpcService(Class type) { + return Objects.requireNonNull(proxyMap.getInstance(type), + "Service is not supported by this requester instance : " + type); } } diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelRequestDispatcher.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelRequestDispatcher.java index 7f73535a..dc55d65f 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelRequestDispatcher.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/MultiModelRequestDispatcher.java @@ -7,13 +7,11 @@ */ package org.opendaylight.jsonrpc.binding; -import java.util.Optional; import java.util.Set; import org.opendaylight.jsonrpc.bus.jsonrpc.JsonRpcErrorObject; import org.opendaylight.jsonrpc.bus.jsonrpc.JsonRpcReplyMessage.Builder; import org.opendaylight.jsonrpc.bus.jsonrpc.JsonRpcRequestMessage; import org.opendaylight.jsonrpc.bus.messagelib.RequestMessageHandler; -import org.opendaylight.yangtools.yang.binding.RpcService; /** * {@link RequestMessageHandler} which dispatch incoming RPC request to correct implementation. @@ -22,15 +20,15 @@ import org.opendaylight.yangtools.yang.binding.RpcService; * @since Oct 16, 2018 */ public class MultiModelRequestDispatcher implements RequestMessageHandler { - private final Set> handlers; + private final Set> handlers; - MultiModelRequestDispatcher(Set> handlers) { + MultiModelRequestDispatcher(Set> handlers) { this.handlers = handlers; } @Override public void handleRequest(JsonRpcRequestMessage request, Builder replyBuilder) { - final Optional> handler = handlers.stream() + final var handler = handlers.stream() .filter(h -> h.hasMethod(request.getMethod())) .findFirst(); if (handler.isPresent()) { diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/OutboundHandler.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/OutboundHandler.java index 4dc0805a..c562eb54 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/OutboundHandler.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/OutboundHandler.java @@ -14,17 +14,15 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; -import java.util.Objects; import org.opendaylight.jsonrpc.bus.jsonrpc.JsonRpcReplyMessage; import org.opendaylight.jsonrpc.bus.messagelib.RequesterSession; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.binding.Rpc; import org.opendaylight.yangtools.yang.common.ErrorType; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,8 +33,9 @@ import org.slf4j.LoggerFactory; * @author Richard Kosegi * @since Sep 20, 2018 */ -public class OutboundHandler extends AbstractHandler { +public class OutboundHandler> extends AbstractHandler { private static final Logger LOG = LoggerFactory.getLogger(OutboundHandler.class); + private final RequesterSession session; public OutboundHandler(Class type, RpcInvocationAdapter adapter, RequesterSession session) { @@ -47,7 +46,7 @@ public class OutboundHandler extends AbstractHandler { @SuppressWarnings("checkstyle:IllegalCatch") @SuppressFBWarnings("DCN_NULLPOINTER_EXCEPTION") @Override - protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable { + Object doHandleInvocation(Object proxy, Method method, Object[] args) { try { return handleInvocationInternal(method, args); } catch (NullPointerException | IllegalArgumentException e) { @@ -62,8 +61,6 @@ public class OutboundHandler extends AbstractHandler { private Object handleInvocationInternal(Method method, Object[] args) throws IOException { Preconditions.checkArgument(args.length < 2, "Unexpected number of arguments : %d", args.length); - RpcDefinition rpcDef = rpcMethodMap.get(method); - Objects.requireNonNull(rpcDef); final JsonElement request; // RPC with input if (args.length == 1) { diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/ProxyContext.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/ProxyContext.java index 41703c11..11fd5fc0 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/ProxyContext.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/ProxyContext.java @@ -9,8 +9,8 @@ package org.opendaylight.jsonrpc.binding; import java.util.function.Consumer; import org.opendaylight.jsonrpc.bus.messagelib.BaseSession; -import org.opendaylight.yangtools.concepts.ObjectRegistration; -import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.Rpc; /** * Context of proxy. Allows proper cleanup of created instance. @@ -18,15 +18,15 @@ import org.opendaylight.yangtools.yang.binding.RpcService; * @author Richard Kosegi * @since Sep 21, 2018 */ -public class ProxyContext implements AutoCloseable { - private final ObjectRegistration rpcRegistration; +public class ProxyContext> implements AutoCloseable { + private final Registration rpcRegistration; private final BaseSession session; private final T proxy; private final Consumer cleanCallback; private final Class type; - ProxyContext(final Class type, final ObjectRegistration rpcRegistration, final BaseSession session, - final T proxy, final Consumer cleanCallback) { + ProxyContext(final Class type, final Registration rpcRegistration, final BaseSession session, final T proxy, + final Consumer cleanCallback) { this.rpcRegistration = rpcRegistration; this.session = session; this.proxy = proxy; diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/RpcInvocationAdapter.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/RpcInvocationAdapter.java index 05c76f5c..0ffaa90d 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/RpcInvocationAdapter.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/RpcInvocationAdapter.java @@ -9,18 +9,18 @@ package org.opendaylight.jsonrpc.binding; import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext; -import org.opendaylight.yangtools.concepts.ObjectRegistration; -import org.opendaylight.yangtools.yang.binding.RpcService; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.Rpc; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; public interface RpcInvocationAdapter { SchemaChangeAwareConverter converter(); BindingNormalizedNodeSerializer codec(); - ObjectRegistration registerImpl(Class type, T impl); + Registration registerImpl(Rpc impl); - SchemaContext schemaContext(); + EffectiveModelContext schemaContext(); BindingRuntimeContext getRuntimeContext(); } diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/SchemaAwareTransportFactory.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/SchemaAwareTransportFactory.java index 257cfb30..8e50f552 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/SchemaAwareTransportFactory.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/SchemaAwareTransportFactory.java @@ -12,10 +12,10 @@ import com.google.common.reflect.Reflection; import java.net.URI; import java.net.URISyntaxException; import java.util.HashSet; -import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.stream.Collectors; import org.opendaylight.jsonrpc.bus.api.BusSessionFactoryProvider; import org.opendaylight.jsonrpc.bus.messagelib.AbstractTransportFactory; @@ -25,8 +25,8 @@ import org.opendaylight.jsonrpc.bus.messagelib.ResponderSession; import org.opendaylight.jsonrpc.bus.messagelib.TransportFactory; import org.opendaylight.jsonrpc.bus.spi.EventLoopConfiguration; import org.opendaylight.jsonrpc.bus.spi.EventLoopGroupProvider; -import org.opendaylight.yangtools.concepts.ObjectRegistration; -import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.Rpc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +38,8 @@ import org.slf4j.LoggerFactory; */ public final class SchemaAwareTransportFactory extends AbstractTransportFactory { private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareTransportFactory.class); - private final Map> proxyMap = new ConcurrentHashMap<>(); + + private final ConcurrentMap> proxyMap = new ConcurrentHashMap<>(); private final RpcInvocationAdapter invocationAdapter; /** @@ -95,18 +96,18 @@ public final class SchemaAwareTransportFactory extends AbstractTransportFactory /** * Create requester session against remote endpoint by creating proxy of given type. * - * @param type Type of {@link RpcService} to create proxy for + * @param type Type of {@link Rpc} to create proxy for * @param uri remote endpoint URI - * @return proxy for {@link RpcService}. + * @return proxy for {@link Rpc}. * @throws URISyntaxException if provided URI is invalid */ - public ProxyContext createBindingRequesterProxy(Class type, String uri) + public > ProxyContext createBindingRequesterProxy(Class type, String uri) throws URISyntaxException { LOG.info("Creating requester proxy for type {} against endpoint '{}'", type.getName(), uri); final RequesterSession requester = createRequester(uri, NoopReplyMessageHandler.INSTANCE); final OutboundHandler handler = new OutboundHandler<>(type, invocationAdapter, requester); final T proxy = Reflection.newProxy(type, handler); - final ObjectRegistration rpcReg = invocationAdapter.registerImpl(type, proxy); + final Registration rpcReg = invocationAdapter.registerImpl(proxy); final ProxyContext context = new ProxyContext<>(type, rpcReg, requester, proxy, this::closeProxy); proxyMap.put(proxy, context); return context; @@ -115,17 +116,16 @@ public final class SchemaAwareTransportFactory extends AbstractTransportFactory /** * Create binding-aware requester proxy against remote responder endpoint implementing multiple service models. * - * @param services set of {@link RpcService} implemented by remote service + * @param services set of {@link Rpc}s implemented by remote service * @param uri remote responder endpoint * @return {@link MultiModelProxy} used to get actual RPC proxy and close requester once it is no longer needed * @throws URISyntaxException if provided responder URI is invalid */ - @SuppressWarnings("unchecked") - public MultiModelProxy createMultiModelRequesterProxy(Set> services, String uri) + public MultiModelProxy createMultiModelRequesterProxy(Set>> services, String uri) throws URISyntaxException { - final Set> proxies = new HashSet<>(); - for (final Class service : services) { - proxies.add((ProxyContext) createBindingRequesterProxy(service, uri)); + final var proxies = new HashSet>(); + for (var service : services) { + proxies.add(createBindingRequesterProxy(service, uri)); } return new MultiModelProxy(proxies); } @@ -136,7 +136,7 @@ public final class SchemaAwareTransportFactory extends AbstractTransportFactory * @param proxy proxy instance to close. */ private void closeProxy(Object proxy) { - final ProxyContext context = proxyMap.remove(proxy); + final var context = proxyMap.remove(proxy); if (context != null) { context.closeInternal(); } @@ -145,31 +145,28 @@ public final class SchemaAwareTransportFactory extends AbstractTransportFactory /** * Create responder bound to local socket provided in URI. * - * @param type actual {@link RpcService} type - * @param rpcImpl {@link RpcService} implementation + * @param rpcImpl {@link Rpc} implementation * @param bindUri URI to bind to * @return {@link ResponderSession} * @throws URISyntaxException if provided URI is invalid */ - public ResponderSession createResponder(Class type, T rpcImpl, String bindUri) + public ResponderSession createResponder(Rpc rpcImpl, String bindUri) throws URISyntaxException { - LOG.info("Creating responder type {} exposed on '{}'", type.getName(), bindUri); + LOG.info("Creating responder type {} exposed on '{}'", rpcImpl.implementedInterface().getName(), bindUri); final URI uri = new URI(bindUri); return getMessageLibraryForTransport(uri.getScheme()).responder(bindUri, - new InboundHandler<>(type, invocationAdapter, rpcImpl), false); + new InboundHandler<>(invocationAdapter, rpcImpl), false); } - @SuppressWarnings("unchecked") public ResponderSession createMultiModelResponder(MultiModelBuilder builder, String bindUri) throws URISyntaxException { - final ClassToInstanceMap services = builder.build(); + final ClassToInstanceMap> services = builder.build(); LOG.info("Creating multi-model responder for services {} exposed on '{}'", services.keySet(), bindUri); final URI uri = new URI(bindUri); - final Set> handlers = services.entrySet() - .stream() - .map(e -> new InboundHandler<>((Class) e.getKey(), invocationAdapter, e.getValue())) + final Set> handlers = services.values().stream() + .map(impl -> new InboundHandler<>(invocationAdapter, impl)) .collect(Collectors.toSet()); return getMessageLibraryForTransport(uri.getScheme()).responder(bindUri, diff --git a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/SchemaChangeAwareConverter.java b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/SchemaChangeAwareConverter.java index 31add569..212d1c61 100644 --- a/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/SchemaChangeAwareConverter.java +++ b/binding-adapter/src/main/java/org/opendaylight/jsonrpc/binding/SchemaChangeAwareConverter.java @@ -15,7 +15,6 @@ import org.opendaylight.jsonrpc.dom.codec.JsonRpcCodecFactory; import org.opendaylight.mdsal.dom.api.DOMSchemaService; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; -import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextListener; import org.opendaylight.yangtools.yang.model.api.SchemaContext; /** @@ -25,13 +24,13 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; * @since Aug 25, 2018 */ public final class SchemaChangeAwareConverter - implements Supplier, AutoCloseable, EffectiveModelContextListener { + implements Supplier, AutoCloseable { private final AtomicReference converter = new AtomicReference<>(null); private Registration registration; public SchemaChangeAwareConverter(@NonNull DOMSchemaService domSchemaService) { Objects.requireNonNull(domSchemaService); - this.registration = domSchemaService.registerSchemaContextListener(this); + this.registration = domSchemaService.registerSchemaContextListener(this::onModelContextUpdated); refresh(domSchemaService.getGlobalContext()); } @@ -49,7 +48,6 @@ public final class SchemaChangeAwareConverter return converter.get(); } - @Override public void onModelContextUpdated(EffectiveModelContext newModelContext) { refresh(newModelContext); } diff --git a/binding-adapter/src/test/java/org/opendaylight/jsonrpc/binding/TestModelServiceTest.java b/binding-adapter/src/test/java/org/opendaylight/jsonrpc/binding/TestModelServiceTest.java index 7e7e7588..c2a9baed 100644 --- a/binding-adapter/src/test/java/org/opendaylight/jsonrpc/binding/TestModelServiceTest.java +++ b/binding-adapter/src/test/java/org/opendaylight/jsonrpc/binding/TestModelServiceTest.java @@ -11,9 +11,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Collection; import java.util.UUID; -import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; @@ -23,23 +21,26 @@ import org.opendaylight.jsonrpc.bus.messagelib.NoopReplyMessageHandler; import org.opendaylight.jsonrpc.bus.messagelib.RequesterSession; import org.opendaylight.jsonrpc.bus.messagelib.ResponderSession; import org.opendaylight.jsonrpc.bus.messagelib.TestHelper; -import org.opendaylight.jsonrpc.test.TestModelServiceImpl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.base.rev201014.numbers.list.Numbers; +import org.opendaylight.jsonrpc.test.TestErrorMethod; +import org.opendaylight.jsonrpc.test.TestFactorial; +import org.opendaylight.jsonrpc.test.TestMultiplyList; +import org.opendaylight.jsonrpc.test.TestRemoveCoffeePot; +import org.opendaylight.jsonrpc.test.TestSimpleMethod; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.base.rev201014.numbers.list.NumbersBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.Coffee; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.ErrorMethod; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.ErrorMethodInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.ErrorMethodOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.Factorial; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.FactorialInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.FactorialOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyList; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyListInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePot; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePotInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePotOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.SimpleMethod; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.SimpleMethodInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.TestModelRpcService; import org.opendaylight.yangtools.yang.binding.util.BindingMap; import org.opendaylight.yangtools.yang.common.ErrorSeverity; import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.Uint16; /** @@ -51,18 +52,22 @@ import org.opendaylight.yangtools.yang.common.Uint16; public class TestModelServiceTest { private SchemaAwareTransportFactory transportFactory; private ResponderSession responder; - private ProxyContext proxy; private RequesterSession requester; + private String connectUri; @Before public void setUp() throws Exception { transportFactory = new SchemaAwareTransportFactory.Builder() .withRpcInvocationAdapter(EmbeddedRpcInvocationAdapter.INSTANCE).build(); final int port = TestHelper.getFreeTcpPort(); - responder = transportFactory.createResponder(TestModelRpcService.class, new TestModelServiceImpl(), - TestHelper.getBindUri("ws", port)); - proxy = transportFactory.createBindingRequesterProxy(TestModelRpcService.class, - TestHelper.getConnectUri("ws", port)); + connectUri = TestHelper.getConnectUri("ws", port); + responder = transportFactory.createMultiModelResponder(MultiModelBuilder.create() + .addService(new TestErrorMethod()) + .addService(new TestFactorial()) + .addService(new TestMultiplyList()) + .addService(new TestRemoveCoffeePot()) + .addService(new TestSimpleMethod()), TestHelper.getBindUri("ws", port)); + requester = transportFactory.endpointBuilder().requester().create(TestHelper.getConnectUri("ws", port), NoopReplyMessageHandler.INSTANCE); TimeUnit.MILLISECONDS.sleep(150); @@ -71,37 +76,37 @@ public class TestModelServiceTest { @After public void tearDown() { responder.close(); - proxy.close(); transportFactory.close(); } @Test public void testFactorial() throws Exception { - final Future> result = proxy.getProxy() - .factorial(new FactorialInputBuilder().setInNumber(Uint16.valueOf(6)).build()); + final var proxy = transportFactory.createBindingRequesterProxy(Factorial.class, connectUri); + final var result = proxy.getProxy().invoke(new FactorialInputBuilder().setInNumber(Uint16.valueOf(6)).build()); assertEquals(720L, result.get().getResult().getOutNumber().longValue()); } @Test public void testMultiplyList() throws Exception { - final Collection resp = proxy.getProxy() - .multiplyList(new MultiplyListInputBuilder().setMultiplier((short) 10) - .setNumbers(BindingMap.ordered( - new NumbersBuilder().setNum(10).build(), - new NumbersBuilder().setNum(20).build())) - .build()) - .get() - .getResult() - .getNumbers().values(); + final var proxy = transportFactory.createBindingRequesterProxy(MultiplyList.class, connectUri); + final var resp = proxy.getProxy().invoke(new MultiplyListInputBuilder() + .setMultiplier((short) 10) + .setNumbers(BindingMap.ordered( + new NumbersBuilder().setNum(10).build(), + new NumbersBuilder().setNum(20).build())) + .build()) + .get() + .getResult() + .getNumbers() + .values(); assertEquals(2, resp.size()); } @Test public void testErrorMethod() throws Exception { - final RpcResult result = proxy.getProxy() - .errorMethod(new ErrorMethodInputBuilder().build()) - .get(); + final var proxy = transportFactory.createBindingRequesterProxy(ErrorMethod.class, connectUri); + final var result = proxy.getProxy().invoke(new ErrorMethodInputBuilder().build()).get(); assertFalse(result.isSuccessful()); final RpcError err = result.getErrors().iterator().next(); assertEquals("Ha!", err.getMessage()); @@ -110,7 +115,8 @@ public class TestModelServiceTest { @Test public void testSimpleMethod() throws Exception { - assertTrue(proxy.getProxy().simpleMethod(new SimpleMethodInputBuilder().build()).get().isSuccessful()); + final var proxy = transportFactory.createBindingRequesterProxy(SimpleMethod.class, connectUri); + assertTrue(proxy.getProxy().invoke(new SimpleMethodInputBuilder().build()).get().isSuccessful()); } @Test @@ -121,8 +127,8 @@ public class TestModelServiceTest { @Test public void testRemoveCoffeePot() throws Exception { - RemoveCoffeePotOutput result = proxy.getProxy() - .removeCoffeePot(new RemoveCoffeePotInputBuilder().build()) + final var proxy = transportFactory.createBindingRequesterProxy(RemoveCoffeePot.class, connectUri); + final var result = proxy.getProxy().invoke(new RemoveCoffeePotInputBuilder().build()) .get() .getResult(); assertEquals(6, result.getCupsBrewed().longValue()); diff --git a/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/AbstractCodec.java b/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/AbstractCodec.java index 7fd51cf8..0ec49477 100644 --- a/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/AbstractCodec.java +++ b/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/AbstractCodec.java @@ -23,8 +23,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.builder.NormalizedNodeCon import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory; import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier; -import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.Module; @@ -37,7 +37,7 @@ abstract class AbstractCodec { } protected static DataContainerNodeBuilder createNodeBuilder(QName qname) { - return Builders.containerBuilder().withNodeIdentifier(NodeIdentifier.create(qname)); + return ImmutableNodes.newContainerBuilder().withNodeIdentifier(NodeIdentifier.create(qname)); } protected static NormalizedNodeStreamWriter createWriter(NormalizedNodeContainerBuilder builder) { diff --git a/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/DataCodec.java b/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/DataCodec.java index dcf9bbb5..2c10457f 100644 --- a/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/DataCodec.java +++ b/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/DataCodec.java @@ -7,8 +7,6 @@ */ package org.opendaylight.jsonrpc.dom.codec; -import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder; - import com.google.common.collect.Iterables; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -20,6 +18,7 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; @@ -33,6 +32,7 @@ import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream; import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.schema.NormalizationResultHolder; +import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes; import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.Module; @@ -187,9 +187,10 @@ class DataCodec extends AbstractCodec implements Codec dataCodec(@NonNull YangInstanceIdentifier path) { Objects.requireNonNull(path); - if (YangInstanceIdentifier.empty().equals(path)) { + if (path.isEmpty()) { throw new IllegalArgumentException("Empty path is not supported by data codec"); } return dataCodecCache.getUnchecked(path); diff --git a/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/NotificationCodec.java b/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/NotificationCodec.java index 6911a7d7..c5979fcf 100644 --- a/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/NotificationCodec.java +++ b/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/NotificationCodec.java @@ -20,7 +20,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream; -import org.opendaylight.yangtools.yang.data.impl.schema.Builders; +import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; @@ -82,7 +82,7 @@ class NotificationCodec extends RpcNotificationBaseCodec { } JsonRpcNotification(final Absolute schemaPath) { - this(Builders.containerBuilder().build(), schemaPath); + this(ImmutableNodes.newContainerBuilder().build(), schemaPath); } JsonRpcNotification(final ContainerNode content, final Absolute schemaPath) { diff --git a/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/RpcCodec.java b/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/RpcCodec.java index e3b455bd..3d100da3 100644 --- a/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/RpcCodec.java +++ b/dom-codec/src/main/java/org/opendaylight/jsonrpc/dom/codec/RpcCodec.java @@ -14,10 +14,9 @@ import java.util.function.Supplier; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream; -import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes; import org.opendaylight.yangtools.yang.model.api.ContainerLike; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; @@ -51,7 +50,9 @@ class RpcCodec extends RpcNotificationBaseCodec { LOG.trace("[decode][{}][{}] input : {}", shortName, type, input); final ContainerNode result; if (isEmpty || input == null || input.isJsonNull()) { - result = ImmutableNodes.containerNode(path.lastNodeIdentifier()); + result = ImmutableNodes.newContainerBuilder() + .withNodeIdentifier(new NodeIdentifier(path.lastNodeIdentifier())) + .build(); } else { result = decode(wrapInputIfNecessary(input)); } @@ -60,8 +61,7 @@ class RpcCodec extends RpcNotificationBaseCodec { } private ContainerNode decode(JsonElement input) throws IOException { - final DataContainerNodeBuilder builder = createNodeBuilder( - path.lastNodeIdentifier()); + final var builder = createNodeBuilder(path.lastNodeIdentifier()); try (NormalizedNodeStreamWriter writer = createWriter(builder); JsonParserStream jsonParser = JsonParserStream.create(writer, jsonCodec(), SchemaInferenceStack.of(context, path).toInference())) { diff --git a/dom-codec/src/test/java/org/opendaylight/jsonrpc/dom/codec/AbstractCodecTest.java b/dom-codec/src/test/java/org/opendaylight/jsonrpc/dom/codec/AbstractCodecTest.java index 52879de5..884c4d03 100644 --- a/dom-codec/src/test/java/org/opendaylight/jsonrpc/dom/codec/AbstractCodecTest.java +++ b/dom-codec/src/test/java/org/opendaylight/jsonrpc/dom/codec/AbstractCodecTest.java @@ -114,10 +114,10 @@ public abstract class AbstractCodecTest extends AbstractDataBrokerTest { sw.write(Strings.repeat(" ", (level - 1) * 2)); sw.write(nn.body().getClass().getSimpleName()); sw.write(" : "); - sw.write(nn.getIdentifier().toString()); + sw.write(nn.name().toString()); sw.write("\n"); - if (nn.body() instanceof Collection) { - for (Object e : (Collection) nn.body()) { + if (nn.body() instanceof Collection coll) { + for (Object e : coll) { dumpNormalizedNode((NormalizedNode) e, sw, level + 1); } } diff --git a/dom-codec/src/test/java/org/opendaylight/jsonrpc/dom/codec/DataCodecTest.java b/dom-codec/src/test/java/org/opendaylight/jsonrpc/dom/codec/DataCodecTest.java index 949c7c94..ab3ddb1d 100644 --- a/dom-codec/src/test/java/org/opendaylight/jsonrpc/dom/codec/DataCodecTest.java +++ b/dom-codec/src/test/java/org/opendaylight/jsonrpc/dom/codec/DataCodecTest.java @@ -13,6 +13,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import com.google.gson.JsonElement; import com.google.gson.JsonNull; @@ -24,9 +25,9 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; public class DataCodecTest extends AbstractCodecTest { - @Test(expected = IllegalArgumentException.class) + @Test public void testEmptyPath() { - factory.dataCodec(YangInstanceIdentifier.empty()); + assertThrows(IllegalArgumentException.class, () -> factory.dataCodec(YangInstanceIdentifier.of())); } @Test diff --git a/features/odl-jsonrpc-all/src/main/feature/feature.xml b/features/odl-jsonrpc-all/src/main/feature/feature.xml index 8a4d9686..4c44897f 100644 --- a/features/odl-jsonrpc-all/src/main/feature/feature.xml +++ b/features/odl-jsonrpc-all/src/main/feature/feature.xml @@ -8,7 +8,7 @@ --> - odl-restconf-openapi + odl-restconf-openapi diff --git a/features/odl-jsonrpc-bus/src/main/feature/feature.xml b/features/odl-jsonrpc-bus/src/main/feature/feature.xml index 2e5d6952..2e19da91 100644 --- a/features/odl-jsonrpc-bus/src/main/feature/feature.xml +++ b/features/odl-jsonrpc-bus/src/main/feature/feature.xml @@ -12,8 +12,8 @@ mvn:org.opendaylight.jsonrpc.bus/bus-config/${project.version}/cfg/config odl-netty-4 - odl-mdsal-model-rfc6991 - odl-aaa-shiro + odl-mdsal-model-rfc6991 + odl-aaa-shiro diff --git a/features/odl-jsonrpc-cluster/src/main/feature/feature.xml b/features/odl-jsonrpc-cluster/src/main/feature/feature.xml index 0bb09c5d..5be4e1a5 100644 --- a/features/odl-jsonrpc-cluster/src/main/feature/feature.xml +++ b/features/odl-jsonrpc-cluster/src/main/feature/feature.xml @@ -8,8 +8,8 @@ --> - odl-mdsal-binding-dom-adapter - odl-restconf-openapi + odl-mdsal-binding-dom-adapter + odl-restconf-openapi diff --git a/features/odl-jsonrpc-provider/src/main/feature/feature.xml b/features/odl-jsonrpc-provider/src/main/feature/feature.xml index f5ac4902..5162d5c1 100644 --- a/features/odl-jsonrpc-provider/src/main/feature/feature.xml +++ b/features/odl-jsonrpc-provider/src/main/feature/feature.xml @@ -8,7 +8,7 @@ --> - odl-mdsal-binding-dom-adapter + odl-mdsal-binding-dom-adapter diff --git a/parent/pom.xml b/parent/pom.xml index a184cddb..2740c10a 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -11,7 +11,7 @@ org.opendaylight.mdsal binding-parent - 12.0.4 + 13.0.0 @@ -34,14 +34,14 @@ org.opendaylight.netconf netconf-artifacts - 6.0.6 + 7.0.0 pom import org.opendaylight.aaa aaa-artifacts - 0.18.4 + 0.19.1 pom import diff --git a/provider/cluster/pom.xml b/provider/cluster/pom.xml index 8ca43262..3c807bfc 100644 --- a/provider/cluster/pom.xml +++ b/provider/cluster/pom.xml @@ -25,13 +25,18 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.controller bundle-parent - 8.0.4 + 9.0.0 pom import + + com.github.spotbugs + spotbugs-annotations + true + io.netty netty-transport @@ -85,7 +90,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.mdsal - mdsal-singleton-common-api + mdsal-singleton-api org.opendaylight.jsonrpc.bus @@ -204,7 +209,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.mdsal - mdsal-singleton-dom-impl + mdsal-singleton-impl test diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ClusterDependencies.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ClusterDependencies.java index 6f60fe39..13c1397d 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ClusterDependencies.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ClusterDependencies.java @@ -15,12 +15,13 @@ import org.opendaylight.jsonrpc.bus.messagelib.TransportFactory; import org.opendaylight.jsonrpc.model.GovernanceProvider; import org.opendaylight.jsonrpc.provider.common.ProviderDependencies; import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.mdsal.dom.api.DOMSchemaService; -import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; +import org.opendaylight.mdsal.singleton.api.ClusterSingletonServiceProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.cluster.provider.config.rev200708.Config; import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; @@ -34,6 +35,7 @@ public class ClusterDependencies extends ProviderDependencies { private final ActorSystem actorSystem; private final ClusterSingletonServiceProvider clusterSingletonServiceProvider; private final GovernanceProvider governanceProvider; + private final RpcProviderService rpcProviderService; private final Config config; public ClusterDependencies(@NonNull TransportFactory transportFactory, @NonNull DataBroker dataBroker, @@ -42,12 +44,14 @@ public class ClusterDependencies extends ProviderDependencies { @NonNull DOMNotificationPublishService domNotificationPublishService, @NonNull DOMRpcService domRpcService, @NonNull YangXPathParserFactory yangXPathParserFactory, @NonNull ActorSystem actorSystem, @NonNull ClusterSingletonServiceProvider clusterSingletonServiceProvider, - @NonNull GovernanceProvider governanceProvider, @Nullable Config config) { + @NonNull GovernanceProvider governanceProvider, @NonNull RpcProviderService rpcProviderService, + @Nullable Config config) { super(transportFactory, dataBroker, domMountPointService, domDataBroker, schemaService, domNotificationPublishService, domRpcService, yangXPathParserFactory); this.actorSystem = Objects.requireNonNull(actorSystem); this.clusterSingletonServiceProvider = Objects.requireNonNull(clusterSingletonServiceProvider); this.governanceProvider = Objects.requireNonNull(governanceProvider); + this.rpcProviderService = Objects.requireNonNull(rpcProviderService); this.config = config; } @@ -55,6 +59,10 @@ public class ClusterDependencies extends ProviderDependencies { return actorSystem; } + public RpcProviderService getRpcProviderService() { + return rpcProviderService; + } + public ClusterSingletonServiceProvider getClusterSingletonServiceProvider() { return clusterSingletonServiceProvider; } diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ClusterUtil.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ClusterUtil.java index 1c28d9ca..0f90dc02 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ClusterUtil.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ClusterUtil.java @@ -19,8 +19,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.config.Ac import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.config.ConfiguredEndpoints; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.config.ConfiguredEndpointsKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.binding.KeyStep; import org.opendaylight.yangtools.yang.common.Uint16; import scala.concurrent.duration.Duration; import scala.concurrent.duration.FiniteDuration; @@ -47,7 +46,7 @@ final class ClusterUtil { * @return {@link DataTreeIdentifier} */ public static DataTreeIdentifier getPeerOpstateIdentifier(String name) { - return DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, + return DataTreeIdentifier.of(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(Config.class) .child(ActualEndpoints.class, new ActualEndpointsKey(name)) .build()); @@ -59,7 +58,7 @@ final class ClusterUtil { * @return {@link DataTreeIdentifier} */ public static DataTreeIdentifier getPeerListIdentifier() { - return DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, + return DataTreeIdentifier.of(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Config.class).child(ConfiguredEndpoints.class).build()); } @@ -70,13 +69,13 @@ final class ClusterUtil { * @return peer's name */ public static String peerNameFromII(InstanceIdentifier ii) { - final PathArgument last = Iterables.getLast(ii.getPathArguments()); - Preconditions.checkArgument(last instanceof IdentifiableItem); - if (((IdentifiableItem) last).getKey() instanceof ConfiguredEndpointsKey) { - return ((ConfiguredEndpointsKey) ((IdentifiableItem) last).getKey()).getName(); + final var last = Iterables.getLast(ii.getPathArguments()); + Preconditions.checkArgument(last instanceof KeyStep); + if (((KeyStep) last).key() instanceof ConfiguredEndpointsKey) { + return ((ConfiguredEndpointsKey) ((KeyStep) last).key()).getName(); } - if (((IdentifiableItem) last).getKey() instanceof ActualEndpointsKey) { - return ((ActualEndpointsKey) ((IdentifiableItem) last).getKey()).getName(); + if (((KeyStep) last).key() instanceof ActualEndpointsKey) { + return ((ActualEndpointsKey) ((KeyStep) last).key()).getName(); } throw new IllegalArgumentException("Unrecognized key : " + last); } diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/JsonRpcPeerListManager.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/JsonRpcPeerListManager.java index 6efedb02..4c6f0946 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/JsonRpcPeerListManager.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/JsonRpcPeerListManager.java @@ -10,10 +10,11 @@ package org.opendaylight.jsonrpc.provider.cluster.impl; import static org.opendaylight.jsonrpc.provider.common.Util.removeFromMapAndClose; import akka.util.Timeout; +import com.google.common.collect.ImmutableClassToInstanceMap; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -24,21 +25,22 @@ import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.jsonrpc.provider.cluster.api.JsonRpcPeerSingletonService; import org.opendaylight.jsonrpc.provider.common.AbstractPeerContext; import org.opendaylight.jsonrpc.provider.common.Util; -import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataObjectModification; +import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataTreeModification; -import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceRefresh; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceRefreshInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceRefreshOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceRefreshOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceReload; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceReloadInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceReloadOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceReloadOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.JsonrpcService; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.config.ConfiguredEndpoints; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.Rpc; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.slf4j.Logger; @@ -51,14 +53,16 @@ import org.slf4j.LoggerFactory; * @author Richard Kosegi * @since Jul 1, 2020 */ -public final class JsonRpcPeerListManager implements ClusteredDataTreeChangeListener, - JsonRpcPeerSingletonService, JsonrpcService, AutoCloseable { +public final class JsonRpcPeerListManager implements DataTreeChangeListener, + JsonRpcPeerSingletonService, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(JsonRpcPeerListManager.class); - private final ListenerRegistration dtcListener; + @GuardedBy("this") private final Map peerMap = new HashMap<>(); - private final Map clusterRegistrations = new HashMap<>(); + private final Map clusterRegistrations = new HashMap<>(); private final ClusterDependencies dependencies; + private final Registration dtcListener; + private Registration rpcReg; public JsonRpcPeerListManager(ClusterDependencies dependencies) { this(dependencies, Timeout.apply(90, TimeUnit.SECONDS)); @@ -67,33 +71,38 @@ public final class JsonRpcPeerListManager implements ClusteredDataTreeChangeList private JsonRpcPeerListManager(ClusterDependencies dependencies, Timeout askTimeout) { this.dependencies = dependencies; this.dtcListener = dependencies.getDataBroker() - .registerDataTreeChangeListener(ClusterUtil.getPeerListIdentifier(), this); + .registerTreeChangeListener(ClusterUtil.getPeerListIdentifier(), this); + this.rpcReg = dependencies.getRpcProviderService() + .registerRpcImplementations(ImmutableClassToInstanceMap.>builder() + .put(ForceRefresh.class, JsonRpcPeerListManager::forceRefresh) + .put(ForceReload.class, this::forceReload) + .build()); } @Override - public void onDataTreeChanged(@NonNull Collection> changes) { + public void onDataTreeChanged(@NonNull List> changes) { for (final DataTreeModification change : changes) { final DataObjectModification rootNode = change.getRootNode(); - final InstanceIdentifier ident = change.getRootPath().getRootIdentifier(); + final InstanceIdentifier ident = change.getRootPath().path(); final String name = ClusterUtil.peerNameFromII(ident); - LOG.debug("CFG DTC [{}] : {} => {}", rootNode.getModificationType(), rootNode.getDataBefore(), - rootNode.getDataAfter()); - switch (rootNode.getModificationType()) { + LOG.debug("CFG DTC [{}] : {} => {}", rootNode.modificationType(), rootNode.dataBefore(), + rootNode.dataAfter()); + switch (rootNode.modificationType()) { case SUBTREE_MODIFIED: - updatePeerContext(rootNode.getDataAfter()); + updatePeerContext(rootNode.dataAfter()); break; case WRITE: if (peerMap.containsKey(name)) { - updatePeerContext(rootNode.getDataAfter()); + updatePeerContext(rootNode.dataAfter()); } else { - createPeerContext(rootNode.getDataAfter()); + createPeerContext(rootNode.dataAfter()); } break; case DELETE: destroyPeerContext(name); break; default: - LOG.warn("Unhandled data modification {}", rootNode.getModificationType()); + LOG.warn("Unhandled data modification {}", rootNode.modificationType()); } } } @@ -118,7 +127,7 @@ public final class JsonRpcPeerListManager implements ClusteredDataTreeChangeList LOG.info("Creating context for '{}'", peer.getName()); final RemotePeerContext service = new RemotePeerContext(peer, dependencies); - final ClusterSingletonServiceRegistration clusterContext = dependencies.getClusterSingletonServiceProvider() + final Registration clusterContext = dependencies.getClusterSingletonServiceProvider() .registerClusterSingletonService(service); LOG.debug("Created {}", service); @@ -130,21 +139,19 @@ public final class JsonRpcPeerListManager implements ClusteredDataTreeChangeList @Override public void close() { + rpcReg.close(); dtcListener.close(); clusterRegistrations.values().forEach(Util::closeAndLogOnError); peerMap.values().forEach(Util::closeAndLogOnError); peerMap.clear(); } - @Override - public ListenableFuture> forceRefresh(ForceRefreshInput input) { + private static ListenableFuture> forceRefresh(ForceRefreshInput input) { // This is NOOP nowadays return Futures.immediateFuture(RpcResultBuilder.success(new ForceRefreshOutputBuilder().build()).build()); } - @Holding("this") - @Override - public synchronized ListenableFuture> forceReload(ForceReloadInput input) { + private synchronized ListenableFuture> forceReload(ForceReloadInput input) { //take snapshot of configured peers final Set configured = peerMap.values() .stream() diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ProxyDOMDataBroker.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ProxyDOMDataBroker.java index b1ff8cc9..b0ddcdde 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ProxyDOMDataBroker.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ProxyDOMDataBroker.java @@ -13,19 +13,15 @@ import static org.opendaylight.jsonrpc.provider.cluster.impl.ClusterUtil.duratio import akka.actor.ActorRef; import akka.pattern.Patterns; import akka.util.Timeout; -import com.google.common.collect.ClassToInstanceMap; -import com.google.common.collect.ImmutableClassToInstanceMap; import java.util.concurrent.TimeUnit; import org.opendaylight.jsonrpc.provider.cluster.tx.ProxyReadTransaction; import org.opendaylight.jsonrpc.provider.cluster.tx.ProxyReadWriteTransaction; import org.opendaylight.jsonrpc.provider.cluster.tx.TxRequest; import org.opendaylight.mdsal.dom.api.DOMDataBroker; -import org.opendaylight.mdsal.dom.api.DOMDataBrokerExtension; import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction; import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMTransactionChain; -import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener; import org.opendaylight.mdsal.dom.spi.PingPongMergingDOMDataBroker; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; import org.slf4j.Logger; @@ -83,16 +79,11 @@ final class ProxyDOMDataBroker implements PingPongMergingDOMDataBroker { // TODO : How about this? @Override - public DOMTransactionChain createTransactionChain(final DOMTransactionChainListener listener) { - LOG.debug("[{}] new transaction chain with listener {}", peer.getName(), listener); + public DOMTransactionChain createTransactionChain() { + LOG.debug("[{}] new transaction chain", peer.getName()); throw new UnsupportedOperationException("Transaction chains not supported for JSONRPC mount point"); } - @Override - public ClassToInstanceMap getExtensions() { - return ImmutableClassToInstanceMap.of(); - } - @Override public String toString() { return "ProxyDOMDataBroker [peer=" + peer + ", askTimeout=" + askTimeout + ", masterActorRef=" + masterActorRef diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ProxyDOMRpcService.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ProxyDOMRpcService.java index e4ca876c..18408749 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ProxyDOMRpcService.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/ProxyDOMRpcService.java @@ -32,7 +32,7 @@ import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.mdsal.dom.api.DefaultDOMRpcException; import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; @@ -108,7 +108,7 @@ final class ProxyDOMRpcService implements DOMRpcService { } @Override - public ListenerRegistration registerRpcListener(T listener) { + public Registration registerRpcListener(DOMRpcAvailabilityListener listener) { throw new UnsupportedOperationException("registerRpcListener is not supported in cluster"); } diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/RemotePeerContext.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/RemotePeerContext.java index 9f469035..e2ff4af4 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/RemotePeerContext.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/RemotePeerContext.java @@ -41,8 +41,8 @@ import org.opendaylight.mdsal.dom.api.DOMMountPoint; import org.opendaylight.mdsal.dom.api.DOMMountPointService.DOMMountPointBuilder; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.mdsal.dom.api.DOMSchemaService; -import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService; -import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; +import org.opendaylight.mdsal.singleton.api.ClusterSingletonService; +import org.opendaylight.mdsal.singleton.api.ServiceGroupIdentifier; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.MountStatus; @@ -74,7 +74,7 @@ class RemotePeerContext extends AbstractPeerContext implements ClusterSingletonS super(peer, dependencies.getDataBroker()); name = peer.getName(); this.peer = peer; - sgi = ServiceGroupIdentifier.create(Util.createBiPath(peer.getName()).toString()); + sgi = new ServiceGroupIdentifier(Util.createBiPath(peer.getName()).toString()); this.dependencies = dependencies; slaveContext = new SlavePeerContext(peer, dependencies); selfAddress = Cluster.get(dependencies.getActorSystem()).selfAddress().toString(); diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/SlavePeerContext.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/SlavePeerContext.java index add48f22..ea6ce1b2 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/SlavePeerContext.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/impl/SlavePeerContext.java @@ -19,29 +19,28 @@ import akka.actor.ActorSelection; import akka.actor.PoisonPill; import akka.dispatch.OnComplete; import akka.util.Timeout; -import java.util.Collection; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.jsonrpc.provider.cluster.api.JsonRpcPeerSingletonService; import org.opendaylight.jsonrpc.provider.cluster.messages.MountPointRequest; import org.opendaylight.jsonrpc.provider.cluster.messages.UnregisterMountPoint; -import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataObjectModification; +import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataTreeModification; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.MountStatus; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.config.ActualEndpoints; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scala.concurrent.duration.Duration; final class SlavePeerContext - implements ClusteredDataTreeChangeListener, JsonRpcPeerSingletonService, AutoCloseable { + implements DataTreeChangeListener, JsonRpcPeerSingletonService, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(SlavePeerContext.class); private final AtomicBoolean closed = new AtomicBoolean(false); - private final ListenerRegistration dtclRegistration; + private final Registration dtclRegistration; private ActorRef slaveActorRef; private final Timeout askTimeout; private final Peer peer; @@ -51,7 +50,7 @@ final class SlavePeerContext this.peer = peer; this.dependencies = dependencies; dtclRegistration = dependencies.getDataBroker() - .registerDataTreeChangeListener(getPeerOpstateIdentifier(peer.getName()), this); + .registerTreeChangeListener(getPeerOpstateIdentifier(peer.getName()), this); final Duration askDuration = dependencies.getConfig() == null ? DEFAULT_ASK_TIMEOUT : durationFromUint16seconds(dependencies.getConfig().getActorResponseWaitTime(), DEFAULT_ASK_TIMEOUT); askTimeout = Timeout.apply(askDuration.toSeconds(), TimeUnit.SECONDS); @@ -59,21 +58,21 @@ final class SlavePeerContext } @Override - public void onDataTreeChanged(@NonNull Collection> changes) { + public void onDataTreeChanged(List> changes) { for (final DataTreeModification change : changes) { final DataObjectModification rootNode = change.getRootNode(); - LOG.debug("[{}] OP DTC [{}] : {} => {}", peer.getName(), rootNode.getModificationType(), - rootNode.getDataBefore(), rootNode.getDataAfter()); - switch (rootNode.getModificationType()) { + LOG.debug("[{}] OP DTC [{}] : {} => {}", peer.getName(), rootNode.modificationType(), + rootNode.dataBefore(), rootNode.dataAfter()); + switch (rootNode.modificationType()) { case SUBTREE_MODIFIED: case WRITE: - onMountpointUpdated(rootNode.getDataAfter()); + onMountpointUpdated(rootNode.dataAfter()); break; case DELETE: deleteMountpoint(); break; default: - LOG.warn("[{}] Unhandled modification {}", peer.getName(), rootNode.getModificationType()); + LOG.warn("[{}] Unhandled modification {}", peer.getName(), rootNode.modificationType()); } } } diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/ActorProxyTransaction.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/ActorProxyTransaction.java index 76477d80..4a2c18a1 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/ActorProxyTransaction.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/ActorProxyTransaction.java @@ -27,7 +27,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scala.concurrent.ExecutionContext; -import scala.concurrent.Future; /** * Implementation of {@link DOMDataTreeReadWriteTransaction} that interacts with an actor. @@ -41,6 +40,8 @@ import scala.concurrent.Future; class ActorProxyTransaction implements ProxyTransactionFacade { private static final Logger LOG = LoggerFactory.getLogger(ActorProxyTransaction.class); + private final SettableFuture settableFuture = SettableFuture.create(); + private final FluentFuture completionFuture = FluentFuture.from(settableFuture); private final ActorRef actorRef; private final Peer peer; private final ExecutionContext executionContext; @@ -51,11 +52,16 @@ class ActorProxyTransaction implements ProxyTransactionFacade { final Timeout askTimeout) { this.actorRef = Objects.requireNonNull(actorRef); this.peer = Objects.requireNonNull(peer); - this.name = peer.getName(); + name = peer.getName(); this.executionContext = Objects.requireNonNull(executionContext); this.askTimeout = Objects.requireNonNull(askTimeout); } + @Override + public FluentFuture completionFuture() { + return completionFuture; + } + @Override public Object getIdentifier() { return peer; @@ -64,8 +70,7 @@ class ActorProxyTransaction implements ProxyTransactionFacade { @Override public boolean cancel() { LOG.debug("[{}]: Cancel tx via actor {}", name, actorRef); - final Future future = Patterns.ask(actorRef, new TxCancel(), askTimeout); - future.onComplete(new OnComplete<>() { + Patterns.ask(actorRef, new TxCancel(), askTimeout).onComplete(new OnComplete<>() { @Override public void onComplete(final Throwable failure, final Object response) { if (failure != null) { @@ -75,24 +80,23 @@ class ActorProxyTransaction implements ProxyTransactionFacade { LOG.debug("[{}] tx cancel succeeded", name); } }, executionContext); - return true; + return settableFuture.cancel(false); } @Override public FluentFuture> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) { LOG.debug("[{}] Read {} {} via actor {}", name, store, path, actorRef); - final Future future = Patterns.ask(actorRef, new TxRead(store, path, false), askTimeout); - final SettableFuture> settableFuture = SettableFuture.create(); - future.onComplete(new OnComplete<>() { + final SettableFuture> future = SettableFuture.create(); + Patterns.ask(actorRef, new TxRead(store, path, false), askTimeout).onComplete(new OnComplete<>() { @Override public void onComplete(final Throwable failure, final Object response) { if (failure != null) { LOG.debug("[{}]: Read {} {} failed", name, store, path, failure); if (failure instanceof ReadFailedException) { - settableFuture.setException(failure); + future.setException(failure); } else { - settableFuture.setException( + future.setException( new ReadFailedException("Read of store " + store + " at " + path + " failed", failure)); } return; @@ -101,41 +105,40 @@ class ActorProxyTransaction implements ProxyTransactionFacade { LOG.debug("[{}] Read {} {} succeeded: {}", name, store, path, response); if (response instanceof EmptyReadResponse) { - settableFuture.set(Optional.empty()); - } else if (response instanceof PathAndDataMsg) { - final PathAndDataMsg pad = (PathAndDataMsg) response; - settableFuture.set(Optional.of(pad.getData())); + future.set(Optional.empty()); + } else if (response instanceof final PathAndDataMsg pad) { + future.set(Optional.of(pad.getData())); } } }, executionContext); - return FluentFuture.from(settableFuture); + return FluentFuture.from(future); } @Override public FluentFuture exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) { LOG.debug("[{}] Exists {} {} via actor {}", name, store, path, actorRef); - final SettableFuture settableFuture = SettableFuture.create(); + final SettableFuture future = SettableFuture.create(); Patterns.ask(actorRef, new TxRead(store, path, true), askTimeout).onComplete(new OnComplete<>() { @Override public void onComplete(final Throwable failure, final Object response) { if (failure != null) { LOG.debug("[{}] Exists {} {} failed", name, store, path, failure); if (failure instanceof ReadFailedException) { - settableFuture.setException(failure); + future.setException(failure); } else { - settableFuture.setException(new ReadFailedException( + future.setException(new ReadFailedException( "Exists of store " + store + " path " + path + " failed", failure)); } return; } LOG.debug("[{}] Exists {} {} succeeded: {}", name, store, path, response); - settableFuture.set((Boolean) response); + future.set((Boolean) response); } }, executionContext); - return FluentFuture.from(settableFuture); + return FluentFuture.from(future); } @Override @@ -159,7 +162,6 @@ class ActorProxyTransaction implements ProxyTransactionFacade { @Override public FluentFuture commit() { LOG.debug("[{}] Commit via actor {}", name, actorRef); - final SettableFuture settableFuture = SettableFuture.create(); Patterns.ask(actorRef, new TxCommit(), askTimeout).onComplete(new OnComplete<>() { @Override public void onComplete(final Throwable failure, final Object response) { @@ -178,6 +180,6 @@ class ActorProxyTransaction implements ProxyTransactionFacade { } }, executionContext); - return FluentFuture.from(settableFuture); + return completionFuture; } } diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/FailedProxyTransaction.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/FailedProxyTransaction.java index 699fce8c..79ab6c3e 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/FailedProxyTransaction.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/FailedProxyTransaction.java @@ -10,7 +10,6 @@ package org.opendaylight.jsonrpc.provider.cluster.tx; import com.google.common.util.concurrent.FluentFuture; import java.util.Objects; import java.util.Optional; -import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.common.api.CommitInfo; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.common.api.ReadFailedException; @@ -23,12 +22,17 @@ import org.slf4j.LoggerFactory; class FailedProxyTransaction implements ProxyTransactionFacade { private static final Logger LOG = LoggerFactory.getLogger(FailedProxyTransaction.class); + private final String name; private final Throwable failure; + private final FluentFuture completionFuture; FailedProxyTransaction(final String name, final Throwable failure) { this.name = Objects.requireNonNull(name); this.failure = Objects.requireNonNull(failure); + completionFuture = FluentFutures.immediateFailedFluentFuture( + failure instanceof TransactionCommitFailedException tcfe ? tcfe : + new TransactionCommitFailedException("commit", failure)); } @Override @@ -41,14 +45,14 @@ class FailedProxyTransaction implements ProxyTransactionFacade { final YangInstanceIdentifier path) { LOG.debug("[{}][FAILED] Read {} {}", name, store, path, failure); return FluentFutures.immediateFailedFluentFuture(ReadFailedException.MAPPER - .apply(failure instanceof Exception ? (Exception) failure : new ReadFailedException("read", failure))); + .apply(failure instanceof Exception ex ? ex : new ReadFailedException("read", failure))); } @Override public FluentFuture exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) { LOG.debug("[{}][FAILED] Exists {} {}", name, store, path, failure); return FluentFutures.immediateFailedFluentFuture(ReadFailedException.MAPPER.apply( - failure instanceof Exception ? (Exception) failure : new ReadFailedException("exists", failure))); + failure instanceof Exception ex ? ex : new ReadFailedException("exists", failure))); } @Override @@ -73,14 +77,13 @@ class FailedProxyTransaction implements ProxyTransactionFacade { } @Override - public @NonNull FluentFuture commit() { + public FluentFuture commit() { LOG.debug("[{}][FAILED] Commit", name, failure); - final TransactionCommitFailedException cause; - if (failure instanceof TransactionCommitFailedException) { - cause = (TransactionCommitFailedException) failure; - } else { - cause = new TransactionCommitFailedException("commit", failure); - } - return FluentFutures.immediateFailedFluentFuture(cause); + return completionFuture; + } + + @Override + public FluentFuture completionFuture() { + return completionFuture; } } \ No newline at end of file diff --git a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/ProxyReadWriteTransaction.java b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/ProxyReadWriteTransaction.java index ca5110d4..048a2468 100644 --- a/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/ProxyReadWriteTransaction.java +++ b/provider/cluster/src/main/java/org/opendaylight/jsonrpc/provider/cluster/tx/ProxyReadWriteTransaction.java @@ -19,7 +19,6 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; -import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.common.api.CommitInfo; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction; @@ -34,14 +33,18 @@ import scala.concurrent.Future; public class ProxyReadWriteTransaction implements DOMDataTreeReadWriteTransaction { private static final Logger LOG = LoggerFactory.getLogger(ProxyReadWriteTransaction.class); + private final String name; private final AtomicBoolean opened = new AtomicBoolean(true); private final List> queue = new ArrayList<>(); + private final SettableFuture settableFuture = SettableFuture.create(); + private final FluentFuture completionFuture = FluentFuture.from(settableFuture); + private volatile ProxyTransactionFacade txFacade; public ProxyReadWriteTransaction(final Peer peer, final Future future, final ExecutionContext executionContext, final Timeout askTimeout) { - this.name = peer.getName(); + name = peer.getName(); future.onComplete(new OnComplete<>() { @Override @@ -60,6 +63,11 @@ public class ProxyReadWriteTransaction implements DOMDataTreeReadWriteTransactio }, executionContext); } + @Override + public FluentFuture completionFuture() { + return completionFuture; + } + @Override public boolean cancel() { if (!opened.compareAndSet(true, false)) { @@ -67,6 +75,7 @@ public class ProxyReadWriteTransaction implements DOMDataTreeReadWriteTransactio } performAction(DOMDataTreeWriteTransaction::cancel, "cancel"); + completionFuture.cancel(false); return true; } @@ -109,13 +118,12 @@ public class ProxyReadWriteTransaction implements DOMDataTreeReadWriteTransactio } @Override - public @NonNull FluentFuture commit() { + public FluentFuture commit() { Preconditions.checkState(opened.compareAndSet(true, false), "[%s] Transaction is already closed", name); LOG.debug("[{}] Commit", name); - final SettableFuture returnFuture = SettableFuture.create(); - performAction(facade -> returnFuture.setFuture(facade.commit()), "commit"); - return FluentFuture.from(returnFuture); + performAction(facade -> settableFuture.setFuture(facade.commit()), "commit"); + return completionFuture; } @Override @@ -123,7 +131,7 @@ public class ProxyReadWriteTransaction implements DOMDataTreeReadWriteTransactio return this; } - private void performAction(final Consumer operation, String opDescription) { + private void performAction(final Consumer operation, final String opDescription) { final ProxyTransactionFacade facadeOnEntry; synchronized (queue) { if (txFacade == null) { diff --git a/provider/cluster/src/main/resources/OSGI-INF/blueprint/cluster-provider-wiring.xml b/provider/cluster/src/main/resources/OSGI-INF/blueprint/cluster-provider-wiring.xml index 570e92cd..2e8d9b2a 100644 --- a/provider/cluster/src/main/resources/OSGI-INF/blueprint/cluster-provider-wiring.xml +++ b/provider/cluster/src/main/resources/OSGI-INF/blueprint/cluster-provider-wiring.xml @@ -17,14 +17,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html - + + - + @@ -40,13 +39,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html + - - - diff --git a/provider/cluster/src/test/java/org/opendaylight/jsonrpc/provider/cluster/MountpointTest.java b/provider/cluster/src/test/java/org/opendaylight/jsonrpc/provider/cluster/MountpointTest.java index 7ca62fd5..c35add7e 100644 --- a/provider/cluster/src/test/java/org/opendaylight/jsonrpc/provider/cluster/MountpointTest.java +++ b/provider/cluster/src/test/java/org/opendaylight/jsonrpc/provider/cluster/MountpointTest.java @@ -55,6 +55,7 @@ import org.opendaylight.mdsal.binding.api.DataObjectModification; import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; import org.opendaylight.mdsal.binding.api.DataTreeModification; import org.opendaylight.mdsal.binding.api.ReadTransaction; +import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.binding.api.WriteTransaction; import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; @@ -65,9 +66,9 @@ import org.opendaylight.mdsal.dom.api.DOMMountPoint; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.mdsal.dom.api.DOMRpcResult; import org.opendaylight.mdsal.dom.api.DOMRpcService; -import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider; -import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration; -import org.opendaylight.mdsal.singleton.dom.impl.DOMClusterSingletonServiceProviderImpl; +import org.opendaylight.mdsal.eos.dom.simple.SimpleDOMEntityOwnershipService; +import org.opendaylight.mdsal.singleton.api.ClusterSingletonServiceProvider; +import org.opendaylight.mdsal.singleton.impl.EOSClusterSingletonServiceProvider; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Config; @@ -85,6 +86,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.data.rev201014 import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.FactorialInput; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.YangModuleInfo; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; @@ -105,15 +107,17 @@ public class MountpointTest { .child(ConfiguredEndpoints.class, new ConfiguredEndpointsKey("device-1")) .build(); private static final DataTreeIdentifier PEER_OP_DTI = DataTreeIdentifier - .create(LogicalDatastoreType.OPERATIONAL, MOCK_PEER_OP_ID); + .of(LogicalDatastoreType.OPERATIONAL, MOCK_PEER_OP_ID); private @Mock AbstractTransportFactory transportFactory; - private DOMClusterSingletonServiceProviderImpl clusterSingletonServiceProvider; + private EOSClusterSingletonServiceProvider clusterSingletonServiceProvider; private @Mock ClusterSingletonServiceProvider mockClusterSingletonServiceProvider; private @Mock ActorSystemProvider masterActorSystemProvider; private @Mock ActorSystemProvider slaveActorSystemProvider; private @Mock GovernanceProvider governanceProvider; - private @Mock ClusterSingletonServiceRegistration mockSingletonRegistration; + private @Mock Registration mockSingletonRegistration; private @Mock RequesterSession rpcClient; + private @Mock RpcProviderService rpcProviderService; + private @Mock Registration rpcReg; private JsonRpcPeerListManager masterManager; private JsonRpcPeerListManager slaveManager; private TestCustomizer masterTestCustomizer; @@ -125,8 +129,7 @@ public class MountpointTest { @Before public void setUp() throws Exception { MockitoAnnotations.openMocks(this); - clusterSingletonServiceProvider = new DOMClusterSingletonServiceProviderImpl(); - clusterSingletonServiceProvider.initializeProvider(); + clusterSingletonServiceProvider = new EOSClusterSingletonServiceProvider(new SimpleDOMEntityOwnershipService()); final YangXPathParserFactory yangXPathParserFactory = ServiceLoader .load(YangXPathParserFactory.class) @@ -150,17 +153,19 @@ public class MountpointTest { .sendRequestAndReadReply(anyString(), any(), any(JsonObject.class)); doReturn(rpcClient).when(transportFactory) .createRequester(anyString(), any(ReplyMessageHandler.class), anyBoolean()); + doReturn(rpcReg).when(rpcProviderService).registerRpcImplementations(any()); + final ClusterDependencies masterDeps = new ClusterDependencies(tf, masterTestCustomizer.getDataBroker(), masterTestCustomizer.getDOMMountPointService(), masterTestCustomizer.getDomBroker(), masterTestCustomizer.getSchemaService(), masterTestCustomizer.getDOMNotificationRouter(), - masterTestCustomizer.getDOMRpcRouter().getRpcService(), yangXPathParserFactory, masterActorSystem, - clusterSingletonServiceProvider, governanceProvider, null); + masterTestCustomizer.getDOMRpcRouter().rpcService(), yangXPathParserFactory, masterActorSystem, + clusterSingletonServiceProvider, governanceProvider, rpcProviderService, null); final ClusterDependencies slaveDeps = new ClusterDependencies(tf, slaveTestCustomizer.getDataBroker(), slaveTestCustomizer.getDOMMountPointService(), slaveTestCustomizer.getDomBroker(), slaveTestCustomizer.getSchemaService(), slaveTestCustomizer.getDOMNotificationRouter(), - slaveTestCustomizer.getDOMRpcRouter().getRpcService(), yangXPathParserFactory, slaveActorSystem, - mockClusterSingletonServiceProvider, governanceProvider, null); + slaveTestCustomizer.getDOMRpcRouter().rpcService(), yangXPathParserFactory, slaveActorSystem, + mockClusterSingletonServiceProvider, governanceProvider, rpcProviderService, null); masterConverter = new JsonRpcCodecFactory(masterTestCustomizer.getSchemaService().getGlobalContext()); JsonRpcDatastoreAdapter datastoreAdapter = new JsonRpcDatastoreAdapter(masterConverter, @@ -268,16 +273,16 @@ public class MountpointTest { } private void testSlave() throws InterruptedException, ExecutionException { - masterTestCustomizer.getDataBroker().registerDataTreeChangeListener(PEER_OP_DTI, changes -> { + masterTestCustomizer.getDataBroker().registerTreeChangeListener(PEER_OP_DTI, changes -> { final WriteTransaction slaveTx = slaveTestCustomizer.getDataBroker().newWriteOnlyTransaction(); for (DataTreeModification dtm : changes) { LOG.info("Change to copy : {}", dtm); DataObjectModification rootNode = dtm.getRootNode(); - InstanceIdentifier path = dtm.getRootPath().getRootIdentifier(); - switch (rootNode.getModificationType()) { + InstanceIdentifier path = dtm.getRootPath().path(); + switch (rootNode.modificationType()) { case WRITE: case SUBTREE_MODIFIED: - slaveTx.merge(LogicalDatastoreType.OPERATIONAL, path, rootNode.getDataAfter()); + slaveTx.merge(LogicalDatastoreType.OPERATIONAL, path, rootNode.dataAfter()); break; case DELETE: slaveTx.delete(LogicalDatastoreType.OPERATIONAL, path); diff --git a/provider/cluster/src/test/java/org/opendaylight/jsonrpc/provider/cluster/TestCustomizer.java b/provider/cluster/src/test/java/org/opendaylight/jsonrpc/provider/cluster/TestCustomizer.java index 229c068e..cdc95814 100644 --- a/provider/cluster/src/test/java/org/opendaylight/jsonrpc/provider/cluster/TestCustomizer.java +++ b/provider/cluster/src/test/java/org/opendaylight/jsonrpc/provider/cluster/TestCustomizer.java @@ -33,7 +33,7 @@ public class TestCustomizer extends AbstractConcurrentDataBrokerTest { } public DOMNotificationPublishService getDOMNotificationRouter() { - return notificationRouter; + return notificationRouter.notificationPublishService(); } public DOMRpcRouter getDOMRpcRouter() { diff --git a/provider/common/pom.xml b/provider/common/pom.xml index ebca8fab..ccd215a7 100644 --- a/provider/common/pom.xml +++ b/provider/common/pom.xml @@ -23,8 +23,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.mdsal - dom-parent - 12.0.4 + bnd-parent + 13.0.0 pom import diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/DataChangeListenerRegistration.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/DataChangeListenerRegistration.java index d002f3f4..b1845db7 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/DataChangeListenerRegistration.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/DataChangeListenerRegistration.java @@ -24,10 +24,10 @@ import org.opendaylight.jsonrpc.model.ListenerKey; import org.opendaylight.jsonrpc.provider.common.Util; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.DOMDataBroker; +import org.opendaylight.mdsal.dom.api.DOMDataBroker.DataTreeChangeExtension; import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener; -import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService; import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate; import org.slf4j.Logger; @@ -40,12 +40,11 @@ import org.slf4j.LoggerFactory; * @author Richard Kosegi * @since May 8, 2018 */ -public final class DataChangeListenerRegistration - implements ListenerRegistration, DOMDataTreeChangeListener { +public final class DataChangeListenerRegistration implements Registration, DOMDataTreeChangeListener { private static final Logger LOG = LoggerFactory.getLogger(DataChangeListenerRegistration.class); private final DataChangeNotificationPublisher publisher; private final YangInstanceIdentifier path; - private final ListenerRegistration delegate; + private final Registration delegate; private final JsonRpcCodecFactory codecFactory; private final Consumer closeCallback; private final ListenerKey listenerKey; @@ -61,9 +60,8 @@ public final class DataChangeListenerRegistration this.listenerKey = Objects.requireNonNull(listenerKey); Objects.requireNonNull(domDataBroker); Objects.requireNonNull(store); - final DOMDataTreeChangeService dtcs = (DOMDataTreeChangeService) domDataBroker.getExtensions() - .get(DOMDataTreeChangeService.class); - delegate = dtcs.registerDataTreeChangeListener(new DOMDataTreeIdentifier(store, path), this); + final var dtcs = domDataBroker.extension(DataTreeChangeExtension.class); + delegate = dtcs.registerDataTreeChangeListener(DOMDataTreeIdentifier.of(store, path), this); } @SuppressWarnings("checkstyle:IllegalCatch") @@ -78,11 +76,6 @@ public final class DataChangeListenerRegistration } } - @Override - public DOMDataTreeChangeListener getInstance() { - return this; - } - @Override public void onInitialData() { // TODO: do something? diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/EnsureParentTransactionFactory.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/EnsureParentTransactionFactory.java index 4677a72c..a60db8d5 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/EnsureParentTransactionFactory.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/EnsureParentTransactionFactory.java @@ -50,7 +50,7 @@ class EnsureParentTransactionFactory implements TransactionFactory { while (it.hasNext()) { final PathArgument pathArgument = it.next(); if (rootNormalizedPath == null) { - rootNormalizedPath = YangInstanceIdentifier.create(pathArgument); + rootNormalizedPath = YangInstanceIdentifier.of(pathArgument); } if (it.hasNext()) { normalizedPathWithoutChildArgs.add(pathArgument); @@ -61,7 +61,7 @@ class EnsureParentTransactionFactory implements TransactionFactory { } Preconditions.checkArgument(rootNormalizedPath != null, "Empty path received"); final NormalizedNode parentStructure = ImmutableNodes.fromInstanceId(schemaContext, - YangInstanceIdentifier.create(normalizedPathWithoutChildArgs)); + YangInstanceIdentifier.of(normalizedPathWithoutChildArgs)); delegate().merge(store, rootNormalizedPath, parentStructure); } diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCDataBroker.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCDataBroker.java index dca673be..c2d2ac58 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCDataBroker.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCDataBroker.java @@ -10,12 +10,11 @@ package org.opendaylight.jsonrpc.impl; import static org.opendaylight.jsonrpc.provider.common.Util.store2int; import static org.opendaylight.jsonrpc.provider.common.Util.store2str; -import com.google.common.collect.ClassToInstanceMap; -import com.google.common.collect.ImmutableClassToInstanceMap; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import java.io.IOException; import java.net.URISyntaxException; +import java.util.List; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.jsonrpc.bus.messagelib.TransportFactory; @@ -31,23 +30,20 @@ import org.opendaylight.jsonrpc.model.RemoteOmShard; import org.opendaylight.jsonrpc.provider.common.Util; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.DOMDataBroker; -import org.opendaylight.mdsal.dom.api.DOMDataBrokerExtension; import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener; -import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService; import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier; import org.opendaylight.mdsal.dom.api.DOMTransactionChain; -import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; -import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.AbstractRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public final class JsonRPCDataBroker extends RemoteShardAware implements DOMDataBroker, DOMDataTreeChangeService { +public final class JsonRPCDataBroker extends RemoteShardAware + implements DOMDataBroker, DOMDataBroker.DataTreeChangeExtension { private static final Logger LOG = LoggerFactory.getLogger(JsonRPCDataBroker.class); private static final JsonObject TOP = new JsonObject(); - private final ClassToInstanceMap extensions; /** * Instantiates a new JSON-RPC data broker. @@ -65,9 +61,7 @@ public final class JsonRPCDataBroker extends RemoteShardAware implements DOMData @NonNull TransportFactory transportFactory, @Nullable RemoteGovernance governance, @NonNull JsonRpcCodecFactory codecFactory) { super(schemaContext, transportFactory, pathMap, codecFactory, peer); - extensions = ImmutableClassToInstanceMap.builder() - .put(DOMDataTreeChangeService.class, this) - .build(); + if (peer.getDataConfigEndpoints() != null) { Util.populateFromEndpointList(pathMap, peer.nonnullDataConfigEndpoints().values(), DataType.CONFIGURATION_DATA); @@ -106,30 +100,29 @@ public final class JsonRPCDataBroker extends RemoteShardAware implements DOMData } @Override - public DOMTransactionChain createTransactionChain(DOMTransactionChainListener listener) { - return new TxChain(this, listener, transportFactory, pathMap, codecFactory, schemaContext, peer); + public DOMTransactionChain createTransactionChain() { + return new TxChain(this, transportFactory, pathMap, codecFactory, schemaContext, peer); } @Override - public @NonNull DOMTransactionChain createMergingTransactionChain(DOMTransactionChainListener listener) { - return createTransactionChain(listener); + public DOMTransactionChain createMergingTransactionChain() { + return createTransactionChain(); } @Override - public @NonNull ClassToInstanceMap getExtensions() { - return extensions; + public List supportedExtensions() { + return List.of(this); } @Override - public ListenerRegistration registerDataTreeChangeListener( - DOMDataTreeIdentifier treeId, L listener) { - final JsonElement busPath = codecFactory.pathCodec().serialize(treeId.getRootIdentifier()); - final RemoteOmShard shard = getShard(treeId.getDatastoreType(), busPath); + public Registration registerTreeChangeListener(DOMDataTreeIdentifier treeId, DOMDataTreeChangeListener listener) { + final JsonElement busPath = codecFactory.pathCodec().serialize(treeId.path()); + final RemoteOmShard shard = getShard(treeId.datastore(), busPath); final DOMDataTreeChangeListenerAdapter adapter; final ListenerKey listenerKey; try { listenerKey = shard.addListener(new AddListenerArgument( - String.valueOf(Util.store2int(treeId.getDatastoreType())), "", busPath, null)); + String.valueOf(Util.store2int(treeId.datastore())), "", busPath, null)); adapter = new DOMDataTreeChangeListenerAdapter(listener, transportFactory, listenerKey.getUri(), codecFactory, schemaContext); } catch (URISyntaxException e) { @@ -139,7 +132,7 @@ public final class JsonRPCDataBroker extends RemoteShardAware implements DOMData throw new IllegalStateException("Unable to create subscriber", e); } - return new AbstractListenerRegistration<>(listener) { + return new AbstractRegistration() { @Override protected void removeRegistration() { shard.deleteListener(new DeleteListenerArgument(listenerKey.getUri(), listenerKey.getName())); @@ -147,4 +140,10 @@ public final class JsonRPCDataBroker extends RemoteShardAware implements DOMData } }; } + + @Override + public Registration registerLegacyTreeChangeListener(DOMDataTreeIdentifier treeId, + DOMDataTreeChangeListener listener) { + return registerTreeChangeListener(treeId, listener); + } } diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCNotificationService.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCNotificationService.java index 90340d26..4f2f350e 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCNotificationService.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCNotificationService.java @@ -34,9 +34,7 @@ import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.mdsal.dom.api.DOMNotificationListener; import org.opendaylight.mdsal.dom.api.DOMNotificationService; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; -import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.AbstractRegistration; -import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; @@ -96,12 +94,12 @@ public final class JsonRPCNotificationService extends AbstractJsonRPCComponent } @Override - public synchronized ListenerRegistration registerNotificationListener( - final T listener, final Collection types) { + public synchronized Registration registerNotificationListener(final DOMNotificationListener listener, + final Collection types) { for (final Absolute type : types) { listeners.put(type, listener); } - return new AbstractListenerRegistration<>(listener) { + return new AbstractRegistration() { @Override protected void removeRegistration() { for (final Absolute type : types) { diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCTx.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCTx.java index e3f4ddc2..6ea5c3f1 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCTx.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCTx.java @@ -14,6 +14,7 @@ import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediate import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.util.concurrent.FluentFuture; +import com.google.common.util.concurrent.SettableFuture; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import java.util.ArrayList; @@ -55,8 +56,11 @@ public class JsonRPCTx extends RemoteShardAware implements JsonRpcTransactionFac .newError(ErrorType.APPLICATION, new ErrorTag("commit"), msg); private static final FluentFuture> NO_DATA = FluentFutures .immediateFluentFuture(Optional.empty()); + + private final @NonNull SettableFuture settableFuture = SettableFuture.create(); + private final @NonNull FluentFuture completionFuture = FluentFuture.from(settableFuture); /* Keep track of TX id to given endpoint (key is endpoint, value is TX ID) */ - private final Map txIdMap; + private final Map txIdMap = new HashMap<>(); private final List listeners = new CopyOnWriteArrayList<>(); private final Codec pathCodec; @@ -74,7 +78,6 @@ public class JsonRPCTx extends RemoteShardAware implements JsonRpcTransactionFac @NonNull JsonRpcCodecFactory codecFactory, @NonNull EffectiveModelContext schemaContext) { super(schemaContext, transportFactory, pathMap, codecFactory, peer); Preconditions.checkArgument(!Strings.isNullOrEmpty(peer.getName()), "Peer name is missing"); - this.txIdMap = new HashMap<>(); this.pathCodec = codecFactory.pathCodec(); } @@ -92,6 +95,11 @@ public class JsonRPCTx extends RemoteShardAware implements JsonRpcTransactionFac k -> withRemoteShard(store, path, RemoteOmShard::txid)); } + @Override + public FluentFuture completionFuture() { + return completionFuture; + } + @Override public FluentFuture> read(final LogicalDatastoreType store, final YangInstanceIdentifier path) { @@ -164,6 +172,7 @@ public class JsonRPCTx extends RemoteShardAware implements JsonRpcTransactionFac } txIdMap.clear(); listeners.forEach(listener -> listener.onCancel(this)); + settableFuture.cancel(false); return result; } catch (Exception e) { LOG.error("Unable to cancel transaction", e); @@ -190,14 +199,15 @@ public class JsonRPCTx extends RemoteShardAware implements JsonRpcTransactionFac txIdMap.clear(); if (result) { listeners.forEach(txListener -> txListener.onSuccess(this)); - return CommitInfo.emptyFluentFuture(); + settableFuture.set(CommitInfo.empty()); } else { final Throwable failure = new TransactionCommitFailedException( "Commit of transaction " + getIdentifier() + " failed", errors.stream().map(ERROR_MAPPER).toArray(size -> new RpcError[size])); listeners.forEach(txListener -> txListener.onFailure(this, failure)); - return FluentFutures.immediateFailedFluentFuture(failure); + settableFuture.setException(failure); } + return completionFuture; } @Override diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCtoRPCBridge.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCtoRPCBridge.java index 45723ca8..b9fc54f2 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCtoRPCBridge.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRPCtoRPCBridge.java @@ -17,7 +17,6 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; -import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.jsonrpc.bus.messagelib.TransportFactory; @@ -32,8 +31,7 @@ import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException; import org.opendaylight.mdsal.dom.api.DOMRpcResult; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; -import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.util.concurrent.FluentFutures; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; @@ -60,9 +58,9 @@ public final class JsonRPCtoRPCBridge extends AbstractJsonRPCComponent implement * @param governance additional json rpc service to query for endpoints * @param transportFactory - JSON RPC 2.0 transport factory */ - public JsonRPCtoRPCBridge(@NonNull Peer peer, @NonNull EffectiveModelContext schemaContext, - @NonNull HierarchicalEnumMap pathMap, @Nullable RemoteGovernance governance, - @NonNull TransportFactory transportFactory, @NonNull JsonRpcCodecFactory codecFactory) { + public JsonRPCtoRPCBridge(Peer peer, EffectiveModelContext schemaContext, + HierarchicalEnumMap pathMap, @Nullable RemoteGovernance governance, + TransportFactory transportFactory, JsonRpcCodecFactory codecFactory) { super(schemaContext, transportFactory, pathMap, codecFactory, peer); final ImmutableMap.Builder mappedRpcsBuilder = ImmutableMap.builder(); for (final RpcDefinition def : schemaContext.getOperations()) { @@ -115,15 +113,11 @@ public final class JsonRPCtoRPCBridge extends AbstractJsonRPCComponent implement } @Override - public ListenerRegistration registerRpcListener( - @NonNull final T listener) { + public Registration registerRpcListener(final DOMRpcAvailabilityListener listener) { LOG.info("registered RPC implementation for json rpc broker"); listener.onRpcAvailable(availableRpcs); - return new AbstractListenerRegistration<>(listener) { - @Override - protected void removeRegistration() { - // NOOP, no rpcs appear and disappear in this implementation - } + return () -> { + // NOOP, no rpcs appear and disappear in this implementation }; } diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRpcDOMSchemaService.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRpcDOMSchemaService.java index 19698bf5..9d71665c 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRpcDOMSchemaService.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/JsonRpcDOMSchemaService.java @@ -9,39 +9,41 @@ package org.opendaylight.jsonrpc.impl; import com.google.common.annotations.Beta; import edu.umd.cs.findbugs.annotations.NonNull; -import java.util.Collections; import java.util.Map; import java.util.Objects; -import org.opendaylight.mdsal.dom.spi.AbstractDOMSchemaService; +import java.util.Set; +import java.util.function.Consumer; +import org.opendaylight.mdsal.dom.api.DOMSchemaService; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.util.ListenerRegistry; +import org.opendaylight.yangtools.concepts.ObjectRegistration; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.util.ObjectRegistry; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; -import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextListener; import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement; import org.opendaylight.yangtools.yang.model.spi.SimpleSchemaContext; @Beta -public class JsonRpcDOMSchemaService extends AbstractDOMSchemaService implements AutoCloseable { +public class JsonRpcDOMSchemaService implements DOMSchemaService, AutoCloseable { private static final EffectiveModelContext EMPTY = new EmptySchema(); - private final ListenerRegistry listenerRegistry; - private final EffectiveModelContext context; + + private final ObjectRegistry> listenerRegistry; + private final @NonNull EffectiveModelContext context; private static final class EmptySchema extends SimpleSchemaContext implements EffectiveModelContext { protected EmptySchema() { - super(Collections.emptySet()); + super(Set.of()); } @Override public Map getModuleStatements() { - return Collections.emptyMap(); + return Map.of(); } } public JsonRpcDOMSchemaService(@NonNull Peer peer, @NonNull EffectiveModelContext context) { this.context = Objects.requireNonNull(context); - listenerRegistry = ListenerRegistry.create(peer.getName()); + listenerRegistry = ObjectRegistry.createConcurrent(peer.getName()); } @Override @@ -50,14 +52,13 @@ public class JsonRpcDOMSchemaService extends AbstractDOMSchemaService implements } @Override - public ListenerRegistration registerSchemaContextListener( - EffectiveModelContextListener listener) { + public Registration registerSchemaContextListener(Consumer listener) { return listenerRegistry.register(listener); } @Override public void close() { - listenerRegistry.streamListeners().forEach(listener -> listener.onModelContextUpdated(EMPTY)); - listenerRegistry.clear(); + listenerRegistry.streamObjects().forEach(listener -> listener.accept(EMPTY)); + listenerRegistry.streamRegistrations().forEach(ObjectRegistration::close); } } diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/RemoteControlProvider.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/RemoteControlProvider.java index acafcf8d..a0124f7b 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/RemoteControlProvider.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/RemoteControlProvider.java @@ -8,7 +8,7 @@ package org.opendaylight.jsonrpc.impl; import java.net.URISyntaxException; -import java.util.Collection; +import java.util.List; import java.util.Objects; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; @@ -19,10 +19,10 @@ import org.opendaylight.jsonrpc.model.GovernanceProvider; import org.opendaylight.jsonrpc.model.RemoteGovernance; import org.opendaylight.jsonrpc.provider.common.ProviderDependencies; import org.opendaylight.jsonrpc.provider.common.Util; -import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.binding.api.DataObjectModification; import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType; +import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; import org.opendaylight.mdsal.binding.api.DataTreeModification; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; @@ -33,7 +33,7 @@ import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.mdsal.dom.api.DOMSchemaService; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Config; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; import org.osgi.service.component.annotations.Activate; @@ -50,9 +50,9 @@ import org.slf4j.LoggerFactory; */ @Component(service = GovernanceProvider.class) public final class RemoteControlProvider - implements AutoCloseable, ClusteredDataTreeChangeListener, GovernanceProvider { + implements AutoCloseable, DataTreeChangeListener, GovernanceProvider { private static final Logger LOG = LoggerFactory.getLogger(RemoteControlProvider.class); - private final ListenerRegistration registration; + private final Registration registration; private final ProviderDependencies dependencies; private final JsonRpcCodecFactory codecFactory; private String remoteControlUri; @@ -75,28 +75,29 @@ public final class RemoteControlProvider this.dependencies = Objects.requireNonNull(dependencies); this.codecFactory = new JsonRpcCodecFactory(dependencies.getSchemaService().getGlobalContext()); registration = dependencies.getDataBroker() - .registerDataTreeChangeListener(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, + .registerTreeChangeListener(DataTreeIdentifier.of(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Config.class)), this); } @Override - public void onDataTreeChanged(@NonNull Collection> changes) { + public void onDataTreeChanged(List> changes) { for (DataTreeModification change : changes) { final DataObjectModification root = change.getRootNode(); - final ModificationType type = root.getModificationType(); + final ModificationType type = root.modificationType(); switch (type) { case DELETE: - if (root.getDataAfter() == null || root.getDataAfter().getGovernanceRoot() == null) { + final var dataAfter = root.dataAfter(); + if (dataAfter == null || dataAfter.getGovernanceRoot() == null) { stopGovernance(); } - if (root.getDataAfter() == null || root.getDataAfter().getWhoAmI() == null) { + if (dataAfter == null || dataAfter.getWhoAmI() == null) { stopRemoteControl(); } break; case WRITE: case SUBTREE_MODIFIED: - reconfigureServices(root.getDataAfter()); + reconfigureServices(root.dataAfter()); break; default: diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/TxChain.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/TxChain.java index 38aa4287..7c4eb822 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/TxChain.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/impl/TxChain.java @@ -9,6 +9,8 @@ package org.opendaylight.jsonrpc.impl; import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; import com.google.gson.JsonElement; import java.util.Objects; import java.util.Optional; @@ -30,9 +32,9 @@ import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMTransactionChain; import org.opendaylight.mdsal.dom.api.DOMTransactionChainClosedException; -import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener; import org.opendaylight.mdsal.dom.api.DOMTransactionFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; +import org.opendaylight.yangtools.yang.common.Empty; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,9 +44,10 @@ import org.slf4j.LoggerFactory; */ public class TxChain extends AbstractJsonRPCComponent implements DOMTransactionChain, TransactionListener { private static final Logger LOG = LoggerFactory.getLogger(TxChain.class); - private final DOMTransactionFactory dataBroker; - private final DOMTransactionChainListener listener; + + private final @NonNull SettableFuture future = SettableFuture.create(); private final ReadWriteLock rwLock = new ReentrantReadWriteLock(); + private final DOMTransactionFactory dataBroker; /** * Transaction created by this chain that hasn't been submitted or cancelled yet. @@ -55,14 +58,18 @@ public class TxChain extends AbstractJsonRPCComponent implements DOMTransactionC @GuardedBy("rwLock") private final ConcurrentMap pendingTxs = new ConcurrentHashMap<>(); - public TxChain(@NonNull final DOMTransactionFactory dataBroker, @NonNull final DOMTransactionChainListener listener, - @NonNull TransportFactory transportFactory, + public TxChain(@NonNull final DOMTransactionFactory dataBroker, @NonNull TransportFactory transportFactory, @NonNull HierarchicalEnumMap pathMap, @NonNull JsonRpcCodecFactory codecFactory, @NonNull EffectiveModelContext schemaContext, @NonNull Peer peer) { super(schemaContext, transportFactory, pathMap, codecFactory, peer); this.dataBroker = Objects.requireNonNull(dataBroker); - this.listener = Objects.requireNonNull(listener); + } + + + @Override + public ListenableFuture future() { + return future; } @Override @@ -116,7 +123,7 @@ public class TxChain extends AbstractJsonRPCComponent implements DOMTransactionC private void notifyChainListenerSuccess() { if (closed && successful && pendingTxs.isEmpty()) { - listener.onTransactionChainSuccessful(this); + future.set(Empty.value()); } } @@ -156,7 +163,7 @@ public class TxChain extends AbstractJsonRPCComponent implements DOMTransactionC if (currentTransaction != null) { currentTransaction.cancel(); } - listener.onTransactionChainFailed(this, tx, failure); + future.setException(failure); } @Override diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/model/StringYangTextSchemaSource.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/model/StringYangTextSchemaSource.java deleted file mode 100644 index 33a0b5ca..00000000 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/model/StringYangTextSchemaSource.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2019 Lumina Networks, Inc. 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.jsonrpc.model; - -import com.google.common.base.MoreObjects; -import com.google.common.base.MoreObjects.ToStringHelper; -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.util.Optional; -import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; - -/** - * Simple wrapper around {@link YangTextSchemaSource}. - * - * @author Richard Kosegi - * @since Jan 29, 2019 - */ -public final class StringYangTextSchemaSource extends YangTextSchemaSource { - private final String content; - - public StringYangTextSchemaSource(String module, String moduleContent) { - super(new SourceIdentifier(module)); - this.content = moduleContent; - } - - @Override - protected ToStringHelper addToStringAttributes(ToStringHelper toStringHelper) { - return MoreObjects.toStringHelper(getClass()); - } - - @Override - public Reader openStream() throws IOException { - return new StringReader(content); - } - - @Override - public Optional getSymbolicName() { - // FIXME: can we return something more reasonable? - return Optional.empty(); - } -} diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/GovernanceSchemaContextProvider.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/GovernanceSchemaContextProvider.java index fe7e6054..a9a65984 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/GovernanceSchemaContextProvider.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/GovernanceSchemaContextProvider.java @@ -12,6 +12,7 @@ import static org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransf import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Queues; import com.google.common.io.CharSource; import java.io.IOException; @@ -26,15 +27,16 @@ import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.jsonrpc.model.ModuleInfo; import org.opendaylight.jsonrpc.model.RemoteGovernance; import org.opendaylight.jsonrpc.model.SchemaContextProvider; -import org.opendaylight.jsonrpc.model.StringYangTextSchemaSource; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; -import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextProvider; -import org.opendaylight.yangtools.yang.model.api.ModuleImport; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.api.source.SourceDependency; +import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier; +import org.opendaylight.yangtools.yang.model.spi.source.DelegatedYangTextSource; +import org.opendaylight.yangtools.yang.model.spi.source.SourceInfo; +import org.opendaylight.yangtools.yang.model.spi.source.StringYangTextSource; import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException; import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors; -import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo; +import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangIRSourceInfoExtractor; import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.BuildAction; @@ -43,7 +45,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Implementation of {@link EffectiveModelContextProvider} which uses {@link RemoteGovernance} to obtain models + * Implementation of {@link SchemaContextProvider} which uses {@link RemoteGovernance} to obtain models * from.Implementation is fail-fast, so any missing model will cause error. Models dependencies are resolved * recursively first. * @@ -55,16 +57,20 @@ public class GovernanceSchemaContextProvider implements SchemaContextProvider { private static final Duration CACHE_TTL = Duration.ofMinutes(10L); private final YangXPathParserFactory xpathParserFactory; // cache to speed-up module import lookups - private final LoadingCache> moduleImportCache = CacheBuilder.newBuilder() + private final LoadingCache> moduleImportCache = CacheBuilder.newBuilder() .expireAfterWrite(CACHE_TTL) - .build(new CacheLoader>() { + .build(new CacheLoader<>() { @Override - public Set load(ModuleInfo key) throws Exception { + public Set load(ModuleInfo key) throws Exception { LOG.trace("Resolving imports of module '{}'", key); final String content = sourceCache.getUnchecked(key); - return YangModelDependencyInfo - .forIR(transformText(new StringYangTextSchemaSource(key.getModule(), content))) - .getDependencies(); + + final SourceInfo info = YangIRSourceInfoExtractor.forIR(transformText( + new StringYangTextSource(new SourceIdentifier(key.getModule()), content))); + return ImmutableSet.builder() + .addAll(info.imports()) + .addAll(info.includes()) + .build(); } }); @@ -128,7 +134,7 @@ public class GovernanceSchemaContextProvider implements SchemaContextProvider { final ModuleInfo mi = toResolve.pop(); final Set imports = moduleImportCache.getUnchecked(mi) .stream() - .map(imp -> new ModuleInfo(imp.getModuleName().getLocalName(), null)) + .map(imp -> new ModuleInfo(imp.name().getLocalName(), null)) .filter(m -> !resolved.contains(m)) .filter(m -> !toResolve.contains(m)) .collect(Collectors.toSet()); @@ -147,8 +153,8 @@ public class GovernanceSchemaContextProvider implements SchemaContextProvider { private static void addSourceToReactor(BuildAction reactor, String name, String yangSource) { try { - reactor.addSource(YangStatementStreamSource.create(YangTextSchemaSource.delegateForCharSource( - name + ".yang", CharSource.wrap(yangSource)))); + reactor.addSource(YangStatementStreamSource.create(new DelegatedYangTextSource( + new SourceIdentifier(name), CharSource.wrap(yangSource)))); } catch (YangSyntaxErrorException | IOException e) { throw new IllegalStateException("Unable to add source of '" + name + "' into reactor", e); } diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/InbandModelsSchemaContextProvider.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/InbandModelsSchemaContextProvider.java index 0317ffa4..d12fbebd 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/InbandModelsSchemaContextProvider.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/InbandModelsSchemaContextProvider.java @@ -17,7 +17,8 @@ import org.opendaylight.jsonrpc.model.SchemaContextProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.peer.RpcEndpoints; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier; +import org.opendaylight.yangtools.yang.model.spi.source.DelegatedYangTextSource; import org.opendaylight.yangtools.yang.parser.api.YangSyntaxErrorException; import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors; import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource; @@ -66,8 +67,8 @@ public final class InbandModelsSchemaContextProvider implements SchemaContextPro requester.getModules().forEach(m -> { try { - reactor.addSource(YangStatementStreamSource.create(YangTextSchemaSource.delegateForCharSource( - m.getName() + ".yang", CharSource.wrap(m.getContent())))); + reactor.addSource(YangStatementStreamSource.create(new DelegatedYangTextSource( + new SourceIdentifier(m.getName()), CharSource.wrap(m.getContent())))); } catch (YangSyntaxErrorException | IOException e) { throw new IllegalStateException("Failed to add YANG source for " + m.getName(), e); } diff --git a/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/MappedPeerContext.java b/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/MappedPeerContext.java index 59c332a8..9a84fcbd 100644 --- a/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/MappedPeerContext.java +++ b/provider/common/src/main/java/org/opendaylight/jsonrpc/provider/common/MappedPeerContext.java @@ -49,8 +49,6 @@ import org.opendaylight.yangtools.yang.model.api.Module; /** * Context of mapped {@link Peer}. * - *

- * * @author Richard Kosegi */ public class MappedPeerContext extends AbstractPeerContext { diff --git a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/AbstractJsonRpcTest.java b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/AbstractJsonRpcTest.java index 12c2c0f1..44a930bb 100644 --- a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/AbstractJsonRpcTest.java +++ b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/AbstractJsonRpcTest.java @@ -49,18 +49,18 @@ import org.slf4j.LoggerFactory; */ public abstract class AbstractJsonRpcTest extends AbstractDataBrokerTest { protected static final Logger LOG = LoggerFactory.getLogger(AbstractJsonRpcTest.class); - private ConcurrentDataBrokerTestCustomizer testCustomizer; private final DOMMountPointService domMountPointService = new DOMMountPointServiceImpl(); private final DOMNotificationRouter notificationRouter = new DOMNotificationRouter(4); private DataBroker dataBroker; private DOMDataBroker domBroker; private DOMRpcRouter rpcRouter; + protected ConcurrentDataBrokerTestCustomizer testCustomizer; protected EffectiveModelContext schemaContext; protected JsonRpcCodecFactory codecFactory; @Rule public TestName nameRule = new TestName(); private BindingCodecContext bnnc; - private @NonNull BindingRuntimeContext runtimeContext = BindingRuntimeHelpers.createRuntimeContext(); + protected @NonNull BindingRuntimeContext runtimeContext = BindingRuntimeHelpers.createRuntimeContext(); @Override protected void setupWithSchema(final EffectiveModelContext context) { diff --git a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCNotificationServiceTest.java b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCNotificationServiceTest.java index c66c2be8..411b4195 100644 --- a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCNotificationServiceTest.java +++ b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCNotificationServiceTest.java @@ -41,7 +41,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types. import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.config.ConfiguredEndpointsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.peer.NotificationEndpointsBuilder; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.util.BindingMap; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.Revision; @@ -96,7 +96,7 @@ public class JsonRPCNotificationServiceTest extends AbstractJsonRpcTest { final int listeners = 10; final int count = 10; final CountDownLatch cl = new CountDownLatch(listeners * count); - final Set> regs = new HashSet<>(); + final Set regs = new HashSet<>(); for (int i = 0; i < listeners; i++) { regs.add(svc.registerNotificationListener((DOMNotificationListener) notification -> { LOG.info("Received notification : {}", notification); @@ -108,7 +108,7 @@ public class JsonRPCNotificationServiceTest extends AbstractJsonRpcTest { pubSession.publish("notification1", new int[] { 1, 2 }); } assertTrue(cl.await(5, TimeUnit.SECONDS)); - regs.stream().forEach(ListenerRegistration::close); + regs.stream().forEach(Registration::close); } @Test diff --git a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCTE2ETest.java b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCTE2ETest.java index ef6eeb33..bcc1b50c 100644 --- a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCTE2ETest.java +++ b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCTE2ETest.java @@ -16,6 +16,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import com.google.common.util.concurrent.FutureCallback; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import java.net.URISyntaxException; @@ -43,12 +44,11 @@ import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction; import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction; -import org.opendaylight.mdsal.dom.api.DOMDataTreeTransaction; import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.mdsal.dom.api.DOMTransactionChain; -import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener; +import org.opendaylight.yangtools.yang.common.Empty; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -141,18 +141,7 @@ public class JsonRPCTE2ETest extends AbstractJsonRpcTest { */ @Test(expected = IllegalStateException.class) public void testUnfinishedTxChain() throws InterruptedException { - final DOMTransactionChain chain = jrbroker.createTransactionChain(new DOMTransactionChainListener() { - @Override - public void onTransactionChainSuccessful(DOMTransactionChain chain) { - // NOOP - } - - @Override - public void onTransactionChainFailed(DOMTransactionChain chain, DOMDataTreeTransaction transaction, - Throwable cause) { - // NOOP - } - }); + final DOMTransactionChain chain = jrbroker.createTransactionChain(); chain.newWriteOnlyTransaction(); chain.newWriteOnlyTransaction(); } @@ -161,24 +150,25 @@ public class JsonRPCTE2ETest extends AbstractJsonRpcTest { public void testTxChain() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final NodeResult e = TestUtils.getMockTopologyAsDom(getCodec()); - final DOMTransactionChain chain = jrbroker.createTransactionChain(new DOMTransactionChainListener() { - @Override - public void onTransactionChainSuccessful(DOMTransactionChain chain) { - latch.countDown(); - } - - @Override - public void onTransactionChainFailed(DOMTransactionChain chain, DOMDataTreeTransaction transaction, - Throwable cause) { - } - }); - final DOMDataTreeWriteTransaction tx1 = chain.newWriteOnlyTransaction(); - tx1.put(LogicalDatastoreType.OPERATIONAL, e.path(), e.node()); - tx1.commit(); - final DOMDataTreeWriteTransaction tx2 = chain.newWriteOnlyTransaction(); - tx2.put(LogicalDatastoreType.OPERATIONAL, e.path(), e.node()); - tx2.commit(); - chain.close(); + try (var chain = jrbroker.createTransactionChain()) { + chain.addCallback(new FutureCallback() { + @Override + public void onSuccess(Empty result) { + latch.countDown(); + } + + @Override + public void onFailure(Throwable cause) { + // No-op + } + }); + final DOMDataTreeWriteTransaction tx1 = chain.newWriteOnlyTransaction(); + tx1.put(LogicalDatastoreType.OPERATIONAL, e.path(), e.node()); + tx1.commit(); + final DOMDataTreeWriteTransaction tx2 = chain.newWriteOnlyTransaction(); + tx2.put(LogicalDatastoreType.OPERATIONAL, e.path(), e.node()); + tx2.commit(); + } assertTrue(latch.await(10, TimeUnit.SECONDS)); } diff --git a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCTxTest.java b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCTxTest.java index b7c6682c..db83f63f 100644 --- a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCTxTest.java +++ b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCTxTest.java @@ -116,7 +116,7 @@ public class JsonRPCTxTest extends AbstractJsonRpcTest { final NormalizedNode nn = fopt.get(5, TimeUnit.SECONDS).orElseThrow(); LOG.info("Read output : {}", nn); - assertEquals(NetworkTopology.QNAME.getNamespace(), nn.getIdentifier().getNodeType().getNamespace()); + assertEquals(NetworkTopology.QNAME.getNamespace(), nn.name().getNodeType().getNamespace()); assertNotNull(nn.body()); } @@ -133,7 +133,7 @@ public class JsonRPCTxTest extends AbstractJsonRpcTest { @Test public void testReadEmpty() throws InterruptedException, ExecutionException { doReturn(null).when(om).read(any()); - assertFalse(trx.read(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.empty()).get().isPresent()); + assertFalse(trx.read(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.of()).get().isPresent()); } @Test diff --git a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCtoRPCBridgeTest.java b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCtoRPCBridgeTest.java index 0697e324..e7498f1b 100644 --- a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCtoRPCBridgeTest.java +++ b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/JsonRPCtoRPCBridgeTest.java @@ -127,8 +127,8 @@ public class JsonRPCtoRPCBridgeTest extends AbstractJsonRpcTest { QName path = rpcPath(mod, "simple-method"); DOMRpcResult result = bridge.invokeRpc(path, rpcDef).get(); LOG.info("Simple RPC result : {}", result); - assertTrue(result.getErrors().isEmpty()); - assertNotNull(result.getResult()); + assertTrue(result.errors().isEmpty()); + assertNotNull(result.value()); } /** @@ -146,7 +146,7 @@ public class JsonRPCtoRPCBridgeTest extends AbstractJsonRpcTest { final DOMRpcResult result = bridge.invokeRpc(path, rpcDef).get(); LOG.info("DOM RPC result : {}", result); - assertTrue(result.getErrors().isEmpty()); + assertTrue(result.errors().isEmpty()); // BI => BA final MultiplyLlOutput out = extractRpcOutput(result, MultiplyLlOutput.class, "multiply-ll", mod); @@ -195,7 +195,7 @@ public class JsonRPCtoRPCBridgeTest extends AbstractJsonRpcTest { final DOMRpcResult result = bridge.invokeRpc(path, rpcDef).get(); logResult(result); - assertTrue(result.getErrors().isEmpty()); + assertTrue(result.errors().isEmpty()); // BI => BA final MultiplyListOutput out = extractRpcOutput(result, MultiplyListOutput.class, "multiply-list", mod); @@ -242,7 +242,7 @@ public class JsonRPCtoRPCBridgeTest extends AbstractJsonRpcTest { ContainerNode rpcDef = ImmutableNodes.containerNode(constructRpcQname(mod, "error-method")); DOMRpcResult result = bridge.invokeRpc(rpcPath(mod, "error-method"), rpcDef).get(); logResult(result); - assertFalse(result.getErrors().isEmpty()); + assertFalse(result.errors().isEmpty()); } @Test // (timeout = 15_000) @@ -251,16 +251,16 @@ public class JsonRPCtoRPCBridgeTest extends AbstractJsonRpcTest { final ContainerNode rpcDef = ImmutableNodes.containerNode(constructRpcQname(mod, "removeCoffeePot")); DOMRpcResult result = bridge.invokeRpc(path, rpcDef).get(); logResult(result); - assertTrue(result.getErrors().isEmpty()); - assertNotNull(result.getResult()); + assertTrue(result.errors().isEmpty()); + assertNotNull(result.value()); } /////////////////////////////////////////////////////////////////////////// // Helper methods /////////////////////////////////////////////////////////////////////////// private static void logResult(DOMRpcResult result) { - LOG.info("Result : {}", result.getResult()); - LOG.info("Errors : {}", result.getErrors()); + LOG.info("Result : {}", result.value()); + LOG.info("Errors : {}", result.errors()); } private ContainerNode prepareRpcInput(T dataObject) { @@ -270,7 +270,7 @@ public class JsonRPCtoRPCBridgeTest extends AbstractJsonRpcTest { @SuppressWarnings("unchecked") private T extractRpcOutput(DOMRpcResult result, Class outputType, String rpcName, Module module) { Absolute path2 = Absolute.of(constructRpcQname(module, rpcName), constructRpcQname(module, "output")); - return (T) getCodec().fromNormalizedNodeRpcData(path2, (ContainerNode) result.getResult()); + return (T) getCodec().fromNormalizedNodeRpcData(path2, (ContainerNode) result.value()); } diff --git a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteControlTest.java b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteControlTest.java index c0ce3fb7..34037002 100644 --- a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteControlTest.java +++ b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteControlTest.java @@ -84,8 +84,8 @@ public class RemoteControlTest extends AbstractJsonRpcTest { public void setUp() throws Exception { transportFactory = new DefaultTransportFactory(); codecFactory = new JsonRpcCodecFactory(schemaContext); - ctrl = new RemoteControl(getDomBroker(), schemaContext, transportFactory, getDOMNotificationRouter(), - getDOMRpcRouter().getRpcService(), codecFactory); + ctrl = new RemoteControl(getDomBroker(), schemaContext, transportFactory, + getDOMNotificationRouter().notificationPublishService(), getDOMRpcRouter().rpcService(), codecFactory); logTestName("START"); } diff --git a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteNotificationPublisherTest.java b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteNotificationPublisherTest.java index 0aa1272b..ce707dc6 100644 --- a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteNotificationPublisherTest.java +++ b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteNotificationPublisherTest.java @@ -22,7 +22,7 @@ import org.opendaylight.jsonrpc.impl.RemoteControl; import org.opendaylight.jsonrpc.model.RemoteNotificationPublisher; import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.mdsal.dom.api.DOMNotificationListener; -import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; @@ -39,24 +39,25 @@ public class RemoteNotificationPublisherTest extends AbstractJsonRpcTest { private static final Logger LOG = LoggerFactory.getLogger(RemoteNotificationPublisherTest.class); private DefaultTransportFactory transportFactory; private RemoteControl ctrl; - private ListenerRegistration reg; + private Registration reg; private CountDownLatch latch; @Before public void setUp() { transportFactory = new DefaultTransportFactory(); - ctrl = new RemoteControl(getDomBroker(), schemaContext, transportFactory, getDOMNotificationRouter(), - getDOMRpcRouter().getRpcService(), codecFactory); + ctrl = new RemoteControl(getDomBroker(), schemaContext, transportFactory, + getDOMNotificationRouter().notificationPublishService(), getDOMRpcRouter().rpcService(), codecFactory); NotificationDefinition path = findNode(schemaContext, "test-model-notification:notification1", Module::getNotifications).orElseThrow(); latch = new CountDownLatch(1); - reg = getDOMNotificationRouter().registerNotificationListener(new DOMNotificationListener() { - @Override - public void onNotification(@NonNull DOMNotification notification) { - LOG.info("Got notification : {}", notification); - latch.countDown(); - } - }, Absolute.of(path.getQName())); + reg = getDOMNotificationRouter().notificationService() + .registerNotificationListener(new DOMNotificationListener() { + @Override + public void onNotification(@NonNull DOMNotification notification) { + LOG.info("Got notification : {}", notification); + latch.countDown(); + } + }, Absolute.of(path.getQName())); logTestName("START"); } diff --git a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteRpcInvokerTest.java b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteRpcInvokerTest.java index 93b5069d..7ae3b855 100644 --- a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteRpcInvokerTest.java +++ b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/RemoteRpcInvokerTest.java @@ -9,6 +9,7 @@ package org.opendaylight.jsonrpc.provider.common; import static org.junit.Assert.assertNotNull; +import com.google.common.collect.ImmutableClassToInstanceMap; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import org.junit.After; @@ -18,12 +19,21 @@ import org.opendaylight.jsonrpc.bus.messagelib.DefaultTransportFactory; import org.opendaylight.jsonrpc.dom.codec.JsonRpcCodecFactory; import org.opendaylight.jsonrpc.impl.RemoteControl; import org.opendaylight.jsonrpc.model.RemoteRpcInvoker; -import org.opendaylight.jsonrpc.test.TestModelServiceImpl; +import org.opendaylight.jsonrpc.test.TestErrorMethod; +import org.opendaylight.jsonrpc.test.TestFactorial; +import org.opendaylight.jsonrpc.test.TestMultiplyList; +import org.opendaylight.jsonrpc.test.TestRemoveCoffeePot; +import org.opendaylight.jsonrpc.test.TestSimpleMethod; import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMRpcProviderServiceAdapter; import org.opendaylight.mdsal.binding.dom.adapter.ConstantAdapterContext; import org.opendaylight.mdsal.binding.dom.codec.impl.BindingCodecContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.TestModelRpcService; -import org.opendaylight.yangtools.concepts.ObjectRegistration; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.ErrorMethod; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.Factorial; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePot; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.SimpleMethod; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.Rpc; /** * Test for {@link RemoteRpcInvoker} part of {@link RemoteControl}. @@ -33,7 +43,7 @@ import org.opendaylight.yangtools.concepts.ObjectRegistration; */ public class RemoteRpcInvokerTest extends AbstractJsonRpcTest { private DefaultTransportFactory transportFactory; - private ObjectRegistration rpcReg; + private Registration rpcReg; private RemoteControl ctrl; private JsonRpcCodecFactory codecFactory; @@ -41,13 +51,19 @@ public class RemoteRpcInvokerTest extends AbstractJsonRpcTest { public void setUp() throws Exception { final BindingDOMRpcProviderServiceAdapter rpcAdapter = new BindingDOMRpcProviderServiceAdapter( new ConstantAdapterContext(new BindingCodecContext(getBindingRuntimeContext())), - getDOMRpcRouter().getRpcProviderService()); - rpcReg = rpcAdapter.registerRpcImplementation(TestModelRpcService.class, new TestModelServiceImpl()); - getDOMRpcRouter().onModelContextUpdated(schemaContext); + getDOMRpcRouter().rpcProviderService()); + rpcReg = rpcAdapter.registerRpcImplementations(ImmutableClassToInstanceMap.>builder() + .put(ErrorMethod.class, new TestErrorMethod()) + .put(Factorial.class, new TestFactorial()) + .put(MultiplyList.class, new TestMultiplyList()) + .put(RemoveCoffeePot.class, new TestRemoveCoffeePot()) + .put(SimpleMethod.class, new TestSimpleMethod()) + .build()); + testCustomizer.updateSchema(runtimeContext); codecFactory = new JsonRpcCodecFactory(schemaContext); transportFactory = new DefaultTransportFactory(); - ctrl = new RemoteControl(getDomBroker(), schemaContext, transportFactory, getDOMNotificationRouter(), - getDOMRpcRouter().getRpcService(), codecFactory); + ctrl = new RemoteControl(getDomBroker(), schemaContext, transportFactory, + getDOMNotificationRouter().notificationPublishService(), getDOMRpcRouter().rpcService(), codecFactory); logTestName("START"); } diff --git a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/TxChainTest.java b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/TxChainTest.java index 12ccda2b..1a4f7af8 100644 --- a/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/TxChainTest.java +++ b/provider/common/src/test/java/org/opendaylight/jsonrpc/provider/common/TxChainTest.java @@ -7,10 +7,12 @@ */ package org.opendaylight.jsonrpc.provider.common; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.google.common.util.concurrent.FutureCallback; import com.google.gson.JsonElement; import org.junit.Before; import org.junit.Test; @@ -27,9 +29,9 @@ import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction; import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction; import org.opendaylight.mdsal.dom.api.DOMTransactionChainClosedException; -import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.config.ConfiguredEndpointsBuilder; +import org.opendaylight.yangtools.yang.common.Empty; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; public class TxChainTest { @@ -45,7 +47,7 @@ public class TxChainTest { @Mock private DOMDataBroker broker; @Mock - private DOMTransactionChainListener listener; + private FutureCallback listener; @Mock private DOMDataTreeReadTransaction readOnlyTx; private TxChain chain; @@ -68,7 +70,8 @@ public class TxChainTest { when(broker.newReadWriteTransaction()).thenReturn(writeOnlyTx1) .thenReturn(writeOnlyTx2) .thenReturn(writeOnlyTx3); - chain = new TxChain(broker, listener, transportFactory, pathMap, codec, schemaContext, DEVICE); + chain = new TxChain(broker, transportFactory, pathMap, codec, schemaContext, DEVICE); + chain.addCallback(listener); } @Test() @@ -106,7 +109,7 @@ public class TxChainTest { @Test(expected = DOMTransactionChainClosedException.class) public void testCloseAfterFinished() throws Exception { chain.close(); - verify(listener).onTransactionChainSuccessful(chain); + verify(listener).onSuccess(any()); chain.newReadOnlyTransaction(); } @@ -116,7 +119,7 @@ public class TxChainTest { writeTx.commit().get(); final TransactionCommitFailedException cause = new TransactionCommitFailedException("fail"); chain.onFailure(writeOnlyTx1, cause); - verify(listener).onTransactionChainFailed(chain, writeOnlyTx1, cause); + verify(listener).onFailure(cause); } @Test @@ -124,7 +127,7 @@ public class TxChainTest { final DOMDataTreeWriteTransaction writeTx = chain.newWriteOnlyTransaction(); chain.close(); writeTx.commit().get(); - verify(listener).onTransactionChainSuccessful(chain); + verify(listener).onSuccess(any()); } @Test @@ -161,7 +164,7 @@ public class TxChainTest { // close chain chain.close(); - verify(listener).onTransactionChainSuccessful(chain); + verify(listener).onSuccess(any()); } @Test @@ -190,8 +193,8 @@ public class TxChainTest { // 2nd transaction success chain.onSuccess(writeOnlyTx2); - verify(listener).onTransactionChainFailed(chain, writeOnlyTx1, cause1); + verify(listener).onFailure(cause1); // 1 transaction failed, onTransactionChainSuccessful must not be called - verify(listener, never()).onTransactionChainSuccessful(chain); + verify(listener, never()).onSuccess(any()); } } diff --git a/provider/pom.xml b/provider/pom.xml index bddf5812..1145a8db 100644 --- a/provider/pom.xml +++ b/provider/pom.xml @@ -114,7 +114,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.mdsal - mdsal-singleton-common-api + mdsal-singleton-api org.opendaylight.jsonrpc.bus diff --git a/provider/single/pom.xml b/provider/single/pom.xml index 9280f86b..32a993ce 100644 --- a/provider/single/pom.xml +++ b/provider/single/pom.xml @@ -79,7 +79,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.mdsal - mdsal-singleton-common-api + mdsal-singleton-api org.opendaylight.jsonrpc.bus diff --git a/provider/single/src/main/java/org/opendaylight/jsonrpc/provider/single/JsonRPCProvider.java b/provider/single/src/main/java/org/opendaylight/jsonrpc/provider/single/JsonRPCProvider.java index ceb7743d..735ea31d 100644 --- a/provider/single/src/main/java/org/opendaylight/jsonrpc/provider/single/JsonRPCProvider.java +++ b/provider/single/src/main/java/org/opendaylight/jsonrpc/provider/single/JsonRPCProvider.java @@ -7,7 +7,9 @@ */ package org.opendaylight.jsonrpc.provider.single; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; +import com.google.common.collect.ImmutableClassToInstanceMap; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import java.net.URISyntaxException; @@ -31,7 +33,6 @@ import org.opendaylight.jsonrpc.provider.common.AbstractPeerContext; import org.opendaylight.jsonrpc.provider.common.FailedPeerContext; import org.opendaylight.jsonrpc.provider.common.MappedPeerContext; import org.opendaylight.jsonrpc.provider.common.ProviderDependencies; -import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; import org.opendaylight.mdsal.binding.api.ReadTransaction; @@ -44,16 +45,18 @@ import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.mdsal.dom.api.DOMSchemaService; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Config; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceRefresh; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceRefreshInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceRefreshOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceRefreshOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceReload; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceReloadInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceReloadOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.ForceReloadOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.JsonrpcService; import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.rev161201.Peer; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.Rpc; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; @@ -65,12 +68,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component(service = { }) -public final class JsonRPCProvider implements JsonrpcService, AutoCloseable { +public final class JsonRPCProvider implements AutoCloseable { private static final String ME = "JSON RPC Provider"; private static final Logger LOG = LoggerFactory.getLogger(JsonRPCProvider.class); private static final InstanceIdentifier GLOBAL_CFG_II = InstanceIdentifier.create(Config.class); private static final DataTreeIdentifier CFG_DTI = - DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, GLOBAL_CFG_II); + DataTreeIdentifier.of(LogicalDatastoreType.CONFIGURATION, GLOBAL_CFG_II); private final Map peerState = new ConcurrentHashMap<>(); private final ReentrantReadWriteLock changeLock = new ReentrantReadWriteLock(); private final ProviderDependencies dependencies; @@ -88,14 +91,16 @@ public final class JsonRPCProvider implements JsonrpcService, AutoCloseable { @Reference TransportFactory transportFactory, @Reference GovernanceProvider governance) { this(new ProviderDependencies(transportFactory, dataBroker, domMountPointService, domDataBroker, schemaService, domNotificationPublishService, domRpcService, yangXPathParserFactory), governance); - rpcReg = rpcProviderService.registerRpcImplementation(JsonrpcService.class, this); + rpcReg = rpcProviderService.registerRpcImplementations(ImmutableClassToInstanceMap.>builder() + .put(ForceRefresh.class, this::forceRefresh) + .put(ForceReload.class, this::forceReload) + .build()); } public JsonRPCProvider(ProviderDependencies dependencies, GovernanceProvider governance) { this.dependencies = Objects.requireNonNull(dependencies); this.governance = Objects.requireNonNull(governance); - dtclReg = dependencies.getDataBroker().registerDataTreeChangeListener(CFG_DTI, - (ClusteredDataTreeChangeListener) changes -> processNotification()); + dtclReg = dependencies.getDataBroker().registerTreeChangeListener(CFG_DTI, changes -> processNotification()); processNotification(); } @@ -245,8 +250,7 @@ public final class JsonRPCProvider implements JsonrpcService, AutoCloseable { /* * JSON Rpc Force refresh */ - @Override - public ListenableFuture> forceRefresh(ForceRefreshInput input) { + private ListenableFuture> forceRefresh(ForceRefreshInput input) { LOG.debug("Refreshing json rpc state"); return Futures.immediateFuture(RpcResultBuilder .success(new ForceRefreshOutputBuilder().setResult(processNotification()).build()) @@ -256,8 +260,8 @@ public final class JsonRPCProvider implements JsonrpcService, AutoCloseable { /* * JSON Rpc Force reload */ - @Override - public ListenableFuture> forceReload(ForceReloadInput input) { + @VisibleForTesting + ListenableFuture> forceReload(ForceReloadInput input) { final ForceReloadOutputBuilder outputBuilder = new ForceReloadOutputBuilder(); LOG.debug("Remounting all json rpc peers"); boolean result = true; diff --git a/provider/single/src/test/java/org/opendaylight/jsonrpc/provider/single/JsonRPCProviderTest.java b/provider/single/src/test/java/org/opendaylight/jsonrpc/provider/single/JsonRPCProviderTest.java index 5c0f0988..377db997 100644 --- a/provider/single/src/test/java/org/opendaylight/jsonrpc/provider/single/JsonRPCProviderTest.java +++ b/provider/single/src/test/java/org/opendaylight/jsonrpc/provider/single/JsonRPCProviderTest.java @@ -87,7 +87,7 @@ public class JsonRPCProviderTest extends AbstractJsonRpcTest { .build()); ProviderDependencies deps = new ProviderDependencies(new MockTransportFactory(tf), getDataBroker(), getDOMMountPointService(), getDomBroker(), getSchemaService(), - getDOMNotificationRouter(), getDOMRpcRouter().getRpcService(), + getDOMNotificationRouter().notificationPublishService(), getDOMRpcRouter().rpcService(), ServiceLoader.load(YangXPathParserFactory.class).findFirst().orElseThrow()); provider = new JsonRPCProvider(deps, () -> Optional.of(GOVERNANCE_MOCK)); logTestName("START"); diff --git a/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestErrorMethod.java b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestErrorMethod.java new file mode 100644 index 00000000..56142465 --- /dev/null +++ b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestErrorMethod.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018 Lumina Networks, Inc. All rights reserved. + * Copyright (c) 2024 PANTHEON.tech, s.r.o. + * + * 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.jsonrpc.test; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.ErrorMethod; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.ErrorMethodInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.ErrorMethodOutput; +import org.opendaylight.yangtools.yang.common.ErrorType; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; + +public class TestErrorMethod implements ErrorMethod { + @Override + public ListenableFuture> invoke(ErrorMethodInput input) { + return RpcResultBuilder.failed().withError(ErrorType.RPC, "Ha!").buildFuture(); + } +} diff --git a/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestFactorial.java b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestFactorial.java new file mode 100644 index 00000000..2a958a1f --- /dev/null +++ b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestFactorial.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 Lumina Networks, Inc. All rights reserved. + * Copyright (c) 2024 PANTHEON.tech, s.r.o. + * + * 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.jsonrpc.test; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.Factorial; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.FactorialInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.FactorialOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.FactorialOutputBuilder; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.opendaylight.yangtools.yang.common.Uint32; + +public class TestFactorial implements Factorial { + @Override + public ListenableFuture> invoke(FactorialInput input) { + int ret = 2; + for (int i = 3; i <= input.getInNumber().intValue(); i++) { + ret *= i; + } + return RpcResultBuilder.success(new FactorialOutputBuilder().setOutNumber(Uint32.valueOf(ret)).build()) + .buildFuture(); + } +} diff --git a/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestModelServiceImpl.java b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestModelServiceImpl.java deleted file mode 100644 index fc4d128a..00000000 --- a/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestModelServiceImpl.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2018 Lumina Networks, Inc. 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.jsonrpc.test; - -import static com.google.common.util.concurrent.Futures.immediateFuture; -import static org.opendaylight.yangtools.yang.common.RpcResultBuilder.success; - -import com.google.common.util.concurrent.ListenableFuture; -import java.util.AbstractMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.stream.Collectors; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.base.rev201014.numbers.list.Numbers; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.base.rev201014.numbers.list.NumbersBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.base.rev201014.numbers.list.NumbersKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.Coffee; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.ErrorMethodInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.ErrorMethodOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.FactorialInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.FactorialOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.FactorialOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.GetAllNumbersInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.GetAllNumbersOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.GetAnyXmlInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.GetAnyXmlOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MethodWithAnyxmlInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MethodWithAnyxmlOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyListInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyListOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyListOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyLlInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyLlOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePotInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePotOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePotOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.SimpleMethodInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.SimpleMethodOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.TestModelRpcService; -import org.opendaylight.yangtools.yang.common.ErrorType; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.common.RpcResultBuilder; -import org.opendaylight.yangtools.yang.common.Uint32; - -public class TestModelServiceImpl implements TestModelRpcService { - - @Override - public ListenableFuture> multiplyList(MultiplyListInput input) { - final short multiplier = input.getMultiplier(); - final Map map = Optional.ofNullable(input.getNumbers()) - .orElse(Map.of()) - .entrySet() - .stream() - .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), - new NumbersBuilder().setNum(e.getValue().getNum() * multiplier).build())) - .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); - return immediateFuture(success(new MultiplyListOutputBuilder().setNumbers(map).build()).build()); - } - - @Override - public ListenableFuture> factorial(FactorialInput input) { - int ret = 2; - for (int i = 3; i <= input.getInNumber().intValue(); i++) { - ret *= i; - } - return immediateFuture(success(new FactorialOutputBuilder().setOutNumber(Uint32.valueOf(ret)).build()).build()); - } - - @Override - public ListenableFuture> getAllNumbers(GetAllNumbersInput input) { - // NOOP - return null; - } - - @Override - public ListenableFuture> getAnyXml(GetAnyXmlInput input) { - // NOOP - return null; - } - - @Override - public ListenableFuture> multiplyLl(MultiplyLlInput input) { - // NOOP - return null; - } - - @Override - public ListenableFuture> removeCoffeePot(RemoveCoffeePotInput input) { - return immediateFuture(success( - new RemoveCoffeePotOutputBuilder().setCupsBrewed(Uint32.valueOf(6)).setDrink(Coffee.VALUE).build()) - .build()); - } - - @Override - public ListenableFuture> errorMethod(ErrorMethodInput input) { - return immediateFuture(RpcResultBuilder.failed().withError(ErrorType.RPC, "Ha!").build()); - } - - @Override - public ListenableFuture> methodWithAnyxml(MethodWithAnyxmlInput input) { - // NOOP - return null; - } - - @Override - public ListenableFuture> simpleMethod(SimpleMethodInput input) { - return immediateFuture(RpcResultBuilder.success().build()); - } -} diff --git a/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestMultiplyList.java b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestMultiplyList.java new file mode 100644 index 00000000..b0c95c05 --- /dev/null +++ b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestMultiplyList.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018 Lumina Networks, Inc. All rights reserved. + * Copyright (c) 2024 PANTHEON.tech, s.r.o. + * + * 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.jsonrpc.test; + + +import com.google.common.util.concurrent.ListenableFuture; +import java.util.AbstractMap; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.base.rev201014.numbers.list.NumbersBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyListInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyListOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.MultiplyListOutputBuilder; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; + +public class TestMultiplyList implements MultiplyList { + @Override + public ListenableFuture> invoke(MultiplyListInput input) { + final short multiplier = input.getMultiplier(); + final var map = input.nonnullNumbers().entrySet().stream() + .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), + new NumbersBuilder().setNum(e.getValue().getNum() * multiplier).build())) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); + return RpcResultBuilder.success(new MultiplyListOutputBuilder().setNumbers(map).build()).buildFuture(); + } +} diff --git a/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestRemoveCoffeePot.java b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestRemoveCoffeePot.java new file mode 100644 index 00000000..1becd7e6 --- /dev/null +++ b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestRemoveCoffeePot.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 Lumina Networks, Inc. All rights reserved. + * Copyright (c) 2024 PANTHEON.tech, s.r.o. + * + * 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.jsonrpc.test; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.Coffee; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePot; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePotInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePotOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.RemoveCoffeePotOutputBuilder; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.opendaylight.yangtools.yang.common.Uint32; + +public class TestRemoveCoffeePot implements RemoveCoffeePot { + @Override + public ListenableFuture> invoke(RemoveCoffeePotInput input) { + return RpcResultBuilder.success(new RemoveCoffeePotOutputBuilder() + .setCupsBrewed(Uint32.valueOf(6)) + .setDrink(Coffee.VALUE) + .build()) + .buildFuture(); + } +} diff --git a/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestSimpleMethod.java b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestSimpleMethod.java new file mode 100644 index 00000000..a52d8e9c --- /dev/null +++ b/test-model/src/test/java/org/opendaylight/jsonrpc/test/TestSimpleMethod.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018 Lumina Networks, Inc. All rights reserved. + * Copyright (c) 2024 PANTHEON.tech, s.r.o. + * + * 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.jsonrpc.test; + +import com.google.common.util.concurrent.ListenableFuture; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.SimpleMethod; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.SimpleMethodInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.jsonrpc.test.rpc.rev201014.SimpleMethodOutput; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; + +public class TestSimpleMethod implements SimpleMethod { + @Override + public ListenableFuture> invoke(SimpleMethodInput input) { + return RpcResultBuilder.success().buildFuture(); + } +} diff --git a/tools/test-tool/src/main/java/org/opendaylight/jsonrpc/tool/test/DatastoreImpl.java b/tools/test-tool/src/main/java/org/opendaylight/jsonrpc/tool/test/DatastoreImpl.java index 2241d59c..c7234db7 100644 --- a/tools/test-tool/src/main/java/org/opendaylight/jsonrpc/tool/test/DatastoreImpl.java +++ b/tools/test-tool/src/main/java/org/opendaylight/jsonrpc/tool/test/DatastoreImpl.java @@ -18,7 +18,6 @@ import java.util.ArrayList; import java.util.Map; import java.util.Set; import java.util.concurrent.Executors; -import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.jsonrpc.bus.messagelib.ResponderSession; import org.opendaylight.jsonrpc.bus.messagelib.TransportFactory; import org.opendaylight.jsonrpc.dom.codec.JsonRpcCodecFactory; @@ -35,7 +34,6 @@ import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore; import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStoreFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; -import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,27 +52,13 @@ final class DatastoreImpl extends JsonRpcDatastoreAdapter { final EffectiveModelContext schemaContext = schemaProvider .createSchemaContext(new MutablePeer().addModels(new ArrayList<>(modules))); LOG.info("Schema : {}", schemaContext); - final DOMSchemaService domSchemaService = FixedDOMSchemaService - .of(new FixedEffectiveModelContextProvider(schemaContext)); + final DOMSchemaService domSchemaService = new FixedDOMSchemaService(schemaContext); final JsonRpcCodecFactory codecFactory = new JsonRpcCodecFactory(schemaContext); final DOMDataBroker domDataBroker = createDomDataBroker(domSchemaService, MoreExecutors.listeningDecorator(Executors.newCachedThreadPool())); return new DatastoreImpl(codecFactory, domDataBroker, schemaContext, transportFactory, endpoint); } - private static class FixedEffectiveModelContextProvider implements EffectiveModelContextProvider { - private final EffectiveModelContext context; - - FixedEffectiveModelContextProvider(EffectiveModelContext context) { - this.context = context; - } - - @Override - public @NonNull EffectiveModelContext getEffectiveModelContext() { - return context; - } - } - private static DOMDataBroker createDomDataBroker(DOMSchemaService schemaService, ListeningExecutorService executor) { final Map stores = ImmutableMap diff --git a/tools/test-tool/src/main/java/org/opendaylight/jsonrpc/tool/test/GovernanceImpl.java b/tools/test-tool/src/main/java/org/opendaylight/jsonrpc/tool/test/GovernanceImpl.java index 11bdd432..ce77ec75 100644 --- a/tools/test-tool/src/main/java/org/opendaylight/jsonrpc/tool/test/GovernanceImpl.java +++ b/tools/test-tool/src/main/java/org/opendaylight/jsonrpc/tool/test/GovernanceImpl.java @@ -7,8 +7,6 @@ */ package org.opendaylight.jsonrpc.tool.test; -import static org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer.transformText; - import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -30,6 +28,7 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.opendaylight.jsonrpc.bus.messagelib.ResponderSession; import org.opendaylight.jsonrpc.bus.messagelib.TransportFactory; import org.opendaylight.jsonrpc.model.ModuleInfo; @@ -37,9 +36,8 @@ import org.opendaylight.jsonrpc.model.RemoteGovernance; import org.opendaylight.jsonrpc.model.StoreOperationArgument; import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers; import org.opendaylight.yangtools.yang.binding.YangModuleInfo; -import org.opendaylight.yangtools.yang.model.repo.api.YangIRSchemaSource; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; -import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo; +import org.opendaylight.yangtools.yang.model.spi.source.FileYangTextSource; +import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangIRSourceInfoExtractor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,12 +51,10 @@ final class GovernanceImpl implements RemoteGovernance { .build(new CacheLoader>() { @Override public Set load(Path file) throws Exception { - final YangIRSchemaSource irSource = transformText(YangTextSchemaSource.forPath(file)); - return YangModelDependencyInfo.forIR(irSource) - .getDependencies() - .stream() - .map(m -> new ModuleInfo(m.getModuleName().getLocalName(), null)) - .collect(Collectors.toSet()); + final var sourceInfo = YangIRSourceInfoExtractor.forYangText(new FileYangTextSource(file)); + return Stream.concat(sourceInfo.imports().stream(), sourceInfo.includes().stream()) + .map(m -> new ModuleInfo(m.name().getLocalName(), null)) + .collect(Collectors.toSet()); } }); -- 2.43.0 From fc49b3e7ef30b965aee8ab2e6f9d0d9fdf800f87 Mon Sep 17 00:00:00 2001 From: jenkins-releng Date: Tue, 5 Mar 2024 12:40:22 +0000 Subject: [PATCH 2/2] Release Validate --- api/pom.xml | 2 +- artifacts/pom.xml | 2 +- binding-adapter/pom.xml | 2 +- bus/api/pom.xml | 2 +- bus/config/pom.xml | 2 +- bus/examples/binding-bridge/pom.xml | 2 +- bus/examples/inband-models/pom.xml | 2 +- bus/examples/pom.xml | 2 +- bus/jsonrpc/pom.xml | 2 +- bus/messagelib/pom.xml | 2 +- bus/pom.xml | 2 +- bus/spi/pom.xml | 2 +- bus/transport-http/pom.xml | 2 +- bus/transport-zmq/pom.xml | 2 +- dom-codec/pom.xml | 2 +- features/features-jsonrpc/pom.xml | 2 +- features/odl-jsonrpc-all/pom.xml | 2 +- features/odl-jsonrpc-bus/pom.xml | 2 +- features/odl-jsonrpc-cluster/pom.xml | 2 +- features/odl-jsonrpc-provider/pom.xml | 2 +- features/pom.xml | 2 +- karaf/pom.xml | 2 +- parent/pom.xml | 2 +- pom.xml | 2 +- provider/cluster/pom.xml | 2 +- provider/common/pom.xml | 2 +- provider/pom.xml | 2 +- provider/single/pom.xml | 2 +- security/aaa/pom.xml | 2 +- security/api/pom.xml | 2 +- security/noop/pom.xml | 2 +- security/pom.xml | 2 +- security/service/pom.xml | 2 +- test-model/pom.xml | 2 +- tools/parent/pom.xml | 2 +- tools/pom.xml | 2 +- tools/test-tool/pom.xml | 2 +- 37 files changed, 37 insertions(+), 37 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index df0bfef0..e56f7070 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../parent jsonrpc-api diff --git a/artifacts/pom.xml b/artifacts/pom.xml index 4977a8a9..fb1010af 100644 --- a/artifacts/pom.xml +++ b/artifacts/pom.xml @@ -16,7 +16,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-artifacts - 1.16.0-SNAPSHOT + 1.16.0 pom JSON-RPC :: Artifacts diff --git a/binding-adapter/pom.xml b/binding-adapter/pom.xml index be3634f7..a2bd2e2a 100644 --- a/binding-adapter/pom.xml +++ b/binding-adapter/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../parent diff --git a/bus/api/pom.xml b/bus/api/pom.xml index be437208..d9a6a4cf 100644 --- a/bus/api/pom.xml +++ b/bus/api/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.bus diff --git a/bus/config/pom.xml b/bus/config/pom.xml index 50149fb6..007c76ff 100644 --- a/bus/config/pom.xml +++ b/bus/config/pom.xml @@ -17,7 +17,7 @@ org.opendaylight.jsonrpc.bus bus-config - 1.16.0-SNAPSHOT + 1.16.0 JSON-RPC :: BUS :: Config Configuration files for JSONRPC bus jar diff --git a/bus/examples/binding-bridge/pom.xml b/bus/examples/binding-bridge/pom.xml index 96a8d928..7c72110b 100644 --- a/bus/examples/binding-bridge/pom.xml +++ b/bus/examples/binding-bridge/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../../parent org.opendaylight.jsonrpc.bus diff --git a/bus/examples/inband-models/pom.xml b/bus/examples/inband-models/pom.xml index 3c4ed02b..82deea50 100644 --- a/bus/examples/inband-models/pom.xml +++ b/bus/examples/inband-models/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../../parent inband-models diff --git a/bus/examples/pom.xml b/bus/examples/pom.xml index 3999505b..3d8ee1e1 100644 --- a/bus/examples/pom.xml +++ b/bus/examples/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-bus - 1.16.0-SNAPSHOT + 1.16.0 org.opendaylight.jsonrpc.bus examples diff --git a/bus/jsonrpc/pom.xml b/bus/jsonrpc/pom.xml index f8674df3..670644af 100644 --- a/bus/jsonrpc/pom.xml +++ b/bus/jsonrpc/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.bus diff --git a/bus/messagelib/pom.xml b/bus/messagelib/pom.xml index 17a44af7..610dffc9 100644 --- a/bus/messagelib/pom.xml +++ b/bus/messagelib/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.bus diff --git a/bus/pom.xml b/bus/pom.xml index 1e453e91..f7c597cf 100644 --- a/bus/pom.xml +++ b/bus/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc - 1.16.0-SNAPSHOT + 1.16.0 jsonrpc-bus pom diff --git a/bus/spi/pom.xml b/bus/spi/pom.xml index de3bfe7c..60a4842d 100644 --- a/bus/spi/pom.xml +++ b/bus/spi/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.bus diff --git a/bus/transport-http/pom.xml b/bus/transport-http/pom.xml index 7d5cd28f..046a8594 100644 --- a/bus/transport-http/pom.xml +++ b/bus/transport-http/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.bus diff --git a/bus/transport-zmq/pom.xml b/bus/transport-zmq/pom.xml index 7a97523f..51ec2860 100644 --- a/bus/transport-zmq/pom.xml +++ b/bus/transport-zmq/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.bus diff --git a/dom-codec/pom.xml b/dom-codec/pom.xml index 8254d353..9d4944bf 100644 --- a/dom-codec/pom.xml +++ b/dom-codec/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../parent diff --git a/features/features-jsonrpc/pom.xml b/features/features-jsonrpc/pom.xml index 60daceb9..28356e9f 100644 --- a/features/features-jsonrpc/pom.xml +++ b/features/features-jsonrpc/pom.xml @@ -19,7 +19,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc features-jsonrpc - 1.16.0-SNAPSHOT + 1.16.0 feature JSON-RPC :: Features :: repository diff --git a/features/odl-jsonrpc-all/pom.xml b/features/odl-jsonrpc-all/pom.xml index 93aad58a..1ffc63f8 100644 --- a/features/odl-jsonrpc-all/pom.xml +++ b/features/odl-jsonrpc-all/pom.xml @@ -19,7 +19,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc odl-jsonrpc-all - 1.16.0-SNAPSHOT + 1.16.0 feature JSON-RPC :: Feature :: all diff --git a/features/odl-jsonrpc-bus/pom.xml b/features/odl-jsonrpc-bus/pom.xml index 48a5ca5e..845b8cc3 100644 --- a/features/odl-jsonrpc-bus/pom.xml +++ b/features/odl-jsonrpc-bus/pom.xml @@ -19,7 +19,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc odl-jsonrpc-bus - 1.16.0-SNAPSHOT + 1.16.0 feature JSON-RPC :: Feature :: bus diff --git a/features/odl-jsonrpc-cluster/pom.xml b/features/odl-jsonrpc-cluster/pom.xml index f49f9688..133f8f67 100644 --- a/features/odl-jsonrpc-cluster/pom.xml +++ b/features/odl-jsonrpc-cluster/pom.xml @@ -19,7 +19,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc odl-jsonrpc-cluster - 1.16.0-SNAPSHOT + 1.16.0 feature JSON-RPC :: Feature :: Cluster diff --git a/features/odl-jsonrpc-provider/pom.xml b/features/odl-jsonrpc-provider/pom.xml index b8d2c796..e79ada19 100644 --- a/features/odl-jsonrpc-provider/pom.xml +++ b/features/odl-jsonrpc-provider/pom.xml @@ -19,7 +19,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc odl-jsonrpc-provider - 1.16.0-SNAPSHOT + 1.16.0 feature JSON-RPC :: Feature :: provider diff --git a/features/pom.xml b/features/pom.xml index be6df4be..8b708f82 100644 --- a/features/pom.xml +++ b/features/pom.xml @@ -16,7 +16,7 @@ org.opendaylight.jsonrpc features-aggregator - 1.16.0-SNAPSHOT + 1.16.0 pom JSON-RPC :: Features :: Aggregator diff --git a/karaf/pom.xml b/karaf/pom.xml index bd5421c4..c98484d9 100644 --- a/karaf/pom.xml +++ b/karaf/pom.xml @@ -16,7 +16,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-karaf - 1.16.0-SNAPSHOT + 1.16.0 JSON-RPC :: Karaf pom diff --git a/parent/pom.xml b/parent/pom.xml index 2740c10a..8b61170e 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -18,7 +18,7 @@ 4.0.0 org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 pom JSON-RPC :: Parent diff --git a/pom.xml b/pom.xml index b9020bc5..2bb87842 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc - 1.16.0-SNAPSHOT + 1.16.0 pom JSON-RPC :: POM diff --git a/provider/cluster/pom.xml b/provider/cluster/pom.xml index 3c807bfc..6fac755c 100644 --- a/provider/cluster/pom.xml +++ b/provider/cluster/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-provider - 1.16.0-SNAPSHOT + 1.16.0 .. diff --git a/provider/common/pom.xml b/provider/common/pom.xml index ccd215a7..f8c39a4d 100644 --- a/provider/common/pom.xml +++ b/provider/common/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-provider - 1.16.0-SNAPSHOT + 1.16.0 .. diff --git a/provider/pom.xml b/provider/pom.xml index 1145a8db..4d1931af 100644 --- a/provider/pom.xml +++ b/provider/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../parent diff --git a/provider/single/pom.xml b/provider/single/pom.xml index 32a993ce..bdbb901d 100644 --- a/provider/single/pom.xml +++ b/provider/single/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-provider - 1.16.0-SNAPSHOT + 1.16.0 .. diff --git a/security/aaa/pom.xml b/security/aaa/pom.xml index a3263b40..f2b94311 100644 --- a/security/aaa/pom.xml +++ b/security/aaa/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.security diff --git a/security/api/pom.xml b/security/api/pom.xml index cf62d18b..533b7496 100644 --- a/security/api/pom.xml +++ b/security/api/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.security diff --git a/security/noop/pom.xml b/security/noop/pom.xml index 0d2e4f5f..1fce7951 100644 --- a/security/noop/pom.xml +++ b/security/noop/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.security diff --git a/security/pom.xml b/security/pom.xml index 7116a79b..59356530 100644 --- a/security/pom.xml +++ b/security/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc - 1.16.0-SNAPSHOT + 1.16.0 jsonrpc-security pom diff --git a/security/service/pom.xml b/security/service/pom.xml index a1b63771..ad85eb2a 100644 --- a/security/service/pom.xml +++ b/security/service/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent org.opendaylight.jsonrpc.security diff --git a/test-model/pom.xml b/test-model/pom.xml index bb82fb18..2a16f6a3 100644 --- a/test-model/pom.xml +++ b/test-model/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../parent jsonrpc-test-model diff --git a/tools/parent/pom.xml b/tools/parent/pom.xml index 0570aab0..902de271 100644 --- a/tools/parent/pom.xml +++ b/tools/parent/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc-parent - 1.16.0-SNAPSHOT + 1.16.0 ../../parent tools-parent diff --git a/tools/pom.xml b/tools/pom.xml index 370d5e50..b620a4a5 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc jsonrpc - 1.16.0-SNAPSHOT + 1.16.0 jsonrpc-tools pom diff --git a/tools/test-tool/pom.xml b/tools/test-tool/pom.xml index b0ee4934..7392b49a 100644 --- a/tools/test-tool/pom.xml +++ b/tools/test-tool/pom.xml @@ -12,7 +12,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.jsonrpc tools-parent - 1.16.0-SNAPSHOT + 1.16.0 ../parent test-tool -- 2.43.0