e4665e9f19aa920e62d561dddbd90562ab6f8a3c
[groupbasedpolicy.git] / renderers / vpp / src / test / java / org / opendaylight / groupbasedpolicy / renderer / vpp / policy / VppRendererPolicyManagerTest.java
1 /*
2  * Copyright (c) 2016 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
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.policy;
10
11 import com.google.common.base.Optional;
12 import com.google.common.base.Strings;
13 import com.google.common.util.concurrent.MoreExecutors;
14 import java.util.Arrays;
15 import java.util.Collection;
16 import java.util.List;
17 import java.util.stream.Collectors;
18 import java.util.stream.Stream;
19 import org.junit.Assert;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.Mockito;
24 import org.mockito.runners.MockitoJUnitRunner;
25 import org.opendaylight.controller.config.yang.config.vpp_provider.impl.VppRenderer;
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
30 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.RendererPolicyConfEvent;
31 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.VppEndpointConfEvent;
32 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
33 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppEndpointLocationProvider;
34 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppPathMapper;
35 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
36 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
37 import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
38 import org.opendaylight.groupbasedpolicy.util.IidFactory;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainment;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.ForwardingContextContainmentBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocationBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.LocationProviders;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocation;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2FloodDomain;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.AddressType;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.ContextType;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.ConfigurationBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.Endpoints;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.EndpointsBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererEndpointsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RuleGroupsBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRuleBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.bridge.domain.PhysicalLocationRef;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCaseBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.TunnelTypeVxlan;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
101 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
102
103 @RunWith(MockitoJUnitRunner.class)
104 public class VppRendererPolicyManagerTest extends CustomDataBrokerTest {
105
106     private static final InstanceIdentifier<RendererPolicy> RENDERER_POLICY_IID =
107             IidFactory.rendererIid(VppRenderer.NAME).child(RendererPolicy.class);
108     private static final ContextId CTX_ID = new ContextId("ctx");
109     private static final ContextId L2FD_CTX = new ContextId("l2fd");
110     private final static TopologyKey TOPO_KEY = new TopologyKey(new TopologyId("topology-netconf"));
111     private final static InstanceIdentifier<Node> VPP_NODE_1_IID = InstanceIdentifier.builder(NetworkTopology.class)
112         .child(Topology.class, TOPO_KEY)
113         .child(Node.class, new NodeKey(new NodeId("node1")))
114         .build();
115     private final static InstanceIdentifier<Node> VPP_NODE_2_IID = InstanceIdentifier.builder(NetworkTopology.class)
116         .child(Topology.class, TOPO_KEY)
117         .child(Node.class, new NodeKey(new NodeId("node2")))
118         .build();
119     private static final ContractId CONTRACT_ID = new ContractId("contract");
120     private static final TenantId TENANT_ID = new TenantId("tenant");
121     private static final SubjectName SUBJECT_NAME = new SubjectName("subject");
122     private static final RuleName RULE_NAME = new RuleName("rule");
123     private static final RuleGroupWithRendererEndpointParticipation RULE_GROUP_WITH_CONSUMER =
124             new RuleGroupWithRendererEndpointParticipationBuilder().setContractId(CONTRACT_ID)
125                 .setTenantId(TENANT_ID)
126                 .setSubjectName(SUBJECT_NAME)
127                 .setRendererEndpointParticipation(EndpointPolicyParticipation.CONSUMER)
128                 .build();
129     private static final RuleGroupWithRendererEndpointParticipation RULE_GROUP_WITH_PROVIDER =
130             new RuleGroupWithRendererEndpointParticipationBuilder().setContractId(CONTRACT_ID)
131                 .setTenantId(TENANT_ID)
132                 .setSubjectName(SUBJECT_NAME)
133                 .setRendererEndpointParticipation(EndpointPolicyParticipation.PROVIDER)
134                 .build();
135     private static final RuleGroup RULE_GROUP = new RuleGroupBuilder().setContractId(CONTRACT_ID)
136         .setTenantId(TENANT_ID)
137         .setSubjectName(SUBJECT_NAME)
138         .setResolvedRule(Arrays.asList(new ResolvedRuleBuilder().setName(RULE_NAME).build()))
139         .build();
140     private final static String SOCKET = "socket";
141
142     private MountedDataBrokerProvider mountedDataProviderMock;
143     private DataBroker mountPointDataBroker;
144     private DataBroker dataBroker;
145
146     private BridgeDomainManager bdManager;
147     private InterfaceManager ifaceManager;
148     private ForwardingManager fwManager;
149     private VppRendererPolicyManager vppRendererPolicyManager;
150
151     @Override
152     public Collection<Class<?>> getClassesFromModules() {
153         return Arrays.asList(Node.class, VppEndpoint.class, Interfaces.class, BridgeDomains.class,
154                 LocationProviders.class, L2FloodDomain.class, VxlanVni.class, TopologyVbridgeAugment.class,
155                 TunnelTypeVxlan.class, PhysicalLocationRef.class);
156     }
157
158     @Before
159     public void init() throws Exception {
160         ForwardingManager.WAIT_FOR_BD_CREATION = 2;
161         mountedDataProviderMock = Mockito.mock(MountedDataBrokerProvider.class);
162         mountPointDataBroker = getDataBroker();
163         setup(); // initialize new data broker for ODL data store
164         dataBroker = getDataBroker();
165         Mockito.when(mountedDataProviderMock.getDataBrokerForMountPoint(Mockito.any(InstanceIdentifier.class)))
166             .thenReturn(Optional.of(mountPointDataBroker));
167         ifaceManager =
168                 new InterfaceManager(mountedDataProviderMock, dataBroker, MoreExecutors.newDirectExecutorService());
169         bdManager = new BridgeDomainManagerImpl(mountPointDataBroker);
170         fwManager = new ForwardingManager(ifaceManager, bdManager, dataBroker);
171         vppRendererPolicyManager = new VppRendererPolicyManager(fwManager, dataBroker);
172     }
173
174     @Test
175     public void testRendererPolicyChanged_created_oneEpPerEpg() throws Exception {
176         String clientIp = "1.1.1.1";
177         String clientIfaceName = "client1";
178         AbsoluteLocation clientLocation = absoluteLocation(VPP_NODE_1_IID, null, clientIfaceName);
179         AddressEndpointWithLocation clientEp = createEndpoint(clientIp, L2FD_CTX.getValue(), clientLocation);
180         String webIp = "2.2.2.2";
181         String webIfaceName = "web1";
182         AbsoluteLocation webLocation = absoluteLocation(VPP_NODE_1_IID, null, webIfaceName);
183         AddressEndpointWithLocation webEp = createEndpoint(webIp, L2FD_CTX.getValue(), webLocation);
184
185         storeVppEndpoint(clientEp.getKey(), clientIfaceName, createVppEndpointIid(clientEp.getKey()));
186         storeVppEndpoint(webEp.getKey(), webIfaceName, createVppEndpointIid(webEp.getKey()));
187
188         Configuration configuration = createConfiguration(Arrays.asList(clientEp), Arrays.asList(webEp));
189         RendererPolicy rendererPolicy =
190                 new RendererPolicyBuilder().setVersion(1L).setConfiguration(configuration).build();
191         RendererPolicyConfEvent event = new RendererPolicyConfEvent(RENDERER_POLICY_IID, null, rendererPolicy);
192
193         vppRendererPolicyManager.rendererPolicyChanged(event);
194
195         // assert state on data store behind mount point
196         Interface clientIface = readAndAssertInterface(clientIfaceName);
197         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), clientIface);
198         Interface webIface = readAndAssertInterface(webIfaceName);
199         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), webIface);
200         // assert state on ODL data store
201         ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
202         Optional<LocationProvider> optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
203                 IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
204             .get();
205         Assert.assertTrue(optLocationProvider.isPresent());
206         List<ProviderAddressEndpointLocation> epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
207         Assert.assertNotNull(epLocs);
208         Assert.assertEquals(2, epLocs.size());
209         assertProviderAddressEndpointLocation(clientEp.getKey(),
210                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), clientIfaceName), epLocs);
211         assertProviderAddressEndpointLocation(webEp.getKey(),
212                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), webIfaceName), epLocs);
213     }
214
215     @Test
216     public void testRendererPolicyChanged_update() throws Exception {
217         String client1IfaceName = "client1";
218         AbsoluteLocation client1LocationNodeNull = absoluteLocation(VPP_NODE_1_IID, null, client1IfaceName);
219         AddressEndpointWithLocation client1Ep =
220                 createEndpoint("10.0.0.1", L2FD_CTX.getValue(), client1LocationNodeNull);
221         String web1IfaceName = "web1";
222         AbsoluteLocation web1LocationNodeNull = absoluteLocation(VPP_NODE_2_IID, null, web1IfaceName);
223         AddressEndpointWithLocation web1Ep = createEndpoint("20.0.0.1", L2FD_CTX.getValue(), web1LocationNodeNull);
224         String client2IfaceName = "client2";
225         AbsoluteLocation client2LocationNodeNull = absoluteLocation(VPP_NODE_1_IID, null, client2IfaceName);
226         AddressEndpointWithLocation client2Ep =
227                 createEndpoint("10.0.0.2", L2FD_CTX.getValue(), client2LocationNodeNull);
228         String web2IfaceName = "web2";
229         AbsoluteLocation web2LocationNodeNull = absoluteLocation(VPP_NODE_2_IID, null, web2IfaceName);
230         AddressEndpointWithLocation web2Ep = createEndpoint("20.0.0.2", L2FD_CTX.getValue(), web2LocationNodeNull);
231
232         storeVppEndpoint(client1Ep.getKey(), client1IfaceName, createVppEndpointIid(client1Ep.getKey()));
233         storeVppEndpoint(web1Ep.getKey(), web1IfaceName, createVppEndpointIid(web1Ep.getKey()));
234         storeVppEndpoint(client2Ep.getKey(), client2IfaceName, createVppEndpointIid(client2Ep.getKey()));
235         storeVppEndpoint(web2Ep.getKey(), web2IfaceName, createVppEndpointIid(web2Ep.getKey()));
236
237         Configuration configuration =
238                 createConfiguration(Arrays.asList(client1Ep, client2Ep), Arrays.asList(web1Ep, web2Ep));
239         RendererPolicy rendererPolicy =
240                 new RendererPolicyBuilder().setVersion(1L).setConfiguration(configuration).build();
241         RendererPolicyConfEvent event = new RendererPolicyConfEvent(RENDERER_POLICY_IID, null, rendererPolicy);
242
243         vppRendererPolicyManager.rendererPolicyChanged(event);
244
245         // assert state on data store behind mount point ######################################
246         Interface client1Iface = readAndAssertInterface(client1IfaceName);
247         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client1Iface);
248         Interface web1Iface = readAndAssertInterface(web1IfaceName);
249         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web1Iface);
250         Interface client2Iface = readAndAssertInterface(client2IfaceName);
251         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client2Iface);
252         Interface web2Iface = readAndAssertInterface(web2IfaceName);
253         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web2Iface);
254         // assert state on ODL data store
255         ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
256         Optional<LocationProvider> optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
257                 IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
258             .get();
259         Assert.assertTrue(optLocationProvider.isPresent());
260         List<ProviderAddressEndpointLocation> epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
261         Assert.assertNotNull(epLocs);
262         Assert.assertEquals(4, epLocs.size());
263         assertProviderAddressEndpointLocation(client1Ep.getKey(),
264                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client1IfaceName), epLocs);
265         assertProviderAddressEndpointLocation(web1Ep.getKey(),
266                 absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web1IfaceName), epLocs);
267         assertProviderAddressEndpointLocation(client2Ep.getKey(),
268                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client2IfaceName), epLocs);
269         assertProviderAddressEndpointLocation(web2Ep.getKey(),
270                 absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web2IfaceName), epLocs);
271         // #####################################################################################
272
273         AbsoluteLocation client1Location =
274                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client1IfaceName);
275         AbsoluteLocation web1Location =
276                 absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web1IfaceName);
277         AbsoluteLocation web2Location =
278                 absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web2IfaceName);
279         configuration = createConfiguration(
280                 Arrays.asList(
281                         new AddressEndpointWithLocationBuilder(client1Ep).setAbsoluteLocation(client1Location).build(),
282                         new AddressEndpointWithLocationBuilder(client2Ep).setAbsoluteLocation(client2LocationNodeNull)
283                             .build()),
284                 Arrays.asList(new AddressEndpointWithLocationBuilder(web1Ep).setAbsoluteLocation(web1Location).build(),
285                         new AddressEndpointWithLocationBuilder(web2Ep).setAbsoluteLocation(web2Location).build()));
286         RendererPolicy rendererPolicy2 =
287                 new RendererPolicyBuilder().setVersion(2L).setConfiguration(configuration).build();
288         RendererPolicyConfEvent event2 =
289                 new RendererPolicyConfEvent(RENDERER_POLICY_IID, rendererPolicy, rendererPolicy2);
290
291         vppRendererPolicyManager.rendererPolicyChanged(event2);
292
293         // assert state on data store behind mount point ######################################
294         client1Iface = readAndAssertInterface(client1IfaceName);
295         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client1Iface);
296         web1Iface = readAndAssertInterface(web1IfaceName);
297         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web1Iface);
298         client2Iface = readAndAssertInterface(client2IfaceName);
299         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client2Iface);
300         web2Iface = readAndAssertInterface(web2IfaceName);
301         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web2Iface);
302         // assert state on ODL data store
303         rTx = dataBroker.newReadOnlyTransaction();
304         optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
305                 IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
306             .get();
307         Assert.assertTrue(optLocationProvider.isPresent());
308         epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
309         Assert.assertNotNull(epLocs);
310         Assert.assertEquals(4, epLocs.size());
311         assertProviderAddressEndpointLocation(client1Ep.getKey(),
312                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client1IfaceName), epLocs);
313         assertProviderAddressEndpointLocation(web1Ep.getKey(),
314                 absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web1IfaceName), epLocs);
315         assertProviderAddressEndpointLocation(client2Ep.getKey(),
316                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client2IfaceName), epLocs);
317         assertProviderAddressEndpointLocation(web2Ep.getKey(),
318                 absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web2IfaceName), epLocs);
319         // #####################################################################################
320
321         AbsoluteLocation client2Location =
322                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client2IfaceName);
323         configuration = createConfiguration(
324                 Arrays.asList(new AddressEndpointWithLocationBuilder(client1Ep).setAbsoluteLocation(client1Location)
325                     .build(),
326                         new AddressEndpointWithLocationBuilder(client2Ep).setAbsoluteLocation(client2Location).build()),
327                 Arrays.asList(new AddressEndpointWithLocationBuilder(web1Ep).setAbsoluteLocation(web1Location).build(),
328                         new AddressEndpointWithLocationBuilder(web2Ep).setAbsoluteLocation(web2Location).build()));
329         RendererPolicy rendererPolicy3 =
330                 new RendererPolicyBuilder().setVersion(3L).setConfiguration(configuration).build();
331         RendererPolicyConfEvent event3 =
332                 new RendererPolicyConfEvent(RENDERER_POLICY_IID, rendererPolicy2, rendererPolicy3);
333
334         vppRendererPolicyManager.rendererPolicyChanged(event3);
335
336         // assert state on data store behind mount point ######################################
337         client1Iface = readAndAssertInterface(client1IfaceName);
338         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client1Iface);
339         web1Iface = readAndAssertInterface(web1IfaceName);
340         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web1Iface);
341         client2Iface = readAndAssertInterface(client2IfaceName);
342         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client2Iface);
343         web2Iface = readAndAssertInterface(web2IfaceName);
344         assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web2Iface);
345         // assert state on ODL data store
346         rTx = dataBroker.newReadOnlyTransaction();
347         optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
348                 IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
349             .get();
350         Assert.assertTrue(optLocationProvider.isPresent());
351         epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
352         Assert.assertNotNull(epLocs);
353         Assert.assertEquals(4, epLocs.size());
354         assertProviderAddressEndpointLocation(client1Ep.getKey(),
355                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client1IfaceName), epLocs);
356         assertProviderAddressEndpointLocation(web1Ep.getKey(),
357                 absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web1IfaceName), epLocs);
358         assertProviderAddressEndpointLocation(client2Ep.getKey(),
359                 absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client2IfaceName), epLocs);
360         assertProviderAddressEndpointLocation(web2Ep.getKey(),
361                 absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web2IfaceName), epLocs);
362         // #####################################################################################
363     }
364
365     private static AbsoluteLocation absoluteLocation(InstanceIdentifier<?> mountPoint, String nodeName,
366             String nodeConnectorName) {
367         ExternalLocationCaseBuilder extLocBuilder =
368                 new ExternalLocationCaseBuilder().setExternalNodeMountPoint(mountPoint);
369         if (!Strings.isNullOrEmpty(nodeName)) {
370             extLocBuilder.setExternalNode(VppPathMapper.bridgeDomainToRestPath(nodeName));
371         }
372         if (!Strings.isNullOrEmpty(nodeConnectorName)) {
373             extLocBuilder.setExternalNodeConnector(VppPathMapper.interfaceToRestPath(nodeConnectorName));
374         }
375         return new AbsoluteLocationBuilder().setLocationType(extLocBuilder.build()).build();
376     }
377
378     private AddressEndpointWithLocation createEndpoint(String ip, String l2FdIdAsNetCont,
379             AbsoluteLocation absoluteLocation) {
380         AddressEndpointWithLocationKey key =
381                 new AddressEndpointWithLocationKey(ip, AddressType.class, CTX_ID, ContextType.class);
382         NetworkContainment networkContainment =
383                 new NetworkContainmentBuilder().setContainment(new ForwardingContextContainmentBuilder()
384                     .setContextType(L2FloodDomain.class).setContextId(new ContextId(l2FdIdAsNetCont)).build()).build();
385         return new AddressEndpointWithLocationBuilder().setKey(key)
386             .setNetworkContainment(networkContainment)
387             .setAbsoluteLocation(absoluteLocation)
388             .build();
389     }
390
391     private InstanceIdentifier<VppEndpoint> createVppEndpointIid(AddressEndpointWithLocationKey key) {
392         return InstanceIdentifier.builder(Config.class)
393             .child(VppEndpoint.class, new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(),
394                     key.getContextType()))
395             .build();
396     }
397
398     private Configuration createConfiguration(List<AddressEndpointWithLocation> consumers,
399             List<AddressEndpointWithLocation> providers) {
400         List<AddressEndpointWithLocation> eps =
401                 Stream.concat(consumers.stream(), providers.stream()).collect(Collectors.toList());
402         Endpoints endpoints = new EndpointsBuilder().setAddressEndpointWithLocation(eps).build();
403         List<RendererEndpoint> consumersAsRendererEps = consumers.stream().map(cons -> {
404             List<PeerEndpoint> peers = providers.stream()
405                 .map(web -> new PeerEndpointBuilder()
406                     .setKey(KeyFactory.peerEndpointKey(web.getKey()))
407                     .setRuleGroupWithRendererEndpointParticipation(Arrays.asList(RULE_GROUP_WITH_CONSUMER))
408                     .build())
409                 .collect(Collectors.toList());
410             return new RendererEndpointBuilder().setKey(KeyFactory.rendererEndpointKey(cons.getKey()))
411                 .setPeerEndpoint(peers)
412                 .build();
413         }).collect(Collectors.toList());
414         List<RendererEndpoint> providersAsRendererEps = providers.stream().map(prov -> {
415             List<PeerEndpoint> peers = consumers.stream()
416                 .map(client -> new PeerEndpointBuilder()
417                     .setKey(KeyFactory.peerEndpointKey(client.getKey()))
418                     .setRuleGroupWithRendererEndpointParticipation(Arrays.asList(RULE_GROUP_WITH_PROVIDER))
419                     .build())
420                 .collect(Collectors.toList());
421             return new RendererEndpointBuilder().setKey(KeyFactory.rendererEndpointKey(prov.getKey()))
422                 .setPeerEndpoint(peers)
423                 .build();
424         }).collect(Collectors.toList());
425         List<RendererEndpoint> rendererEps = Stream
426             .concat(consumersAsRendererEps.stream(), providersAsRendererEps.stream()).collect(Collectors.toList());
427         return new ConfigurationBuilder().setEndpoints(endpoints)
428             .setRendererEndpoints(new RendererEndpointsBuilder().setRendererEndpoint(rendererEps).build())
429             .setRuleGroups(new RuleGroupsBuilder().setRuleGroup(Arrays.asList(RULE_GROUP)).build())
430             .build();
431     }
432
433     private void assertProviderAddressEndpointLocation(AddressEndpointWithLocationKey expectedEpKey,
434             AbsoluteLocation expectedEpLoc, List<ProviderAddressEndpointLocation> providerEpLocs) {
435         List<ProviderAddressEndpointLocation> expectedProvEpLoc =
436                 providerEpLocs.stream()
437                     .filter(provEpLoc -> provEpLoc.getKey()
438                         .equals(KeyFactory.providerAddressEndpointLocationKey(expectedEpKey)))
439                     .collect(Collectors.toList());
440         Assert.assertFalse(expectedProvEpLoc.isEmpty());
441         Assert.assertEquals(1, expectedProvEpLoc.size());
442         Assert.assertEquals(expectedEpLoc, expectedProvEpLoc.get(0).getAbsoluteLocation());
443     }
444
445     private Interface readAndAssertInterface(String expectedInterface) throws Exception {
446         ReadOnlyTransaction rTxMount = mountPointDataBroker.newReadOnlyTransaction();
447         Optional<Interface> potentialIface = rTxMount.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
448             .builder(Interfaces.class).child(Interface.class, new InterfaceKey(expectedInterface)).build()).get();
449         Assert.assertTrue(potentialIface.isPresent());
450         return potentialIface.get();
451     }
452
453     private static void assertBridgeDomainOnInterface(String expectedBridgeDomain, Interface actualIface) {
454         VppInterfaceAugmentation vppIfaceAug = actualIface.getAugmentation(VppInterfaceAugmentation.class);
455         Assert.assertNotNull(vppIfaceAug);
456         if (!Strings.isNullOrEmpty(expectedBridgeDomain)) {
457             Interconnection interconnection = vppIfaceAug.getL2().getInterconnection();
458             Assert.assertNotNull(interconnection);
459             Assert.assertTrue(interconnection instanceof BridgeBased);
460             Assert.assertEquals(expectedBridgeDomain, ((BridgeBased) interconnection).getBridgeDomain());
461         } else {
462             if (vppIfaceAug != null) {
463                 L2 l2 = vppIfaceAug.getL2();
464                 if (l2 != null) {
465                     Assert.assertNull(l2.getInterconnection());
466                 }
467             }
468         }
469     }
470
471     private void storeVppEndpoint(AddressEndpointWithLocationKey epKey, String ifaceName,
472             InstanceIdentifier<VppEndpoint> vppEpIid) {
473         VppEndpoint vhostEp = new VppEndpointBuilder().setAddress(epKey.getAddress())
474             .setAddressType(epKey.getAddressType())
475             .setContextId(epKey.getContextId())
476             .setContextType(epKey.getContextType())
477             .setVppInterfaceName(ifaceName)
478             .setVppNodePath(VPP_NODE_1_IID)
479             .setInterfaceTypeChoice(new VhostUserCaseBuilder().setSocket(SOCKET).build())
480             .build();
481         VppEndpointConfEvent vppEpEvent = new VppEndpointConfEvent(vppEpIid, null, vhostEp);
482         ifaceManager.vppEndpointChanged(vppEpEvent);
483     }
484
485 }