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