Updated implementation of internal RPC Router for Binding-Aware Broker and added...
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / test / java / org / opendaylight / controller / sal / binding / test / RuntimeCodeGeneratorTest.java
1 package org.opendaylight.controller.sal.binding.test;
2 import static org.junit.Assert.*;
3
4 import java.util.Arrays;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import javassist.ClassPool;
9
10 import org.junit.Before;
11 import org.junit.Test;
12
13 import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.*;
14
15 import org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator;
16 import org.opendaylight.controller.sal.binding.spi.RpcRouter;
17 import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
18 import org.opendaylight.controller.sal.binding.test.mock.FooService;
19 import org.opendaylight.controller.sal.binding.test.mock.ReferencableObject;
20 import org.opendaylight.controller.sal.binding.test.mock.ReferencableObjectKey;
21 import org.opendaylight.controller.sal.binding.test.mock.SimpleInput;
22 import org.opendaylight.yangtools.yang.binding.Augmentation;
23 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
24 import org.opendaylight.yangtools.yang.binding.DataObject;
25 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
28
29 import static org.mockito.Mockito.*;
30
31
32 public class RuntimeCodeGeneratorTest {
33
34     private RuntimeCodeGenerator codeGenerator;
35
36     
37     @Before
38     public void initialize() {
39         this.codeGenerator = new RuntimeCodeGenerator(ClassPool.getDefault());
40     }
41     
42     @Test
43     public void testGenerateDirectProxy() {
44         FooService product = codeGenerator.getDirectProxyFor(FooService.class);
45         assertNotNull(product);
46     }
47
48     @Test
49     public void testGenerateRouter() throws Exception {
50         RpcRouter<FooService> product = codeGenerator.getRouterFor(FooService.class);
51         assertNotNull(product);
52         assertNotNull(product.getInvocationProxy());
53         
54         assertEquals("2 fields should be generated.",2,product.getInvocationProxy().getClass().getFields().length);
55         
56         verifyRouting(product);
57     }
58
59     private void verifyRouting(RpcRouter<FooService> product) {
60         assertNotNull("Routing table should be initialized",product.getRoutingTable(BaseIdentity.class));
61         
62         RpcRoutingTable<BaseIdentity, FooService> routingTable = product.getRoutingTable(BaseIdentity.class);
63         
64         int servicesCount = 2;
65         int instancesPerService = 3;
66         
67         InstanceIdentifier<?>[][] identifiers = identifiers(servicesCount,instancesPerService);
68         FooService service[] = new FooService[] {
69                 mock(FooService.class, "Instance 0"),
70                 mock(FooService.class,"Instance 1")
71         };
72         
73         for(int i = 0;i<service.length;i++) {
74             for (InstanceIdentifier<?> instance : identifiers[i]) {
75                 routingTable.updateRoute(instance, service[i]);
76             }
77         }
78         
79         assertEquals("All instances should be registered.", servicesCount*instancesPerService, routingTable.getRoutes().size());
80         
81         SimpleInput[] instance_0_input = new SimpleInputImpl[] {
82             new SimpleInputImpl(identifiers[0][0]),
83             new SimpleInputImpl(identifiers[0][1]),
84             new SimpleInputImpl(identifiers[0][2])
85         };
86         
87         SimpleInput[] instance_1_input = new SimpleInputImpl[] {
88                 new SimpleInputImpl(identifiers[1][0]),
89                 new SimpleInputImpl(identifiers[1][1]),
90                 new SimpleInputImpl(identifiers[1][2])
91         };
92         
93         // We test sending mock messages
94         
95         product.getInvocationProxy().simple(instance_0_input[0]);
96         verify(service[0]).simple(instance_0_input[0]);
97         
98         product.getInvocationProxy().simple(instance_0_input[1]);
99         product.getInvocationProxy().simple(instance_0_input[2]);
100         
101         verify(service[0]).simple(instance_0_input[1]);
102         verify(service[0]).simple(instance_0_input[2]);
103         
104         
105         product.getInvocationProxy().simple(instance_1_input[0]);
106         
107         // We should have call to instance 1
108         verify(service[1]).simple(instance_1_input[0]);
109     }
110
111     private InstanceIdentifier<?>[][] identifiers(int serviceSize, int instancesPerService) {
112         InstanceIdentifier<?>[][] ret = new InstanceIdentifier[serviceSize][];
113         int service = 0;
114         for (int i = 0;i<serviceSize;i++) {
115             
116             InstanceIdentifier<?>[] instanceIdentifiers = new InstanceIdentifier[instancesPerService];
117             ret[i] = instanceIdentifiers;
118             for(int id = 0;id<instancesPerService;id++) {
119                 instanceIdentifiers[id] = referencableIdentifier(service*instancesPerService+id);
120             }
121             service++;
122         }
123         
124         return ret;
125     }
126
127     private InstanceIdentifier<?> referencableIdentifier(int i) {
128         ReferencableObjectKey key = new ReferencableObjectKey(i);
129         IdentifiableItem<ReferencableObject,ReferencableObjectKey> pathArg = new IdentifiableItem<>(ReferencableObject.class,key);
130         return new InstanceIdentifier<ReferencableObject>(Arrays.<PathArgument>asList(pathArg), ReferencableObject.class);
131     }
132
133     private static class SimpleInputImpl implements SimpleInput {
134         private final InstanceIdentifier<?> identifier;
135
136         public SimpleInputImpl(InstanceIdentifier<?> _identifier) {
137             this.identifier = _identifier;
138         }
139
140         @Override
141         public <E extends Augmentation<SimpleInput>> E getAugmentation(Class<E> augmentationType) {
142             return null;
143         }
144
145         @Override
146         public InstanceIdentifier<?> getIdentifier() {
147             return this.identifier;
148         }
149
150         @Override
151         public Class<? extends DataObject> getImplementedInterface() {
152             return SimpleInput.class;
153         }
154     }
155 }