Search in sources :

Example 1 with Dependency

use of org.apache.felix.dm.Dependency in project felix by apache.

the class ComponentImpl method add.

@Override
public Component add(final Dependency... dependencies) {
    getExecutor().execute(() -> {
        List<DependencyContext> instanceBoundDeps = new ArrayList<>();
        for (Dependency d : dependencies) {
            DependencyContext dc = (DependencyContext) d;
            if (dc.getComponentContext() != null) {
                m_logger.err("%s can't be added to %s (dependency already added to component %s).", dc, ComponentImpl.this, dc.getComponentContext());
                continue;
            }
            m_dependencyEvents.put(dc, new ConcurrentSkipListSet<Event>());
            m_dependencies.add(dc);
            generateNameBasedOnServiceAndProperties();
            dc.setComponentContext(ComponentImpl.this);
            if (!(m_state == ComponentState.INACTIVE)) {
                dc.setInstanceBound(true);
                instanceBoundDeps.add(dc);
            }
        }
        startDependencies(instanceBoundDeps);
        handleChange();
    });
    return this;
}
Also used : ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Event(org.apache.felix.dm.context.Event) Dependency(org.apache.felix.dm.Dependency) DependencyContext(org.apache.felix.dm.context.DependencyContext)

Example 2 with Dependency

use of org.apache.felix.dm.Dependency in project felix by apache.

the class DependencyBuilder method createServiceDependency.

private Dependency createServiceDependency(Bundle b, DependencyManager dm) throws ClassNotFoundException {
    String service = m_metaData.getString(Params.service, null);
    Class<?> serviceClass = service != null ? b.loadClass(service) : null;
    String serviceFilter = m_metaData.getString(Params.filter, null);
    String defaultServiceImpl = m_metaData.getString(Params.defaultImpl, null);
    Class<?> defaultServiceImplClass = (defaultServiceImpl != null) ? b.loadClass(defaultServiceImpl) : null;
    String added = m_metaData.getString(Params.added, null);
    long timeout = m_metaData.getLong(Params.timeout, -1L);
    String changed = timeout != -1 ? null : m_metaData.getString(Params.changed, null);
    String removed = timeout != -1 ? null : m_metaData.getString(Params.removed, null);
    String swap = m_metaData.getString(Params.swap, null);
    String autoConfigField = m_metaData.getString(Params.autoConfig, null);
    boolean required = "true".equals(m_metaData.getString(Params.required, "true"));
    boolean propagate = "true".equals(m_metaData.getString(Params.propagate, "false"));
    boolean dereference = "true".equals(m_metaData.getString(Params.dereference, "true"));
    Dependency dp = createServiceDependency(dm, serviceClass, serviceFilter, defaultServiceImplClass, added, changed, removed, swap, autoConfigField, timeout, required, propagate, dereference);
    return dp;
}
Also used : ConfigurationDependency(org.apache.felix.dm.ConfigurationDependency) Dependency(org.apache.felix.dm.Dependency) ResourceDependency(org.apache.felix.dm.ResourceDependency) BundleDependency(org.apache.felix.dm.BundleDependency) ServiceDependency(org.apache.felix.dm.ServiceDependency)

Example 3 with Dependency

use of org.apache.felix.dm.Dependency in project felix by apache.

the class DependencyBuilder method createResourceDependency.

private Dependency createResourceDependency(DependencyManager dm) {
    String added = m_metaData.getString(Params.added, null);
    String changed = m_metaData.getString(Params.changed, null);
    String removed = m_metaData.getString(Params.removed, null);
    String filter = m_metaData.getString(Params.filter, null);
    boolean required = "true".equals(m_metaData.getString(Params.required, "true"));
    boolean propagate = "true".equals(m_metaData.getString(Params.propagate, "false"));
    String autoConfigField = m_metaData.getString(Params.autoConfig, null);
    Dependency dp = createResourceDependency(dm, added, changed, removed, required, filter, propagate, autoConfigField);
    return dp;
}
Also used : ConfigurationDependency(org.apache.felix.dm.ConfigurationDependency) Dependency(org.apache.felix.dm.Dependency) ResourceDependency(org.apache.felix.dm.ResourceDependency) BundleDependency(org.apache.felix.dm.BundleDependency) ServiceDependency(org.apache.felix.dm.ServiceDependency)

Example 4 with Dependency

use of org.apache.felix.dm.Dependency in project felix by apache.

the class ServiceLifecycleHandler method init.

/**
 * Handles an "init" lifecycle service callback. We just catch the "init" method, and callback
 * the actual Service' init method, to see if a dependency customization map is returned.
 * We also check if a Lifecycle Controller is used. In this case, we add a hidden custom dependency,
 * allowing to take control of when the component is actually started/stopped.
 * We also handle an edge case described in FELIX-4050, where component state calculation
 * may mess up if some dependencies are added using the API from the init method.
 *
 * @param c The Annotated Component
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public void init(Component c) throws Exception {
    Object serviceInstance = c.getInstances()[0];
    DependencyManager dm = c.getDependencyManager();
    // Check if a lifecycle controller is defined for this service. If true, then
    // We'll use the ToggleServiceDependency in order to manually activate/deactivate
    // the component ...
    String starter = m_srvMeta.getString(Params.starter, null);
    String stopper = m_srvMeta.getString(Params.stopper, null);
    List<Dependency> instanceBoundDeps = new ArrayList<>();
    if (starter != null) {
        // We'll inject two runnables: one that will start or service, when invoked, and the other
        // that will stop our service, when invoked. We'll use a shared atomic boolean in order to
        // synchronize both runnables.
        Log.instance().debug("Setting up a lifecycle controller for service %s", serviceInstance);
        String componentName = serviceInstance.getClass().getName();
        // Create a toggle service, used to start/stop our service.
        ToggleServiceDependency toggle = new ToggleServiceDependency();
        AtomicBoolean startFlag = new AtomicBoolean(false);
        // Add the toggle to the service.
        instanceBoundDeps.add(toggle);
        // Inject the runnable that will start our service, when invoked.
        setField(serviceInstance, starter, Runnable.class, new ComponentStarter(componentName, toggle, startFlag));
        if (stopper != null) {
            // Inject the runnable that will stop our service, when invoked.
            setField(serviceInstance, stopper, Runnable.class, new ComponentStopper(componentName, toggle, startFlag));
        }
    }
    // Before invoking an optional init method, we have to handle an edge case (FELIX-4050), where
    // init may add dependencies using the API and also return a map for configuring some
    // named dependencies. We have to add a hidden toggle dependency in the component, which we'll
    // active *after* the init method is called, and possibly *after* named dependencies are configured.
    ToggleServiceDependency initToggle = null;
    if (m_init != null) {
        initToggle = new ToggleServiceDependency();
        c.add(initToggle);
    }
    // Invoke component and all composites init methods, and for each one, check if a dependency
    // customization map is returned by the method. This map will be used to configure
    // some dependency filters (or required flag).
    Map<String, String> customization = new HashMap<String, String>();
    Object[] composites = c.getInstances();
    for (Object composite : composites) {
        Object o = invokeMethod(composite, m_init, dm, c);
        if (o != null && Map.class.isAssignableFrom(o.getClass())) {
            customization.putAll((Map) o);
        }
    }
    Log.instance().debug("ServiceLifecycleHandler.init: invoked init method from service %s " + ", returned map: %s", serviceInstance, customization);
    for (MetaData dependency : m_depsMeta) {
        // Check if this dependency has a name, and if we find the name from the
        // customization map, then apply filters and required flag from the map into it.
        // Also parse optional pid/propagate flags for named Configuration dependencies
        String name = dependency.getString(Params.name, null);
        if (name != null) {
            String filter = customization.get(name + ".filter");
            String required = customization.get(name + ".required");
            String pid = customization.get(name + ".pid");
            String propagate = customization.get(name + ".propagate");
            if (filter != null || required != null || pid != null || propagate != null) {
                dependency = (MetaData) dependency.clone();
                if (filter != null) {
                    dependency.setString(Params.filter, filter);
                }
                if (required != null) {
                    dependency.setString(Params.required, required);
                }
                if (pid != null) {
                    dependency.setString(Params.pid, pid);
                }
                if (propagate != null) {
                    dependency.setString(Params.propagate, propagate);
                }
            }
            DependencyBuilder depBuilder = new DependencyBuilder(dependency);
            Log.instance().info("ServiceLifecycleHandler.init: adding dependency %s into service %s", dependency, m_srvMeta);
            Dependency d = depBuilder.build(m_bundle, dm);
            instanceBoundDeps.add(d);
        }
    }
    // Add all extra dependencies in one shot, in order to calculate state changes for all dependencies at a time.
    if (instanceBoundDeps.size() > 0) {
        Log.instance().info("ServiceLifecycleHandler.init: adding extra/named dependencies %s", instanceBoundDeps);
        c.add(instanceBoundDeps.toArray(new Dependency[instanceBoundDeps.size()]));
    }
    // hidden toggle, and then remove it from the component, because we don't need it anymore.
    if (initToggle != null) {
        c.remove(initToggle);
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) DependencyManager(org.apache.felix.dm.DependencyManager) Dependency(org.apache.felix.dm.Dependency) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with Dependency

use of org.apache.felix.dm.Dependency in project felix by apache.

the class AbstractDecorator method addDependency.

/**
 * Add a Dependency to all already instantiated services.
 */
public void addDependency(Dependency... dependencies) {
    for (Component component : m_services.values()) {
        Dependency[] copy = Stream.of(dependencies).map(d -> (DependencyContext) d).map(dc -> dc.createCopy()).toArray(Dependency[]::new);
        for (int i = 0; i < dependencies.length; i++) {
            m_depclones.put(dependencies[i], copy[i]);
        }
        component.add(copy);
    }
}
Also used : Component(org.apache.felix.dm.Component) Dependency(org.apache.felix.dm.Dependency) URL(java.net.URL) ComponentStateListener(org.apache.felix.dm.ComponentStateListener) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) DependencyContext(org.apache.felix.dm.context.DependencyContext) BundleContext(org.osgi.framework.BundleContext) Stream(java.util.stream.Stream) ComponentContext(org.apache.felix.dm.context.ComponentContext) ConfigurationException(org.osgi.service.cm.ConfigurationException) Map(java.util.Map) DependencyManager(org.apache.felix.dm.DependencyManager) Bundle(org.osgi.framework.Bundle) Dictionary(java.util.Dictionary) ServiceReference(org.osgi.framework.ServiceReference) ServiceRegistration(org.osgi.framework.ServiceRegistration) Dependency(org.apache.felix.dm.Dependency) Component(org.apache.felix.dm.Component)

Aggregations

Dependency (org.apache.felix.dm.Dependency)14 Component (org.apache.felix.dm.Component)7 DependencyManager (org.apache.felix.dm.DependencyManager)7 BundleDependency (org.apache.felix.dm.BundleDependency)4 ConfigurationDependency (org.apache.felix.dm.ConfigurationDependency)4 ResourceDependency (org.apache.felix.dm.ResourceDependency)4 ServiceDependency (org.apache.felix.dm.ServiceDependency)4 Ensure (org.apache.felix.dm.itest.util.Ensure)4 URL (java.net.URL)3 Hashtable (java.util.Hashtable)3 ArrayList (java.util.ArrayList)2 Dictionary (java.util.Dictionary)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Properties (java.util.Properties)2 ResourceHandler (org.apache.felix.dm.ResourceHandler)2 DependencyContext (org.apache.felix.dm.context.DependencyContext)2 Method (java.lang.reflect.Method)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1