Fixes for DVR
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / controller / config / yang / config / vpp_provider / impl / VppRenderer.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.controller.config.yang.config.vpp_provider.impl;
10
11 import java.util.ArrayList;
12 import java.util.List;
13
14 import javax.annotation.Nonnull;
15 import javax.annotation.Nullable;
16
17 import com.google.common.util.concurrent.MoreExecutors;
18
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
21 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
24 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
25 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
26 import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
27 import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil;
28 import org.opendaylight.groupbasedpolicy.renderer.vpp.dhcp.DhcpRelayHandler;
29 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
30 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
31 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.event.manager.GbpSubnetEventManager;
32 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.flat.overlay.FlatOverlayManager;
33 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.loopback.LoopbackManager;
34 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.GbpSubnetListener;
35 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.RendererPolicyListener;
36 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppEndpointListener;
37 import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppNodeListener;
38 import org.opendaylight.groupbasedpolicy.renderer.vpp.manager.VppNodeManager;
39 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.CentralizedNatImpl;
40 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.DvrNatImpl;
41 import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager;
42 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.BridgeDomainManagerImpl;
43 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.ForwardingManager;
44 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.VppRendererPolicyManager;
45 import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager;
46 import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager;
47 import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.AllowAction;
48 import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.Classifier;
49 import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.EtherTypeClassifier;
50 import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.IpProtoClassifier;
51 import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.L4Classifier;
52 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
53 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.CapabilitiesBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodesBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedActionDefinition;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedActionDefinitionBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinition;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinitionBuilder;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67 import com.google.common.base.Preconditions;
68 import com.google.common.collect.ImmutableList;
69 import com.google.common.eventbus.EventBus;
70 import com.google.common.util.concurrent.CheckedFuture;
71 import com.google.common.util.concurrent.FutureCallback;
72 import com.google.common.util.concurrent.Futures;
73
74 public class VppRenderer implements AutoCloseable, BindingAwareProvider {
75
76     public static final RendererName NAME = new RendererName("vpp-renderer");
77     private static final Logger LOG = LoggerFactory.getLogger(VppRenderer.class);
78     private final List<SupportedActionDefinition> actionDefinitions =
79             ImmutableList.of(new SupportedActionDefinitionBuilder().setActionDefinitionId(new AllowAction().getId())
80                     .setSupportedParameterValues(new AllowAction().getSupportedParameterValues())
81                     .build());
82     private final List<SupportedClassifierDefinition> classifierDefinitions;
83
84     private final DataBroker dataBroker;
85     private final String publicInterfaces;
86     private InterfaceManager interfaceManager;
87     private MountedDataBrokerProvider mountDataProvider;
88     private BridgeDomainManager bdManager;
89     private VppNodeListener vppNodeListener;
90     private VppEndpointListener vppEndpointListener;
91     private RendererPolicyListener rendererPolicyListener;
92     private GbpSubnetListener vppGbpSubnetListener;
93     private GbpSubnetEventManager subnetEventManager;
94
95     VppRenderer(@Nonnull DataBroker dataBroker, @Nonnull BindingAwareBroker bindingAwareBroker,
96                        @Nullable String publicInterfaces) {
97         this.dataBroker = Preconditions.checkNotNull(dataBroker);
98         this.publicInterfaces = publicInterfaces;
99         bindingAwareBroker.registerProvider(this);
100         EtherTypeClassifier etherTypeClassifier = new EtherTypeClassifier(null);
101         IpProtoClassifier ipProtoClassifier = new IpProtoClassifier(etherTypeClassifier);
102         classifierDefinitions =
103                 buildClassifierDefinitions(etherTypeClassifier, ipProtoClassifier, new L4Classifier(ipProtoClassifier));
104     }
105
106     private List<SupportedClassifierDefinition> buildClassifierDefinitions(Classifier... classifs) {
107         List<SupportedClassifierDefinition> clDefs = new ArrayList<>();
108         SupportedClassifierDefinitionBuilder clDefBuilder = new SupportedClassifierDefinitionBuilder();
109         for (Classifier classif : classifs) {
110             if (classif.getParent() != null) {
111                 clDefBuilder.setParentClassifierDefinitionId(classif.getParent().getId());
112             }
113             clDefs.add(clDefBuilder.setClassifierDefinitionId(classif.getId())
114                     .setSupportedParameterValues(classif.getSupportedParameterValues())
115                     .build());
116         }
117         return clDefs;
118     }
119
120     @Override
121     public void close() throws Exception {
122         LOG.info("Closing Vpp renderer");
123         if (vppNodeListener != null) {
124             vppNodeListener.close();
125         }
126         if (vppEndpointListener != null) {
127             vppEndpointListener.close();
128         }
129         if (rendererPolicyListener != null) {
130             rendererPolicyListener.close();
131         }
132         if (interfaceManager != null) {
133             interfaceManager.close();
134         }
135
136         if (vppGbpSubnetListener != null) {
137             vppGbpSubnetListener.close();
138         }
139         unregisterFromRendererManager();
140     }
141
142     @Override
143     public void onSessionInitiated(BindingAwareBroker.ProviderContext providerContext) {
144         LOG.info("starting vpp renderer");
145
146         MountPointService mountService =
147                 Preconditions.checkNotNull(providerContext.getSALService(MountPointService.class));
148         mountDataProvider = new MountedDataBrokerProvider(mountService, dataBroker);
149         VppNodeManager vppNodeManager = new VppNodeManager(dataBroker, providerContext, publicInterfaces);
150         EventBus dtoEventBus = new EventBus((exception, context) -> LOG.error("Could not dispatch event: {} to {}",
151                 context.getSubscriber(), context.getSubscriberMethod(), exception));
152         vppEndpointListener = new VppEndpointListener(dataBroker, dtoEventBus);
153         LispStateManager lispStateManager = new LispStateManager(mountDataProvider);
154         FlatOverlayManager flatOverlayManager = new FlatOverlayManager(dataBroker, mountDataProvider, vppEndpointListener);
155         LoopbackManager loopbackManager = new LoopbackManager(mountDataProvider);
156
157         interfaceManager = new InterfaceManager(mountDataProvider, dataBroker, flatOverlayManager);
158         AclManager aclManager = new AclManager(mountDataProvider, interfaceManager);
159         NatManager natManager =
160             (ConfigUtil.getInstance().isL3FlatEnabled()) ? new DvrNatImpl(dataBroker) : new CentralizedNatImpl(
161                 dataBroker);
162         LOG.info("Instantiated NAT manager implementation {}", natManager.getClass());
163         subnetEventManager = new GbpSubnetEventManager(loopbackManager);
164         dtoEventBus.register(interfaceManager);
165         dtoEventBus.register(subnetEventManager);
166         RoutingManager routingManager = new RoutingManager(dataBroker, mountDataProvider);
167         DhcpRelayHandler dhcpRelayHandler = new DhcpRelayHandler(dataBroker);
168         bdManager = new BridgeDomainManagerImpl(dataBroker);
169         ForwardingManager fwManager =
170                 new ForwardingManager(interfaceManager, aclManager, natManager, routingManager, bdManager,
171                         lispStateManager, loopbackManager, flatOverlayManager, dhcpRelayHandler, dataBroker);
172         VppRendererPolicyManager vppRendererPolicyManager =
173             new VppRendererPolicyManager(fwManager, aclManager, dataBroker);
174         dtoEventBus.register(vppRendererPolicyManager);
175
176         vppNodeListener = new VppNodeListener(dataBroker, vppNodeManager, dtoEventBus);
177         rendererPolicyListener = new RendererPolicyListener(dataBroker, dtoEventBus);
178         vppGbpSubnetListener = new GbpSubnetListener(dataBroker, dtoEventBus);
179         registerToRendererManager();
180     }
181
182     private void registerToRendererManager() {
183         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
184
185         Renderer renderer = new RendererBuilder().setName(VppRenderer.NAME)
186                 .setRendererNodes(new RendererNodesBuilder().build())
187                 .setCapabilities(new CapabilitiesBuilder().setSupportedActionDefinition(actionDefinitions)
188                         .setSupportedClassifierDefinition(classifierDefinitions)
189                         .build())
190                 .build();
191
192         writeTransaction.put(LogicalDatastoreType.OPERATIONAL, VppIidFactory.getRendererIID(renderer.getKey()),
193                 renderer, true);
194         CheckedFuture<Void, TransactionCommitFailedException> future = writeTransaction.submit();
195         Futures.addCallback(future, new FutureCallback<Void>() {
196
197             @Override
198             public void onFailure(@Nonnull Throwable throwable) {
199                 LOG.error("Could not register renderer {}: {}", renderer, throwable);
200             }
201
202             @Override
203             public void onSuccess(Void result) {
204                 LOG.debug("Renderer {} successfully registered.", renderer);
205             }
206         }, MoreExecutors.directExecutor());
207     }
208
209     private void unregisterFromRendererManager() {
210         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
211         writeTransaction.delete(LogicalDatastoreType.OPERATIONAL,
212                 VppIidFactory.getRendererIID(new RendererKey(VppRenderer.NAME)));
213
214         CheckedFuture<Void, TransactionCommitFailedException> future = writeTransaction.submit();
215         Futures.addCallback(future, new FutureCallback<Void>() {
216
217             @Override
218             public void onFailure(@Nonnull Throwable throwable) {
219                 LOG.error("Could not unregister renderer {}: {}", VppRenderer.NAME, throwable);
220             }
221
222             @Override
223             public void onSuccess(Void result) {
224                 LOG.debug("Renderer {} successfully unregistered.", VppRenderer.NAME);
225             }
226         }, MoreExecutors.directExecutor());
227     }
228
229     public MountedDataBrokerProvider getMountedDataBroker() {
230         return mountDataProvider;
231     }
232
233     public InterfaceManager getInterfaceManager() {
234         return interfaceManager;
235     }
236
237     public BridgeDomainManager getBridgeDomainManager() {
238         return bdManager;
239     }
240 }