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