2 * Copyright (c) 2013 Cisco Systems, 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
8 package org.opendaylight.controller.config.manager.impl.osgi;
10 import org.opendaylight.controller.config.api.ModuleIdentifier;
11 import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
12 import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
13 import org.opendaylight.controller.config.spi.Module;
14 import org.osgi.framework.BundleContext;
15 import org.osgi.framework.ServiceRegistration;
17 import java.util.Dictionary;
18 import java.util.HashSet;
19 import java.util.Hashtable;
23 * Registers instantiated beans as OSGi services and unregisters these services
24 * if beans are destroyed.
26 public class BeanToOsgiServiceManager {
27 // name of properties submitted to osgi
28 static final String INSTANCE_NAME_OSGI_PROP = "instanceName";
29 static final String IMPLEMENTATION_NAME_OSGI_PROP = "implementationName";
32 * To be called for every created, reconfigured and recreated config bean.
33 * It is expected that before using this method OSGi service registry will
34 * be cleaned from previous registrations.
36 public OsgiRegistration registerToOsgi(
37 Class<? extends Module> configBeanClass, AutoCloseable instance,
38 ModuleIdentifier moduleIdentifier, BundleContext bundleContext) {
40 final Set<Class<?>> configuresInterfaces = InterfacesHelper
41 .getOsgiRegistrationTypes(configBeanClass);
42 checkInstanceImplementing(instance, configuresInterfaces);
44 // bundleContext.registerService blows up with empty 'clazzes'
45 if (configuresInterfaces.isEmpty() == false) {
46 final Dictionary<String, ?> propertiesForOsgi = getPropertiesForOsgi(moduleIdentifier);
47 final ServiceRegistration<?> serviceRegistration = bundleContext
48 .registerService(classesToNames(configuresInterfaces), instance, propertiesForOsgi);
49 return new OsgiRegistration(serviceRegistration);
51 return new OsgiRegistration();
53 } catch (IllegalStateException e) {
54 throw new IllegalStateException(
55 "Error while registering instance into OSGi Service Registry: "
56 + moduleIdentifier, e);
60 private static String[] classesToNames(Set<Class<?>> cfgs) {
61 String[] result = new String[cfgs.size()];
63 for (Class<?> cfg : cfgs) {
64 result[i] = cfg.getName();
70 private void checkInstanceImplementing(AutoCloseable instance,
71 Set<Class<?>> configures) {
72 Set<Class<?>> missing = new HashSet<>();
73 for (Class<?> requiredIfc : configures) {
74 if (requiredIfc.isInstance(instance) == false) {
75 missing.add(requiredIfc);
78 if (missing.isEmpty() == false) {
79 throw new IllegalStateException(
81 + " does not implement following interfaces as announced by "
82 + ServiceInterfaceAnnotation.class.getName()
83 + " annotation :" + missing);
87 private static Dictionary<String, ?> getPropertiesForOsgi(
88 ModuleIdentifier moduleIdentifier) {
89 Hashtable<String, String> table = new Hashtable<>();
90 table.put(IMPLEMENTATION_NAME_OSGI_PROP,
91 moduleIdentifier.getFactoryName());
92 table.put(INSTANCE_NAME_OSGI_PROP, moduleIdentifier.getInstanceName());
96 public static class OsgiRegistration implements AutoCloseable {
97 private final ServiceRegistration<?> serviceRegistration;
99 public OsgiRegistration(ServiceRegistration<?> serviceRegistration) {
100 this.serviceRegistration = serviceRegistration;
103 public OsgiRegistration() {
104 this.serviceRegistration = null;
108 public void close() {
109 if (serviceRegistration != null) {
110 serviceRegistration.unregister();