Add INFO.yaml for GBP
[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 java.util.AbstractMap;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.List;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.locks.ReentrantLock;
18 import java.util.stream.Collectors;
19
20 import org.junit.Assert;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.mockito.Mockito;
25 import org.mockito.runners.MockitoJUnitRunner;
26 import org.opendaylight.controller.config.yang.config.vpp_provider.impl.VppRenderer;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
29 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
30 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
31 import org.opendaylight.groupbasedpolicy.renderer.vpp.DtoFactory;
32 import org.opendaylight.groupbasedpolicy.renderer.vpp.dhcp.DhcpRelayHandler;
33 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.RendererPolicyConfEvent;
34 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.VppEndpointConfEvent;
35 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
36 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppEndpointLocationProvider;
37 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
38 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.flat.overlay.FlatOverlayManager;
39 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.loopback.LoopbackManager;
40 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppEndpointListener;
41 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.CentralizedNatImpl;
42 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
43 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
44 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
45 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
46 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
47 import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
48 import org.opendaylight.groupbasedpolicy.util.IidFactory;
49 import org.opendaylight.vbd.impl.transaction.VbdNetconfTransaction;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.Endpoints;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpoints;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointKey;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.LocationProviders;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocation;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.L2FloodDomain;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.L2BridgeDomain;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.MacAddressType;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes._interface.type.choice.VhostUserCaseBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.bridge.domain.base.attributes.PhysicalLocationRef;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.VppAclInterfaceAugmentation;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.BridgeDomains;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.VppInterfaceAugmentation;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.VxlanVni;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.L2;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.Interconnection;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.l2.config.attributes.interconnection.BridgeBased;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev170327.TunnelTypeVxlan;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev170327.network.topology.topology.tunnel.parameters.VxlanTunnelParameters;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev170615.access.lists.acl.access.list.entries.ace.matches.ace.type.VppAce;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev170816._interface.nat.attributes.Nat;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
95 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
96 import org.slf4j.Logger;
97 import org.slf4j.LoggerFactory;
98
99 import com.google.common.base.Optional;
100 import com.google.common.base.Strings;
101 import com.google.common.collect.Lists;
102 import com.google.common.eventbus.EventBus;
103
104 @RunWith(MockitoJUnitRunner.class)
105 public class VppRendererPolicyManagerTest extends CustomDataBrokerTest {
106
107     private static final Logger LOG = LoggerFactory.getLogger(VppRendererPolicyManagerTest.class);
108     private static final InstanceIdentifier<RendererPolicy> RENDERER_POLICY_IID =
109             IidFactory.rendererIid(VppRenderer.NAME).child(RendererPolicy.class);
110     private final static String SOCKET = "socket";
111     private static final String CLIENT_MAC = "10:00:00:00:00:01";
112     private static final String CLIENT_MAC_2 = "10:00:00:00:00:02";
113     private static final String WEB_MAC = "10:00:00:00:00:01";
114     private static final String WEB_MAC_2 = "10:00:00:00:00:02";
115     private static final String WEB_IP_2 = "20.0.0.2/32";
116     private static final String CLIENT_IP_2 = "10.0.0.2/32";
117     private static final String WEB_IP = "20.0.0.1/32";
118     private static final String CLIENT_IP = "10.0.0.1/32";
119     private static final String CLIENT_1_IFACE_NAME = "client1";
120     private static final String CLIENT_2_IFACE_NAME = "client2";
121     private static final String WEB_2_IFACE_NAME = "web2";
122     private static final String WEB_1_IFACE_NAME = "web1";
123
124     public static final TenantId TENANT = new TenantId("tenant");
125     public static final List<EndpointGroupId>
126         ENDPOINT_GROUP =
127         Collections.singletonList(new EndpointGroupId("default"));
128
129     private MountedDataBrokerProvider mountedDataProviderMock;
130     private DataBroker mountPointDataBroker;
131     private DataBroker dataBroker;
132
133     private BridgeDomainManagerImpl bdManager;
134     private InterfaceManager ifaceManager;
135     private AclManager aclManager;
136     private ForwardingManager fwManager;
137     private NatManager natManager;
138     private RoutingManager routingManager;
139     private LispStateManager lispStateManager;
140     private LoopbackManager loopbackManager;
141     private FlatOverlayManager flatOverlayManager;
142     private DhcpRelayHandler dhcpRelayHandler;
143     private VppRendererPolicyManager vppRendererPolicyManager;
144     private VppEndpointListener vppEndpointListener;
145
146     @Override
147     public Collection<Class<?>> getClassesFromModules() {
148         return Arrays.asList(Node.class, VppEndpoint.class, Interfaces.class, BridgeDomains.class,
149                 LocationProviders.class, L2FloodDomain.class, VxlanVni.class, TopologyVbridgeAugment.class,
150                 TunnelTypeVxlan.class, PhysicalLocationRef.class, AccessLists.class, VppAce.class,
151                 VppInterfaceAugmentation.class, VppAclInterfaceAugmentation.class, VxlanTunnelParameters.class,
152                 PhysicalLocationRef.class, Nat.class);
153         }
154
155     @Before
156     public void init() throws Exception {
157         mountedDataProviderMock = Mockito.mock(MountedDataBrokerProvider.class);
158         mountPointDataBroker = getDataBroker();
159         EventBus dtoEventBus = new EventBus((exception, context) -> LOG.error("Could not dispatch event: {} to {}",
160             context.getSubscriber(), context.getSubscriberMethod(), exception));
161         setup(); // initialize new data broker for ODL data store
162         dataBroker = getDataBroker();
163         Mockito.when(mountedDataProviderMock.resolveDataBrokerForMountPoint(Mockito.any(InstanceIdentifier.class)))
164             .thenReturn(Optional.of(mountPointDataBroker));
165         vppEndpointListener = new VppEndpointListener(dataBroker, dtoEventBus);
166         lispStateManager = new LispStateManager();
167         loopbackManager = new LoopbackManager();
168         flatOverlayManager = new FlatOverlayManager(dataBroker, mountedDataProviderMock, vppEndpointListener);
169         ifaceManager = new InterfaceManager(mountedDataProviderMock, dataBroker);
170         aclManager = new AclManager(mountedDataProviderMock, ifaceManager);
171         natManager = new CentralizedNatImpl(dataBroker);
172         routingManager = new RoutingManager(dataBroker, mountedDataProviderMock);
173         bdManager = new BridgeDomainManagerImpl(mountPointDataBroker);
174         dhcpRelayHandler = new DhcpRelayHandler(dataBroker);
175         fwManager = new ForwardingManager(ifaceManager, aclManager, natManager, routingManager, bdManager,
176                 lispStateManager, loopbackManager, flatOverlayManager, dhcpRelayHandler, dataBroker);
177         vppRendererPolicyManager = new VppRendererPolicyManager(fwManager, aclManager, dataBroker);
178         fwManager.setTimer((byte) 1);
179         VbdNetconfTransaction.NODE_DATA_BROKER_MAP.put(DtoFactory.VPP_NODE_1_IID,
180                 new AbstractMap.SimpleEntry<DataBroker, ReentrantLock>(mountPointDataBroker, new ReentrantLock()));
181         VbdNetconfTransaction.NODE_DATA_BROKER_MAP.put(DtoFactory.VPP_NODE_2_IID,
182                 new AbstractMap.SimpleEntry<DataBroker, ReentrantLock>(mountPointDataBroker, new ReentrantLock()));
183     }
184
185     @Test
186     public void testRendererPolicyChanged_created_oneEpPerEpg() throws Exception {
187         AbsoluteLocation clientLocation =
188                 DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, CLIENT_1_IFACE_NAME);
189         AddressEndpointWithLocation clientEp =
190                 DtoFactory.createEndpoint(CLIENT_IP, CLIENT_MAC, DtoFactory.L2FD_CTX.getValue(), clientLocation);
191         AbsoluteLocation webLocation = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, WEB_1_IFACE_NAME);
192         AddressEndpointWithLocation webEp =
193                 DtoFactory.createEndpoint(WEB_IP, WEB_MAC, DtoFactory.L2FD_CTX.getValue(), webLocation);
194
195         storeVppEndpoint(clientEp.getKey(), CLIENT_MAC, CLIENT_1_IFACE_NAME, createVppEndpointIid(clientEp.getKey()));
196         storeVppEndpoint(webEp.getKey(), WEB_MAC, WEB_1_IFACE_NAME, createVppEndpointIid(webEp.getKey()));
197
198         Configuration configuration = DtoFactory.createConfiguration(Collections.singletonList(clientEp),
199             Collections.singletonList(webEp));
200         RendererPolicy rendererPolicy =
201                 new RendererPolicyBuilder().setVersion(1L).setConfiguration(configuration).build();
202         RendererPolicyConfEvent event = new RendererPolicyConfEvent(RENDERER_POLICY_IID, null, rendererPolicy);
203
204         vppRendererPolicyManager.rendererPolicyChanged(event);
205
206         // assert state on data store behind mount point
207         Interface clientIface = readAndAssertInterface(CLIENT_1_IFACE_NAME);
208         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), clientIface);
209         Interface webIface = readAndAssertInterface(WEB_1_IFACE_NAME);
210         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), webIface);
211         // assert state on ODL data store
212         ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
213         Optional<LocationProvider> optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
214                 IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
215             .get();
216         Assert.assertTrue(optLocationProvider.isPresent());
217         List<ProviderAddressEndpointLocation> epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
218         Assert.assertNotNull(epLocs);
219         Assert.assertEquals(2, epLocs.size());
220         assertProviderAddressEndpointLocation(clientEp.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
221                 DtoFactory.L2FD_CTX.getValue(), CLIENT_1_IFACE_NAME), epLocs);
222         assertProviderAddressEndpointLocation(webEp.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
223                 DtoFactory.L2FD_CTX.getValue(), WEB_1_IFACE_NAME), epLocs);
224     }
225
226     @Test
227     public void testRendererPolicyChanged_update() throws Exception {
228         AbsoluteLocation client1LocationNodeNull =
229                 DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, CLIENT_1_IFACE_NAME);
230         AddressEndpointWithLocation client1Ep = DtoFactory.createEndpoint(CLIENT_IP, CLIENT_MAC,
231                 DtoFactory.L2FD_CTX.getValue(), client1LocationNodeNull);
232         AbsoluteLocation web1LocationNodeNull =
233                 DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID, null, WEB_1_IFACE_NAME);
234         AddressEndpointWithLocation web1Ep =
235                 DtoFactory.createEndpoint(WEB_IP, WEB_MAC, DtoFactory.L2FD_CTX.getValue(), web1LocationNodeNull);
236         AbsoluteLocation client2LocationNodeNull =
237                 DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, CLIENT_2_IFACE_NAME);
238         AddressEndpointWithLocation client2Ep = DtoFactory.createEndpoint(CLIENT_IP_2, CLIENT_MAC_2,
239                 DtoFactory.L2FD_CTX.getValue(), client2LocationNodeNull);
240         AbsoluteLocation web2LocationNodeNull =
241                 DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID, null, WEB_2_IFACE_NAME);
242         AddressEndpointWithLocation web2Ep =
243                 DtoFactory.createEndpoint(WEB_IP_2, WEB_MAC_2, DtoFactory.L2FD_CTX.getValue(), web2LocationNodeNull);
244
245         storeVppEndpoint(client1Ep.getKey(), CLIENT_MAC, CLIENT_1_IFACE_NAME, createVppEndpointIid(client1Ep.getKey()));
246         storeVppEndpoint(web1Ep.getKey(), WEB_MAC, WEB_1_IFACE_NAME, createVppEndpointIid(web1Ep.getKey()));
247         storeVppEndpoint(client2Ep.getKey(), CLIENT_MAC_2, CLIENT_2_IFACE_NAME,
248                 createVppEndpointIid(client2Ep.getKey()));
249         storeVppEndpoint(web2Ep.getKey(), WEB_MAC_2, WEB_2_IFACE_NAME, createVppEndpointIid(web2Ep.getKey()));
250
251         Configuration configuration =
252                 DtoFactory.createConfiguration(Arrays.asList(client1Ep, client2Ep), Arrays.asList(web1Ep, web2Ep));
253         RendererPolicy rendererPolicy =
254                 new RendererPolicyBuilder().setVersion(1L).setConfiguration(configuration).build();
255         RendererPolicyConfEvent event = new RendererPolicyConfEvent(RENDERER_POLICY_IID, null, rendererPolicy);
256
257         vppRendererPolicyManager.rendererPolicyChanged(event);
258
259         // assert state on data store behind mount point ######################################
260         Interface client1Iface = readAndAssertInterface(CLIENT_1_IFACE_NAME);
261         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), client1Iface);
262         Interface web1Iface = readAndAssertInterface(WEB_1_IFACE_NAME);
263         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), web1Iface);
264         Interface client2Iface = readAndAssertInterface(CLIENT_2_IFACE_NAME);
265         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), client2Iface);
266         Interface web2Iface = readAndAssertInterface(WEB_2_IFACE_NAME);
267         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), web2Iface);
268         // assert state on ODL data store
269         ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
270         Optional<LocationProvider> optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
271                 IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
272             .get();
273         Assert.assertTrue(optLocationProvider.isPresent());
274         List<ProviderAddressEndpointLocation> epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
275         Assert.assertNotNull(epLocs);
276         Assert.assertEquals(4, epLocs.size());
277         assertProviderAddressEndpointLocation(client1Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
278                 DtoFactory.L2FD_CTX.getValue(), CLIENT_1_IFACE_NAME), epLocs);
279         assertProviderAddressEndpointLocation(web1Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID,
280                 DtoFactory.L2FD_CTX.getValue(), WEB_1_IFACE_NAME), epLocs);
281         assertProviderAddressEndpointLocation(client2Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
282                 DtoFactory.L2FD_CTX.getValue(), CLIENT_2_IFACE_NAME), epLocs);
283         assertProviderAddressEndpointLocation(web2Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID,
284                 DtoFactory.L2FD_CTX.getValue(), WEB_2_IFACE_NAME), epLocs);
285         // #####################################################################################
286
287         AbsoluteLocation client1Location = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
288                 DtoFactory.L2FD_CTX.getValue(), CLIENT_1_IFACE_NAME);
289         AbsoluteLocation web1Location = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID,
290                 DtoFactory.L2FD_CTX.getValue(), WEB_1_IFACE_NAME);
291         AbsoluteLocation web2Location = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID,
292                 DtoFactory.L2FD_CTX.getValue(), WEB_2_IFACE_NAME);
293         configuration = DtoFactory.createConfiguration(
294                 Arrays.asList(new AddressEndpointWithLocationBuilder(client1Ep).setAbsoluteLocation(client1Location)
295                     .build(),
296                         new AddressEndpointWithLocationBuilder(client2Ep).setAbsoluteLocation(client2LocationNodeNull)
297                             .build()),
298                 Arrays.asList(new AddressEndpointWithLocationBuilder(web1Ep).setAbsoluteLocation(web1Location).build(),
299                         new AddressEndpointWithLocationBuilder(web2Ep).setAbsoluteLocation(web2Location).build()));
300         RendererPolicy rendererPolicy2 =
301                 new RendererPolicyBuilder().setVersion(2L).setConfiguration(configuration).build();
302         RendererPolicyConfEvent event2 =
303                 new RendererPolicyConfEvent(RENDERER_POLICY_IID, rendererPolicy, rendererPolicy2);
304
305         vppRendererPolicyManager.rendererPolicyChanged(event2);
306
307         // assert state on data store behind mount point ######################################
308         client1Iface = readAndAssertInterface(CLIENT_1_IFACE_NAME);
309         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), client1Iface);
310         web1Iface = readAndAssertInterface(WEB_1_IFACE_NAME);
311         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), web1Iface);
312         client2Iface = readAndAssertInterface(CLIENT_2_IFACE_NAME);
313         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), client2Iface);
314         web2Iface = readAndAssertInterface(WEB_2_IFACE_NAME);
315         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), web2Iface);
316         // assert state on ODL data store
317         rTx = dataBroker.newReadOnlyTransaction();
318         optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
319                 IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
320             .get();
321         Assert.assertTrue(optLocationProvider.isPresent());
322         epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
323         Assert.assertNotNull(epLocs);
324         Assert.assertEquals(4, epLocs.size());
325         assertProviderAddressEndpointLocation(client1Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
326                 DtoFactory.L2FD_CTX.getValue(), CLIENT_1_IFACE_NAME), epLocs);
327         assertProviderAddressEndpointLocation(web1Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID,
328                 DtoFactory.L2FD_CTX.getValue(), WEB_1_IFACE_NAME), epLocs);
329         assertProviderAddressEndpointLocation(client2Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
330                 DtoFactory.L2FD_CTX.getValue(), CLIENT_2_IFACE_NAME), epLocs);
331         assertProviderAddressEndpointLocation(web2Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID,
332                 DtoFactory.L2FD_CTX.getValue(), WEB_2_IFACE_NAME), epLocs);
333         // #####################################################################################
334
335         AbsoluteLocation client2Location = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
336                 DtoFactory.L2FD_CTX.getValue(), CLIENT_2_IFACE_NAME);
337         configuration = DtoFactory.createConfiguration(
338                 Arrays.asList(new AddressEndpointWithLocationBuilder(client1Ep).setAbsoluteLocation(client1Location)
339                     .build(),
340                         new AddressEndpointWithLocationBuilder(client2Ep).setAbsoluteLocation(client2Location).build()),
341                 Arrays.asList(new AddressEndpointWithLocationBuilder(web1Ep).setAbsoluteLocation(web1Location).build(),
342                         new AddressEndpointWithLocationBuilder(web2Ep).setAbsoluteLocation(web2Location).build()));
343         RendererPolicy rendererPolicy3 =
344                 new RendererPolicyBuilder().setVersion(3L).setConfiguration(configuration).build();
345         RendererPolicyConfEvent event3 =
346                 new RendererPolicyConfEvent(RENDERER_POLICY_IID, rendererPolicy2, rendererPolicy3);
347
348         vppRendererPolicyManager.rendererPolicyChanged(event3);
349
350         // assert state on data store behind mount point ######################################
351         client1Iface = readAndAssertInterface(CLIENT_1_IFACE_NAME);
352         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), client1Iface);
353         web1Iface = readAndAssertInterface(WEB_1_IFACE_NAME);
354         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), web1Iface);
355         client2Iface = readAndAssertInterface(CLIENT_2_IFACE_NAME);
356         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), client2Iface);
357         web2Iface = readAndAssertInterface(WEB_2_IFACE_NAME);
358         assertBridgeDomainOnInterface(DtoFactory.L2FD_CTX.getValue(), web2Iface);
359         // assert state on ODL data store
360         rTx = dataBroker.newReadOnlyTransaction();
361         optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
362                 IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
363             .get();
364         Assert.assertTrue(optLocationProvider.isPresent());
365         epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
366         Assert.assertNotNull(epLocs);
367         Assert.assertEquals(4, epLocs.size());
368         assertProviderAddressEndpointLocation(client1Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
369                 DtoFactory.L2FD_CTX.getValue(), CLIENT_1_IFACE_NAME), epLocs);
370         assertProviderAddressEndpointLocation(web1Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID,
371                 DtoFactory.L2FD_CTX.getValue(), WEB_1_IFACE_NAME), epLocs);
372         assertProviderAddressEndpointLocation(client2Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID,
373                 DtoFactory.L2FD_CTX.getValue(), CLIENT_2_IFACE_NAME), epLocs);
374         assertProviderAddressEndpointLocation(web2Ep.getKey(), DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID,
375                 DtoFactory.L2FD_CTX.getValue(), WEB_2_IFACE_NAME), epLocs);
376         // #####################################################################################
377     }
378
379     private InstanceIdentifier<VppEndpoint> createVppEndpointIid(AddressEndpointWithLocationKey key) {
380         return InstanceIdentifier.builder(Config.class)
381             .child(VppEndpoint.class, new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(),
382                     key.getContextType()))
383             .build();
384     }
385
386     private void assertProviderAddressEndpointLocation(AddressEndpointWithLocationKey expectedEpKey,
387             AbsoluteLocation expectedEpLoc, List<ProviderAddressEndpointLocation> providerEpLocs) {
388         List<ProviderAddressEndpointLocation> expectedProvEpLoc =
389                 providerEpLocs.stream()
390                     .filter(provEpLoc -> provEpLoc.getKey()
391                         .equals(KeyFactory.providerAddressEndpointLocationKey(expectedEpKey)))
392                     .collect(Collectors.toList());
393         Assert.assertFalse(expectedProvEpLoc.isEmpty());
394         Assert.assertEquals(1, expectedProvEpLoc.size());
395         Assert.assertEquals(expectedEpLoc, expectedProvEpLoc.get(0).getAbsoluteLocation());
396     }
397
398     private Interface readAndAssertInterface(String expectedInterface) throws Exception {
399         ReadOnlyTransaction rTxMount = mountPointDataBroker.newReadOnlyTransaction();
400         Optional<Interface> potentialIface = rTxMount.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
401             .builder(Interfaces.class).child(Interface.class, new InterfaceKey(expectedInterface)).build()).get();
402         Assert.assertTrue(potentialIface.isPresent());
403         return potentialIface.get();
404     }
405
406     private static void assertBridgeDomainOnInterface(String expectedBridgeDomain, Interface actualIface) {
407         VppInterfaceAugmentation vppIfaceAug = actualIface.getAugmentation(VppInterfaceAugmentation.class);
408         Assert.assertNotNull(vppIfaceAug);
409         if (!Strings.isNullOrEmpty(expectedBridgeDomain)) {
410             Interconnection interconnection = vppIfaceAug.getL2().getInterconnection();
411             Assert.assertNotNull(interconnection);
412             Assert.assertTrue(interconnection instanceof BridgeBased);
413             Assert.assertEquals(expectedBridgeDomain, ((BridgeBased) interconnection).getBridgeDomain());
414         } else {
415             L2 l2 = vppIfaceAug.getL2();
416             if (l2 != null) {
417                 Assert.assertNull(l2.getInterconnection());
418             }
419         }
420     }
421
422     private void storeVppEndpoint(AddressEndpointWithLocationKey clientEp, String mac, String ifaceName,
423             InstanceIdentifier<VppEndpoint> vppEpIid) {
424         AddressEndpoint addrEp = new AddressEndpointBuilder()
425             .setKey(new AddressEndpointKey(clientEp.getAddress(), clientEp.getAddressType(), clientEp.getContextId(),
426                     clientEp.getContextType()))
427             .setTenant(TENANT)
428             .setEndpointGroup(ENDPOINT_GROUP)
429             .setChildEndpoint(Lists.newArrayList(new ChildEndpointBuilder()
430                 .setKey(new ChildEndpointKey(mac, MacAddressType.class, clientEp.getContextId(), L2BridgeDomain.class))
431                 .build()))
432             .build();
433         InstanceIdentifier<AddressEndpoint> iid = InstanceIdentifier.create(Endpoints.class)
434             .child(AddressEndpoints.class)
435             .child(AddressEndpoint.class, addrEp.getKey());
436         WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
437         wTx.put(LogicalDatastoreType.OPERATIONAL, iid, addrEp);
438         try {
439             wTx.submit().get();
440         } catch (InterruptedException | ExecutionException e) {
441             e.printStackTrace();
442         }
443
444         VppEndpoint vhostEp = new VppEndpointBuilder().setAddress(mac)
445             .setAddressType(MacAddressType.class)
446             .setContextId(clientEp.getContextId())
447             .setContextType(L2BridgeDomain.class)
448             .setVppInterfaceName(ifaceName)
449             .setVppNodeId(DtoFactory.VPP_NODE_1_IID.firstKeyOf(Node.class).getNodeId())
450             .setInterfaceTypeChoice(new VhostUserCaseBuilder().setSocket(SOCKET).build())
451             .build();
452         VppEndpointConfEvent vppEpEvent = new VppEndpointConfEvent(vppEpIid, null, vhostEp);
453         ifaceManager.vppEndpointChanged(vppEpEvent);
454     }
455
456 }