2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.mdsal.binding.dom.adapter;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNotSame;
13 import static org.junit.Assert.assertSame;
14 import static org.junit.Assert.assertTrue;
16 import com.google.common.collect.HashMultimap;
17 import com.google.common.collect.ImmutableSet;
18 import com.google.common.collect.Multimap;
19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture;
21 import com.google.common.util.concurrent.MoreExecutors;
22 import java.util.concurrent.Future;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
26 import org.opendaylight.mdsal.binding.api.RpcProviderService;
27 import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingBrokerTestFactory;
28 import org.opendaylight.mdsal.binding.dom.adapter.test.util.BindingTestContext;
29 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
30 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
31 import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
32 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
33 import org.opendaylight.mdsal.dom.api.DOMRpcService;
34 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnock;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnockInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnockInputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnockOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.KnockKnockOutputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.md.sal.knock.knock.rev180723.OpendaylightKnockKnockRpcService;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
44 import org.opendaylight.yangtools.concepts.ObjectRegistration;
45 import org.opendaylight.yangtools.util.concurrent.FluentFutures;
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
47 import org.opendaylight.yangtools.yang.common.QName;
48 import org.opendaylight.yangtools.yang.common.RpcResult;
49 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
50 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
52 public class BindingDOMRpcIntegrationTest {
53 private static final InstanceIdentifier<TopLevelList> BA_NODE_ID = InstanceIdentifier.create(Top.class)
54 .child(TopLevelList.class, new TopLevelListKey("a"));
56 private static final QName KNOCK_KNOCK_QNAME = QName.create(KnockKnockOutput.QNAME, "knock-knock");
58 private RpcProviderService baRpcProviderService;
59 private RpcConsumerRegistry baRpcConsumerService;
60 private DOMRpcProviderService biRpcProviderService;
61 private BindingTestContext testContext;
62 private DOMRpcService biRpcService;
63 private final OpendaylightKnockKnockRpcServiceImpl knockRpcImpl = new OpendaylightKnockKnockRpcServiceImpl();
66 public void setup() throws Exception {
67 BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory();
68 testFactory.setExecutor(MoreExecutors.newDirectExecutorService());
69 testContext = testFactory.getTestContext();
71 testContext.setSchemaModuleInfos(ImmutableSet.of(
72 BindingReflections.getModuleInfo(OpendaylightKnockKnockRpcService.class),
73 BindingReflections.getModuleInfo(Top.class)));
75 baRpcProviderService = testContext.getBindingRpcProviderRegistry();
76 baRpcConsumerService = testContext.getBindingRpcConsumerRegistry();
77 biRpcProviderService = testContext.getDomRpcRegistry();
78 biRpcService = testContext.getDomRpcInvoker();
82 public void testBindingRegistrationWithDOMInvocation() throws Exception {
83 knockRpcImpl.registerTo(baRpcProviderService, BA_NODE_ID).setKnockKnockResult(knockResult(true, "open"));
85 final OpendaylightKnockKnockRpcService baKnockService =
86 baRpcConsumerService.getRpcService(OpendaylightKnockKnockRpcService.class);
87 assertNotSame(knockRpcImpl, baKnockService);
89 KnockKnockInput baKnockKnockInput = knockKnock(BA_NODE_ID).setQuestion("who's there?").build();
91 ContainerNode biKnockKnockInput = toDOMKnockKnockInput(baKnockKnockInput);
92 DOMRpcResult domResult = Futures.getDone(biRpcService.invokeRpc(KNOCK_KNOCK_QNAME, biKnockKnockInput));
93 assertNotNull(domResult);
94 assertNotNull(domResult.value());
95 assertTrue("Binding KnockKnock service was not invoked",
96 knockRpcImpl.getReceivedKnocks().containsKey(BA_NODE_ID));
97 assertEquals(baKnockKnockInput, knockRpcImpl.getReceivedKnocks().get(BA_NODE_ID).iterator().next());
101 public void testDOMRegistrationWithBindingInvocation() throws Exception {
102 KnockKnockOutput baKnockKnockOutput = new KnockKnockOutputBuilder().setAnswer("open").build();
104 biRpcProviderService.registerRpcImplementation((rpc, input) ->
105 FluentFutures.immediateFluentFuture(new DefaultDOMRpcResult(testContext.getCodec()
106 .currentSerializer().toNormalizedNodeRpcData(baKnockKnockOutput))),
107 DOMRpcIdentifier.create(KNOCK_KNOCK_QNAME, testContext.getCodec().currentSerializer()
108 .toYangInstanceIdentifier(BA_NODE_ID)));
110 final OpendaylightKnockKnockRpcService baKnockService =
111 baRpcConsumerService.getRpcService(OpendaylightKnockKnockRpcService.class);
112 Future<RpcResult<KnockKnockOutput>> baResult = baKnockService.knockKnock(knockKnock(BA_NODE_ID)
113 .setQuestion("Who's there?").build());
114 assertNotNull(baResult);
115 assertEquals(baKnockKnockOutput, Futures.getDone(baResult).getResult());
119 public void testBindingRpcShortcut() throws Exception {
120 final ListenableFuture<RpcResult<KnockKnockOutput>> baKnockResult = knockResult(true, "open");
121 knockRpcImpl.registerTo(baRpcProviderService, BA_NODE_ID).setKnockKnockResult(baKnockResult);
123 final OpendaylightKnockKnockRpcService baKnockService =
124 baRpcConsumerService.getRpcService(OpendaylightKnockKnockRpcService.class);
126 KnockKnockInput baKnockKnockInput = knockKnock(BA_NODE_ID).setQuestion("who's there?").build();
128 final RpcResult<KnockKnockOutput> rpcResult = Futures.getDone(baKnockService.knockKnock(baKnockKnockInput));
130 assertEquals(baKnockResult.get().getResult().getClass(), rpcResult.getResult().getClass());
131 assertSame(baKnockResult.get().getResult(), rpcResult.getResult());
132 assertSame(baKnockKnockInput, knockRpcImpl.getReceivedKnocks().get(BA_NODE_ID).iterator().next());
136 public void testSimpleRpc() throws Exception {
137 baRpcProviderService.registerRpcImplementation((KnockKnock) input -> knockResult(true, "open"));
139 final KnockKnock baKnockService = baRpcConsumerService.getRpc(KnockKnock.class);
140 final RpcResult<KnockKnockOutput> rpcResult = Futures.getDone(
141 baKnockService.invoke(knockKnock(BA_NODE_ID).setQuestion("who's there?").build()));
143 assertEquals(rpcResult.getResult().getClass(), rpcResult.getResult().getClass());
144 assertSame(rpcResult.getResult(), rpcResult.getResult());
147 private static ListenableFuture<RpcResult<KnockKnockOutput>> knockResult(final boolean success,
148 final String answer) {
149 return RpcResultBuilder.<KnockKnockOutput>status(success)
150 .withResult(new KnockKnockOutputBuilder().setAnswer(answer).build())
154 private static KnockKnockInputBuilder knockKnock(final InstanceIdentifier<TopLevelList> listId) {
155 KnockKnockInputBuilder builder = new KnockKnockInputBuilder();
156 builder.setKnockerId(listId);
160 private ContainerNode toDOMKnockKnockInput(final KnockKnockInput from) {
161 return testContext.getCodec().currentSerializer().toNormalizedNodeRpcData(from);
164 private static final class OpendaylightKnockKnockRpcServiceImpl implements OpendaylightKnockKnockRpcService {
165 private final Multimap<InstanceIdentifier<?>, KnockKnockInput> receivedKnocks = HashMultimap.create();
166 private ListenableFuture<RpcResult<KnockKnockOutput>> knockKnockResult;
167 private ObjectRegistration<OpendaylightKnockKnockRpcServiceImpl> registration;
169 OpendaylightKnockKnockRpcServiceImpl setKnockKnockResult(
170 final ListenableFuture<RpcResult<KnockKnockOutput>> kkOutput) {
171 knockKnockResult = kkOutput;
175 Multimap<InstanceIdentifier<?>, KnockKnockInput> getReceivedKnocks() {
176 return receivedKnocks;
179 OpendaylightKnockKnockRpcServiceImpl registerTo(final RpcProviderService registry,
180 final InstanceIdentifier<?>... paths) {
181 registration = registry.registerRpcImplementation(OpendaylightKnockKnockRpcService.class, this,
182 ImmutableSet.copyOf(paths));
183 assertNotNull(registration);
188 public ListenableFuture<RpcResult<KnockKnockOutput>> knockKnock(final KnockKnockInput input) {
189 receivedKnocks.put(input.getKnockerId(), input);
190 return knockKnockResult;