Bug 4132 config ovs to respond to pings to router
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / ConfigActivator.java
1 /*
2  * Copyright (c) 2015, 2016 Red Hat, 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.ovsdb.openstack.netvirt;
10
11 import java.util.ArrayList;
12 import java.util.Dictionary;
13 import java.util.Hashtable;
14 import java.util.List;
15
16 import org.apache.commons.lang3.tuple.Pair;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
20 import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
21 import org.opendaylight.ovsdb.openstack.netvirt.api.IcmpEchoProvider;
22 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
23 import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
24 import org.opendaylight.ovsdb.openstack.netvirt.api.ArpProvider;
25 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
26 import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
27 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
28 import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolver;
29 import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolverListener;
30 import org.opendaylight.ovsdb.openstack.netvirt.api.InboundNatProvider;
31 import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
32 import org.opendaylight.ovsdb.openstack.netvirt.api.L3ForwardingProvider;
33 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerProvider;
34 import org.opendaylight.ovsdb.openstack.netvirt.api.MultiTenantAwareRouter;
35 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
36 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheListener;
37 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
38 import org.opendaylight.ovsdb.openstack.netvirt.api.OutboundNatProvider;
39 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryListener;
40 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryService;
41 import org.opendaylight.ovsdb.openstack.netvirt.api.RoutingProvider;
42 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityGroupCacheManger;
43 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
44 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
45 import org.opendaylight.ovsdb.openstack.netvirt.impl.BridgeConfigurationManagerImpl;
46 import org.opendaylight.ovsdb.openstack.netvirt.impl.ConfigurationServiceImpl;
47 import org.opendaylight.ovsdb.openstack.netvirt.impl.EventDispatcherImpl;
48 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
49 import org.opendaylight.ovsdb.openstack.netvirt.impl.NodeCacheManagerImpl;
50 import org.opendaylight.ovsdb.openstack.netvirt.impl.OpenstackRouter;
51 import org.opendaylight.ovsdb.openstack.netvirt.impl.OvsdbInventoryServiceImpl;
52 import org.opendaylight.ovsdb.openstack.netvirt.impl.ProviderNetworkManagerImpl;
53 import org.opendaylight.ovsdb.openstack.netvirt.impl.SecurityGroupCacheManagerImpl;
54 import org.opendaylight.ovsdb.openstack.netvirt.impl.SecurityServicesImpl;
55 import org.opendaylight.ovsdb.openstack.netvirt.impl.SouthboundImpl;
56 import org.opendaylight.ovsdb.openstack.netvirt.impl.TenantNetworkManagerImpl;
57 import org.opendaylight.ovsdb.openstack.netvirt.impl.VlanConfigurationCacheImpl;
58 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronFloatingIPCRUD;
59 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerCRUD;
60 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerPoolCRUD;
61 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
62 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
63 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
64 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronFirewallInterface;
65 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronFirewallPolicyInterface;
66 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronFirewallRuleInterface;
67 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronFloatingIPInterface;
68 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerHealthMonitorInterface;
69 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerInterface;
70 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerListenerInterface;
71 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerPoolInterface;
72 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerPoolMemberInterface;
73 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronNetworkInterface;
74 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronPortInterface;
75 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronRouterInterface;
76 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronSecurityGroupInterface;
77 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronSecurityRuleInterface;
78 import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronSubnetInterface;
79 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFirewallAware;
80 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFirewallPolicyAware;
81 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFirewallRuleAware;
82 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFloatingIPAware;
83 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerAware;
84 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerPoolAware;
85 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerPoolMemberAware;
86 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronNetworkAware;
87 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronPortAware;
88 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronRouterAware;
89 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityGroupAware;
90 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityRuleAware;
91 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSubnetAware;
92 import org.opendaylight.ovsdb.utils.neutron.utils.NeutronModelsDataStoreHelper;
93 import org.osgi.framework.BundleActivator;
94 import org.osgi.framework.BundleContext;
95 import org.osgi.framework.ServiceReference;
96 import org.osgi.framework.ServiceRegistration;
97 import org.osgi.util.tracker.ServiceTracker;
98 import org.slf4j.Logger;
99 import org.slf4j.LoggerFactory;
100
101 public class ConfigActivator implements BundleActivator {
102     private static final Logger LOG = LoggerFactory.getLogger(ConfigActivator.class);
103     private List<ServiceRegistration<?>> translatorCRUDRegistrations = new ArrayList<>();
104     private List<Pair<Object, ServiceRegistration>> servicesAndRegistrations = new ArrayList<>();
105     private ProviderContext providerContext;
106     private boolean conntrackEnabled = false;
107
108     public ConfigActivator(ProviderContext providerContext) {
109         this.providerContext = providerContext;
110     }
111
112     @Override
113     public void start(BundleContext context) throws Exception {
114         LOG.info("ConfigActivator start:");
115         registerCRUDServiceProviders(context, this.providerContext);
116
117         ConfigurationServiceImpl configurationService = new ConfigurationServiceImpl();
118         registerService(context, new String[] {ConfigurationService.class.getName()},
119                 null, configurationService);
120
121         BridgeConfigurationManagerImpl bridgeConfigurationManager = new BridgeConfigurationManagerImpl();
122         registerService(context, new String[] {BridgeConfigurationManager.class.getName()},
123                 null, bridgeConfigurationManager);
124
125         final TenantNetworkManagerImpl tenantNetworkManager = new TenantNetworkManagerImpl();
126         registerService(context, new String[] {TenantNetworkManager.class.getName()},
127                 null, tenantNetworkManager);
128
129         VlanConfigurationCacheImpl vlanConfigurationCache = new VlanConfigurationCacheImpl();
130         registerService(context, new String[] {VlanConfigurationCache.class.getName()},
131                 null, vlanConfigurationCache);
132
133         FloatingIPHandler floatingIPHandler = new FloatingIPHandler();
134         registerAbstractHandlerService(context, new Class[] {INeutronFloatingIPAware.class},
135                 AbstractEvent.HandlerType.NEUTRON_FLOATING_IP, floatingIPHandler);
136
137         final NetworkHandler networkHandler = new NetworkHandler();
138         registerAbstractHandlerService(context, new Class[] {INeutronNetworkAware.class},
139                 AbstractEvent.HandlerType.NEUTRON_NETWORK, networkHandler);
140
141         SubnetHandler subnetHandler = new SubnetHandler();
142         registerAbstractHandlerService(context, new Class[] {INeutronSubnetAware.class},
143                 AbstractEvent.HandlerType.NEUTRON_SUBNET, subnetHandler);
144
145         PortHandler portHandler = new PortHandler();
146         registerAbstractHandlerService(context, new Class[] {INeutronPortAware.class},
147                 AbstractEvent.HandlerType.NEUTRON_PORT, portHandler);
148
149         RouterHandler routerHandler = new RouterHandler();
150         registerAbstractHandlerService(context, new Class[] {INeutronRouterAware.class},
151                 AbstractEvent.HandlerType.NEUTRON_ROUTER, routerHandler);
152
153         SouthboundHandler southboundHandler = new SouthboundHandler();
154         registerAbstractHandlerService(context, new Class[] {OvsdbInventoryListener.class, NodeCacheListener.class},
155                 AbstractEvent.HandlerType.SOUTHBOUND, southboundHandler);
156
157         final LBaaSHandler lBaaSHandler = new LBaaSHandler();
158         registerAbstractHandlerService(context, new Class[] {INeutronLoadBalancerAware.class, NodeCacheListener.class},
159                 AbstractEvent.HandlerType.NEUTRON_LOAD_BALANCER, lBaaSHandler);
160
161         final LBaaSPoolHandler lBaaSPoolHandler = new LBaaSPoolHandler();
162         registerAbstractHandlerService(context, new Class[] {INeutronLoadBalancerPoolAware.class},
163                 AbstractEvent.HandlerType.NEUTRON_LOAD_BALANCER_POOL, lBaaSPoolHandler);
164
165         final LBaaSPoolMemberHandler lBaaSPoolMemberHandler = new LBaaSPoolMemberHandler();
166         registerAbstractHandlerService(context, new Class[] {INeutronLoadBalancerPoolMemberAware.class},
167                 AbstractEvent.HandlerType.NEUTRON_LOAD_BALANCER_POOL_MEMBER, lBaaSPoolMemberHandler);
168
169         PortSecurityHandler portSecurityHandler = new PortSecurityHandler();
170         registerAbstractHandlerService(context,
171                 new Class[] {INeutronSecurityRuleAware.class, INeutronSecurityGroupAware.class},
172                 AbstractEvent.HandlerType.NEUTRON_PORT_SECURITY, portSecurityHandler);
173
174         final SecurityServicesImpl securityServices = new SecurityServicesImpl(conntrackEnabled);
175         registerService(context,
176                 new String[]{SecurityServicesManager.class.getName()}, null, securityServices);
177
178         final SecurityGroupCacheManger securityGroupCacheManger = new SecurityGroupCacheManagerImpl();
179         registerService(context,
180                         new String[]{SecurityGroupCacheManger.class.getName()}, null, securityGroupCacheManger);
181
182         registerService(context,
183                 new String[]{SecurityServicesManager.class.getName()}, null, securityServices);
184
185         FWaasHandler fWaasHandler = new FWaasHandler();
186         registerAbstractHandlerService(context,
187                 new Class[] {INeutronFirewallAware.class, INeutronFirewallRuleAware.class, INeutronFirewallPolicyAware.class},
188                 AbstractEvent.HandlerType.NEUTRON_FWAAS, fWaasHandler);
189
190         ProviderNetworkManagerImpl providerNetworkManager = new ProviderNetworkManagerImpl();
191         registerService(context,
192                 new String[]{NetworkingProviderManager.class.getName()}, null, providerNetworkManager);
193
194         EventDispatcherImpl eventDispatcher = new EventDispatcherImpl();
195         registerService(context,
196                 new String[]{EventDispatcher.class.getName()}, null, eventDispatcher);
197
198         Dictionary<String, Object> neutronL3AdapterProperties = new Hashtable<>();
199         neutronL3AdapterProperties.put(Constants.EVENT_HANDLER_TYPE_PROPERTY,
200                 AbstractEvent.HandlerType.NEUTRON_L3_ADAPTER);
201         final NeutronL3Adapter neutronL3Adapter = new NeutronL3Adapter(
202                 new NeutronModelsDataStoreHelper(this.providerContext.getSALService(DataBroker.class)));
203         registerService(context,
204                 new String[]{NeutronL3Adapter.class.getName(), GatewayMacResolverListener.class.getName()},
205                 neutronL3AdapterProperties, neutronL3Adapter);
206
207         OpenstackRouter openstackRouter = new OpenstackRouter();
208         registerService(context,
209                 new String[]{MultiTenantAwareRouter.class.getName()}, null, openstackRouter);
210
211         Southbound southbound = new SouthboundImpl(providerContext.getSALService(DataBroker.class));
212         registerService(context,
213                 new String[]{Southbound.class.getName()}, null, southbound);
214
215         NodeCacheManagerImpl nodeCacheManager = new NodeCacheManagerImpl();
216         registerAbstractHandlerService(context, new Class[] {NodeCacheManager.class},
217                 AbstractEvent.HandlerType.NODE, nodeCacheManager);
218
219         OvsdbInventoryServiceImpl ovsdbInventoryService = new OvsdbInventoryServiceImpl(providerContext);
220         registerService(context,
221                 new String[] {OvsdbInventoryService.class.getName()}, null, ovsdbInventoryService);
222
223         // Call .setDependencies() starting with the last service registered
224         for (int i = servicesAndRegistrations.size() - 1; i >= 0; i--) {
225             Pair<Object, ServiceRegistration> serviceAndRegistration = servicesAndRegistrations.get(i);
226             Object service = serviceAndRegistration.getLeft();
227             ServiceRegistration<?> serviceRegistration = serviceAndRegistration.getRight();
228             LOG.info("Setting dependencies on service {}/{}, {}", i, servicesAndRegistrations.size(),
229                     service.getClass());
230             if (service instanceof ConfigInterface) {
231                 ((ConfigInterface) service).setDependencies(
232                         serviceRegistration != null ? serviceRegistration.getReference() : null);
233                 LOG.info("Dependencies set");
234             } else {
235                 LOG.warn("Service isn't a ConfigInterface");
236             }
237         }
238
239         // TODO check if services are already available and setDependencies
240         // addingService may not be called if the service is already available when the ServiceTracker
241         // is started
242         trackService(context, INeutronNetworkCRUD.class, tenantNetworkManager, networkHandler, lBaaSHandler,
243                 lBaaSPoolHandler, lBaaSPoolMemberHandler, neutronL3Adapter);
244         trackService(context, INeutronSubnetCRUD.class, lBaaSHandler, lBaaSPoolHandler, lBaaSPoolMemberHandler,
245                 securityServices, neutronL3Adapter);
246         trackService(context, INeutronPortCRUD.class, tenantNetworkManager, lBaaSHandler, lBaaSPoolHandler,
247                 lBaaSPoolMemberHandler, securityServices, neutronL3Adapter);
248         trackService(context, INeutronFloatingIPCRUD.class, neutronL3Adapter);
249         trackService(context, INeutronLoadBalancerCRUD.class, lBaaSHandler, lBaaSPoolHandler, lBaaSPoolMemberHandler);
250         trackService(context, INeutronLoadBalancerPoolCRUD.class, lBaaSHandler, lBaaSPoolMemberHandler);
251         trackService(context, LoadBalancerProvider.class, lBaaSHandler, lBaaSPoolHandler, lBaaSPoolMemberHandler);
252         trackService(context, ArpProvider.class, neutronL3Adapter);
253         trackService(context, InboundNatProvider.class, neutronL3Adapter);
254         trackService(context, OutboundNatProvider.class, neutronL3Adapter);
255         trackService(context, RoutingProvider.class, neutronL3Adapter);
256         trackService(context, L3ForwardingProvider.class, neutronL3Adapter);
257         trackService(context, GatewayMacResolver.class, neutronL3Adapter);
258         trackService(context, IngressAclProvider.class, securityServices);
259         trackService(context, EgressAclProvider.class, securityServices);
260         trackService(context, IcmpEchoProvider.class, neutronL3Adapter);
261
262         // We no longer need to track the services, avoid keeping references around
263         servicesAndRegistrations.clear();
264     }
265
266     private void registerCRUDServiceProviders(BundleContext context,
267             ProviderContext providerContext) {
268         LOG.debug("Registering CRUD service providers");
269         NeutronRouterInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
270         NeutronPortInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
271         NeutronSubnetInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
272         NeutronNetworkInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
273         NeutronSecurityGroupInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
274         NeutronSecurityRuleInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
275         NeutronFirewallInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
276         NeutronFirewallPolicyInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
277         NeutronFirewallRuleInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
278         NeutronLoadBalancerInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
279         NeutronLoadBalancerPoolInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
280         NeutronLoadBalancerListenerInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
281         NeutronLoadBalancerHealthMonitorInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
282         NeutronLoadBalancerPoolMemberInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
283         NeutronFloatingIPInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
284     }
285
286     private void trackService(BundleContext context, final Class<?> clazz, final ConfigInterface... dependents) {
287         @SuppressWarnings("unchecked")
288         ServiceTracker tracker = new ServiceTracker(context, clazz, null) {
289             @Override
290             public Object addingService(ServiceReference reference) {
291                 LOG.info("addingService " + clazz.getName());
292                 Object service = context.getService(reference);
293                 if (service != null) {
294                     for (ConfigInterface dependent : dependents) {
295                         dependent.setDependencies(service);
296                     }
297                 }
298                 return service;
299             }
300         };
301         tracker.open();
302     }
303
304     private void registerAbstractHandlerService(BundleContext context, Class[] interfaces,
305                                                 AbstractEvent.HandlerType handlerType, AbstractHandler handler) {
306         Dictionary<String, Object> properties = new Hashtable<>();
307         properties.put(Constants.EVENT_HANDLER_TYPE_PROPERTY, handlerType);
308         String[] interfaceNames = new String[interfaces.length + 1];
309         for (int i = 0; i < interfaces.length; i++) {
310             interfaceNames[i] = interfaces[i].getName();
311         }
312         interfaceNames[interfaces.length] = AbstractHandler.class.getName();
313         registerService(context, interfaceNames, properties, handler);
314     }
315
316
317     @Override
318     public void stop(BundleContext context) throws Exception {
319         LOG.info("ConfigActivator stop");
320         // ServiceTrackers and services are already released when bundle stops,
321         // so we don't need to close the trackers or unregister the services
322     }
323
324     private ServiceRegistration<?> registerService(BundleContext bundleContext, String[] interfaces,
325                                                    Dictionary<String, Object> properties, Object impl) {
326         ServiceRegistration serviceRegistration = bundleContext.registerService(interfaces, impl, properties);
327         if (serviceRegistration == null) {
328             LOG.warn("Service registration for {} failed to return a ServiceRegistration instance", impl.getClass());
329         }
330         servicesAndRegistrations.add(Pair.of(impl, serviceRegistration));
331         return serviceRegistration;
332     }
333
334     public void setConntrackEnabled(boolean conntrackEnabled) {
335         this.conntrackEnabled = conntrackEnabled;
336     }
337 }