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