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