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