Updated implementation of internal RPC Router for Binding-Aware Broker and added...
[controller.git] / opendaylight / md-sal / sal-binding-it / src / test / java / org / opendaylight / controller / test / sal / binding / it / RoutedServiceTest.java
1 package org.opendaylight.controller.test.sal.binding.it;
2
3 import static org.junit.Assert.*;
4
5 import java.math.BigInteger;
6 import java.util.Collection;
7
8 import org.junit.Before;
9 import org.junit.Test;
10 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
11 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
12 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
13 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
14 import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
15 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;
16 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.opendaylight.yangtools.yang.binding.RpcService;
28
29 import com.google.inject.Inject;
30
31 import static org.mockito.Mockito.*;
32
33 public class RoutedServiceTest extends AbstractTest {
34
35     private SalFlowService first;
36     private SalFlowService second;
37
38     private SalFlowService consumerService;
39
40     private RoutedRpcRegistration<SalFlowService> firstReg;
41     private RoutedRpcRegistration<SalFlowService> secondReg;
42
43     @Before
44     public void setUp() throws Exception {
45         first = mock(SalFlowService.class,"First Flow Service");
46         second = mock(SalFlowService.class,"Second Flow Service");
47     }
48
49     @Test
50     public void testServiceRegistration() {
51
52         assertNotNull(getBroker());
53
54         BindingAwareProvider provider1 = new AbstractTestProvider() {
55
56             @Override
57             public void onSessionInitiated(ProviderContext session) {
58                 assertNotNull(session);
59                 firstReg = session.addRoutedRpcImplementation(SalFlowService.class, first);
60             }
61         };
62
63         /**
64          * Register first provider, which register first implementation of 
65          * SalFlowService
66          * 
67          */
68         getBroker().registerProvider(provider1, getBundleContext());
69         assertNotNull("Registration should not be null", firstReg);
70         assertSame(first, firstReg.getInstance());
71         
72         BindingAwareProvider provider2 = new AbstractTestProvider() {
73
74             @Override
75             public void onSessionInitiated(ProviderContext session) {
76                 assertNotNull(session);
77                 secondReg = session.addRoutedRpcImplementation(SalFlowService.class, second);
78             }
79         };
80         getBroker().registerProvider(provider2, getBundleContext());
81         assertNotNull("Registration should not be null", firstReg);
82         assertNotSame(secondReg, firstReg);
83
84
85         BindingAwareConsumer consumer = new BindingAwareConsumer() {
86             @Override
87             public void onSessionInitialized(ConsumerContext session) {
88                 consumerService = session.getRpcService(SalFlowService.class);
89             }
90         };
91         broker.registerConsumer(consumer, getBundleContext());
92
93         assertNotNull("MD-SAL instance of Flow Service should be returned", consumerService);
94         assertNotSame("Provider instance and consumer instance should not be same.", first, consumerService);
95
96         NodeRef nodeOne = createNodeRef("foo:node:1");
97
98
99         /**
100          * Provider 1 - register itself as provider for SalFlowService
101          * for nodeOne
102          */
103         firstReg.registerPath(NodeContext.class, nodeOne.getValue());
104
105         /**
106          * Consumer creates addFlow Message for node one and sends
107          * it to the MD-SAL
108          * 
109          */
110         AddFlowInput firstMessage = createSampleAddFlow(nodeOne,1);
111         consumerService.addFlow(firstMessage);
112         
113         /**
114          * We verify if implementation of first provider received same
115          * message from MD-SAL.
116          * 
117          */
118         verify(first).addFlow(firstMessage);
119         
120         /**
121          * Verifies that second instance was not invoked with first
122          * message
123          * 
124          */
125         verify(second, times(0)).addFlow(firstMessage);
126         
127         /**
128          * Second provider registers as provider for nodeTwo
129          * 
130          */
131         NodeRef nodeTwo = createNodeRef("foo:node:2");
132         secondReg.registerPath(NodeContext.class, nodeTwo.getValue());
133         
134         
135         /**
136          * Consumer sends message to nodeTwo for three times.
137          * Should be processed by second instance.
138          */
139         AddFlowInput secondMessage = createSampleAddFlow(nodeTwo,2);
140         consumerService.addFlow(secondMessage);
141         consumerService.addFlow(secondMessage);
142         consumerService.addFlow(secondMessage);
143         
144         /**
145          * We verify that second was invoked 3 times, with message
146          * two as parameter, first was invoked 0 times.
147          * 
148          */
149         verify(second, times(3)).addFlow(secondMessage);
150         verify(first, times(0)).addFlow(secondMessage);
151         
152         
153         /**
154          * First provider unregisters as implementation of FlowService
155          * for node one
156          * 
157          */
158         firstReg.unregisterPath(NodeContext.class, nodeOne.getValue());
159         
160         
161         /**
162          * Second provider registers as implementation for FlowService
163          * for node one
164          * 
165          */
166         secondReg.registerPath(NodeContext.class, nodeOne.getValue());
167         
168         /**
169          * Consumer sends third message to Node 1, should be processed
170          * by second instance.
171          * 
172          */
173         AddFlowInput thirdMessage = createSampleAddFlow(nodeOne,3);
174         consumerService.addFlow(thirdMessage);
175         
176         /**
177          * We verify that first provider was invoked 0 times,
178          * second provider 1 time.
179          */
180         verify(first,times(0)).addFlow(thirdMessage);
181         verify(second).addFlow(thirdMessage);
182         
183     }
184
185     private static NodeRef createNodeRef(String string) {
186         NodeKey key = new NodeKey(new NodeId(string));
187         InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).node(Node.class, key)
188                 .toInstance();
189
190         return new NodeRef(path);
191     }
192
193     static AddFlowInput createSampleAddFlow(NodeRef node,int cookie) {
194         AddFlowInputBuilder ret = new AddFlowInputBuilder();
195         ret.setNode(node);
196         ret.setCookie(BigInteger.valueOf(cookie));
197         return ret.build();
198     }
199 }