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