Sure, I'll investigate.  They seem to have passed correctly on my machine,
so it may be a timing issue.

On Tue, Jul 24, 2012 at 11:33 AM, Mark Nuttall <[email protected]> wrote:

> Hi Guillaume,
> Perhaps you've noticed all ready, but this change plus the three before it
> is causing
> org.apache.aries.blueprint.itests.TestConfigAdmin.testManagedServiceFactory
> to fail, and so breaking the Hudson build. We saw this first in
> https://builds.apache.org/job/Aries/1592/changes ; it can be seen again in
> https://builds.apache.org/job/Aries/1593/ .
>
> Please would you revert these changes, or fix the resulting test failure?
> Thank you.
>
> Regards,
> Mark
>
> On 24 July 2012 07:35, <[email protected]> wrote:
>
> > Author: gnodet
> > Date: Tue Jul 24 06:35:34 2012
> > New Revision: 1364914
> >
> > URL: http://svn.apache.org/viewvc?rev=1364914&view=rev
> > Log:
> > [ARIES-584] Refactor ManagedServiceFactory to avoid holding lock while
> > registering/unregistering services and have a safer destruction mechanism
> >
> > Added:
> >
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java
> > Modified:
> >
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
> >
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
> >
> >
> aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java
> >
> > Added:
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java
> > URL:
> >
> http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java?rev=1364914&view=auto
> >
> >
> ==============================================================================
> > ---
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java
> > (added)
> > +++
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java
> > Tue Jul 24 06:35:34 2012
> > @@ -0,0 +1,233 @@
> > +/**
> > + * Licensed to the Apache Software Foundation (ASF) under one
> > + * or more contributor license agreements.  See the NOTICE file
> > + * distributed with this work for additional information
> > + * regarding copyright ownership.  The ASF licenses this file
> > + * to you under the Apache License, Version 2.0 (the
> > + * "License"); you may not use this file except in compliance
> > + * with the License.  You may obtain a copy of the License at
> > + *
> > + *   http://www.apache.org/licenses/LICENSE-2.0
> > + *
> > + * Unless required by applicable law or agreed to in writing,
> > + * software distributed under the License is distributed on an
> > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > + * KIND, either express or implied.  See the License for the
> > + * specific language governing permissions and limitations
> > + * under the License.
> > + */
> > +package org.apache.aries.blueprint.compendium.cm;
> > +
> > +import java.util.Dictionary;
> > +import java.util.Map;
> > +import java.util.concurrent.ConcurrentHashMap;
> > +import java.util.concurrent.ExecutorService;
> > +import java.util.concurrent.Executors;
> > +import java.util.concurrent.TimeUnit;
> > +import java.util.concurrent.atomic.AtomicBoolean;
> > +
> > +import org.apache.aries.blueprint.utils.JavaUtils;
> > +import org.osgi.framework.BundleContext;
> > +import org.osgi.framework.ServiceRegistration;
> > +import org.osgi.service.cm.ConfigurationException;
> > +import org.osgi.service.cm.ManagedServiceFactory;
> > +import org.slf4j.Logger;
> > +import org.slf4j.LoggerFactory;
> > +
> > +public abstract class BaseManagedServiceFactory<T> implements
> > ManagedServiceFactory {
> > +
> > +    public static final long DEFAULT_TIMEOUT_BEFORE_INTERRUPT = 30000;
> > +
> > +    public static final int CONFIGURATION_ADMIN_OBJECT_DELETED = 1;
> > +
> > +    public static final int BUNDLE_STOPPING = 2;
> > +
> > +    public static final int INTERNAL_ERROR = 4;
> > +
> > +    protected final Logger LOGGER = LoggerFactory.getLogger(getClass());
> > +
> > +    private final BundleContext context;
> > +    private final String name;
> > +    private final long timeoutBeforeInterrupt;
> > +    private final AtomicBoolean destroyed;
> > +    private final ExecutorService executor;
> > +    private final Map<String, Pair<T, ServiceRegistration>> services;
> > +    private final Map<ServiceRegistration, T> registrations;
> > +
> > +    public BaseManagedServiceFactory(BundleContext context, String
> name) {
> > +        this(context, name, DEFAULT_TIMEOUT_BEFORE_INTERRUPT);
> > +    }
> > +
> > +    public BaseManagedServiceFactory(BundleContext context, String name,
> > long timeoutBeforeInterrupt) {
> > +        this.context = context;
> > +        this.name = name;
> > +        this.timeoutBeforeInterrupt = timeoutBeforeInterrupt;
> > +        this.destroyed = new AtomicBoolean(false);
> > +        this.executor = Executors.newSingleThreadExecutor();
> > +        this.services = new ConcurrentHashMap<String, Pair<T,
> > ServiceRegistration>>();
> > +        this.registrations = new ConcurrentHashMap<ServiceRegistration,
> > T>();
> > +    }
> > +
> > +    public String getName() {
> > +        return name;
> > +    }
> > +
> > +    public Map<ServiceRegistration, T> getServices() {
> > +        return registrations;
> > +    }
> > +
> > +    public void updated(final String pid, final Dictionary properties)
> > throws ConfigurationException {
> > +        if (destroyed.get()) {
> > +            return;
> > +        }
> > +        checkConfiguration(pid, properties);
> > +        executor.submit(new Runnable() {
> > +            public void run() {
> > +                try {
> > +                    internalUpdate(pid, properties);
> > +                } catch (Throwable t) {
> > +                    LOGGER.warn("Error destroying service for
> > ManagedServiceFactory " + getName(), t);
> > +                }
> > +            }
> > +        });
> > +    }
> > +
> > +    public void deleted(final String pid) {
> > +        if (destroyed.get()) {
> > +            return;
> > +        }
> > +        executor.submit(new Runnable() {
> > +            public void run() {
> > +                try {
> > +                    internalDelete(pid,
> > CONFIGURATION_ADMIN_OBJECT_DELETED);
> > +                } catch (Throwable throwable) {
> > +                    LOGGER.warn("Error destroying service for
> > ManagedServiceFactory " + getName(), throwable);
> > +                }
> > +            }
> > +        });
> > +    }
> > +
> > +    protected void checkConfiguration(String pid, Dictionary properties)
> > throws ConfigurationException {
> > +        // Do nothing
> > +    }
> > +
> > +    protected abstract T doCreate(Dictionary properties) throws
> Exception;
> > +
> > +    protected abstract T doUpdate(T t, Dictionary properties) throws
> > Exception;
> > +
> > +    protected abstract void doDestroy(T t, Dictionary properties, int
> > code) throws Exception;
> > +
> > +    protected abstract String[] getExposedClasses(T t);
> > +
> > +    private void internalUpdate(String pid, Dictionary properties) {
> > +        Pair<T, ServiceRegistration> pair = services.get(pid);
> > +        if (pair != null) {
> > +            try {
> > +                T t = doUpdate(pair.getFirst(), properties);
> > +                pair.setFirst(t);
> > +                pair.getSecond().setProperties(properties);
> > +            } catch (Throwable throwable) {
> > +                internalDelete(pid, INTERNAL_ERROR);
> > +                LOGGER.warn("Error updating service for
> > ManagedServiceFactory " + getName(), throwable);
> > +            }
> > +        } else {
> > +            if (destroyed.get()) {
> > +                return;
> > +            }
> > +            try {
> > +                T t = doCreate(properties);
> > +                try {
> > +                    if (destroyed.get()) {
> > +                        throw new
> > IllegalStateException("ManagedServiceFactory has been destroyed");
> > +                    }
> > +                    ServiceRegistration registration =
> > context.registerService(getExposedClasses(t), t, properties);
> > +                    services.put(pid, new Pair<T,
> ServiceRegistration>(t,
> > registration));
> > +                    registrations.put(registration,  t);
> > +                    postRegister(t, properties, registration);
> > +                } catch (Throwable throwable1) {
> > +                    try {
> > +                        doDestroy(t, properties, INTERNAL_ERROR);
> > +                    } catch (Throwable throwable2) {
> > +                        // Ignore
> > +                    }
> > +                    throw throwable1;
> > +                }
> > +            } catch (Throwable throwable) {
> > +                LOGGER.warn("Error creating service for
> > ManagedServiceFactory " + getName(), throwable);
> > +            }
> > +        }
> > +    }
> > +
> > +    protected void postRegister(T t, Dictionary properties,
> > ServiceRegistration registration) {
> > +        // Place holder
> > +    }
> > +
> > +    protected void preUnregister(T t, Dictionary properties,
> > ServiceRegistration registration) {
> > +        // Place holder
> > +    }
> > +
> > +    private void internalDelete(String pid, int code) {
> > +        Pair<T, ServiceRegistration> pair = services.remove(pid);
> > +        if (pair != null) {
> > +            registrations.remove(pair.getSecond());
> > +            Dictionary properties =
> > JavaUtils.getProperties(pair.getSecond().getReference());
> > +            try {
> > +                preUnregister(pair.getFirst(), properties,
> > pair.getSecond());
> > +                pair.getSecond().unregister();
> > +            } catch (Throwable t) {
> > +                LOGGER.info("Error unregistering service", t);
> > +            }
> > +            try {
> > +                doDestroy(pair.getFirst(), properties, code);
> > +            } catch (Throwable t) {
> > +                LOGGER.info("Error destroying service", t);
> > +            }
> > +        }
> > +    }
> > +
> > +    public void destroy() {
> > +        if (destroyed.compareAndSet(false, true)) {
> > +            executor.shutdown();
> > +            try {
> > +                executor.awaitTermination(timeoutBeforeInterrupt,
> > TimeUnit.MILLISECONDS);
> > +            } catch (InterruptedException e) {
> > +                throw new RuntimeException("Shutdown interrupted");
> > +            }
> > +            if (!executor.isTerminated()) {
> > +                executor.shutdownNow();
> > +                try {
> > +                    executor.awaitTermination(Long.MAX_VALUE,
> > TimeUnit.NANOSECONDS);
> > +                } catch (InterruptedException e) {
> > +                    throw new RuntimeException("Shutdown interrupted");
> > +                }
> > +            }
> > +
> > +            while (!services.isEmpty()) {
> > +                String pid = services.keySet().iterator().next();
> > +                internalDelete(pid, BUNDLE_STOPPING);
> > +            }
> > +        }
> > +    }
> > +
> > +    static class Pair<U,V> {
> > +        private U first;
> > +        private V second;
> > +        public Pair(U first, V second) {
> > +            this.first = first;
> > +            this.second = second;
> > +        }
> > +        public U getFirst() {
> > +            return first;
> > +        }
> > +        public V getSecond() {
> > +            return second;
> > +        }
> > +        public void setFirst(U first) {
> > +            this.first = first;
> > +        }
> > +        public void setSecond(V second) {
> > +            this.second = second;
> > +        }
> > +    }
> > +
> > +}
> >
> > Modified:
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
> > URL:
> >
> http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java?rev=1364914&r1=1364913&r2=1364914&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
> > (original)
> > +++
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
> > Tue Jul 24 06:35:34 2012
> > @@ -27,23 +27,18 @@ import java.util.List;
> >  import java.util.Map;
> >  import java.util.Properties;
> >  import java.util.Set;
> > -import java.util.concurrent.ConcurrentHashMap;
> >
> >  import org.apache.aries.blueprint.BeanProcessor;
> > -import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
> >  import org.apache.aries.blueprint.ServiceProcessor;
> > +import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
> >  import org.apache.aries.blueprint.utils.JavaUtils;
> >  import org.apache.aries.blueprint.utils.ReflectionUtils;
> >  import org.apache.aries.blueprint.utils.ServiceListener;
> >  import org.apache.aries.util.AriesFrameworkUtil;
> >  import org.osgi.framework.Bundle;
> >  import org.osgi.framework.Constants;
> > -import org.osgi.framework.ServiceReference;
> >  import org.osgi.framework.ServiceRegistration;
> >  import org.osgi.service.blueprint.reflect.ServiceMetadata;
> > -import org.osgi.service.cm.Configuration;
> > -import org.osgi.service.cm.ConfigurationAdmin;
> > -import org.osgi.service.cm.ConfigurationException;
> >  import org.osgi.service.cm.ManagedServiceFactory;
> >  import org.slf4j.Logger;
> >  import org.slf4j.LoggerFactory;
> > @@ -54,30 +49,27 @@ import org.slf4j.LoggerFactory;
> >   *
> >   * @version $Rev$, $Date$
> >   */
> > -public class CmManagedServiceFactory {
> > -
> > -    static final int CONFIGURATION_ADMIN_OBJECT_DELETED = 1;
> > -
> > -    static final int BUNDLE_STOPPING = 2;
> > +public class CmManagedServiceFactory extends
> > BaseManagedServiceFactory<Object> {
> >
> >      private static final Logger LOGGER =
> > LoggerFactory.getLogger(CmManagedServiceFactory.class);
> > -
> > +
> >      private ExtendedBlueprintContainer blueprintContainer;
> > -    private ConfigurationAdmin configAdmin;
> >      private String id;
> >      private String factoryPid;
> >      private List<String> interfaces;
> >      private int autoExport;
> >      private int ranking;
> > -    private Map serviceProperties;
> > +    private Map<Object,Object> serviceProperties;
> >      private String managedComponentName;
> >      private String componentDestroyMethod;
> >      private List<ServiceListener> listeners;
> > -    private final Object lock = new Object();
> >
> >      private ServiceRegistration registration;
> > -    private final Map<String, ServiceRegistration> pids = new
> > ConcurrentHashMap<String, ServiceRegistration>();
> > -    private final Map<ServiceRegistration, Object> services = new
> > ConcurrentHashMap<ServiceRegistration, Object>();
> > +
> > +    public CmManagedServiceFactory(ExtendedBlueprintContainer
> > blueprintContainer) {
> > +        super(blueprintContainer.getBundleContext(), null);
> > +        this.blueprintContainer = blueprintContainer;
> > +    }
> >
> >      public void init() throws Exception {
> >          LOGGER.debug("Initializing CmManagedServiceFactory for
> > factoryPid={}", factoryPid);
> > @@ -86,61 +78,27 @@ public class CmManagedServiceFactory {
> >          Bundle bundle =
> blueprintContainer.getBundleContext().getBundle();
> >          props.put(Constants.BUNDLE_SYMBOLICNAME,
> > bundle.getSymbolicName());
> >          props.put(Constants.BUNDLE_VERSION,
> > bundle.getHeaders().get(Constants.BUNDLE_VERSION));
> > -
> > -        synchronized(lock) {
> > -            registration =
> >
> blueprintContainer.getBundleContext().registerService(ManagedServiceFactory.class.getName(),
> > new ConfigurationWatcher(), props);
> > -
> > -            String filter = '(' + ConfigurationAdmin.SERVICE_FACTORYPID
> +
> > '=' + this.factoryPid + ')';
> > -            Configuration[] configs =
> > configAdmin.listConfigurations(filter);
> > -            if (configs != null) {
> > -                for (Configuration config : configs) {
> > -                    updated(config.getPid(), config.getProperties());
> > -                }
> > -            }
> > -        }
> > +
> > +        registration =
> >
> blueprintContainer.getBundleContext().registerService(ManagedServiceFactory.class.getName(),
> > this, props);
> >      }
> >
> >      public void destroy() {
> >          AriesFrameworkUtil.safeUnregisterService(registration);
> > -        for (Map.Entry<ServiceRegistration, Object> entry :
> > services.entrySet()) {
> > -            destroy(entry.getValue(), entry.getKey(), BUNDLE_STOPPING);
> > -        }
> > -        services.clear();
> > -        pids.clear();
> > +        super.destroy();
> >      }
> >
> > -    private void destroy(Object component, ServiceRegistration
> > registration, int code) {
> > -        if (listeners != null) {
> > -            ServiceReference ref = registration.getReference();
> > -            for (ServiceListener listener : listeners) {
> > -                Hashtable props = JavaUtils.getProperties(ref);
> > -                listener.unregister(component, props);
> > -            }
> > -        }
> > -        destroyComponent(component, code);
> > -        AriesFrameworkUtil.safeUnregisterService(registration);
> > -    }
> > -
> >      public Map<ServiceRegistration, Object> getServiceMap() {
> > -        return Collections.unmodifiableMap(services);
> > -    }
> > -
> > -    public void setBlueprintContainer(ExtendedBlueprintContainer
> > blueprintContainer) {
> > -        this.blueprintContainer = blueprintContainer;
> > -    }
> > -
> > -    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
> > -        this.configAdmin = configAdmin;
> > +        return Collections.unmodifiableMap(getServices());
> >      }
> >
> >      public void setListeners(List<ServiceListener> listeners) {
> >          this.listeners = listeners;
> >      }
> > -
> > +
> >      public void setId(String id) {
> >          this.id = id;
> >      }
> > -
> > +
> >      public void setFactoryPid(String factoryPid) {
> >          this.factoryPid = factoryPid;
> >      }
> > @@ -160,7 +118,7 @@ public class CmManagedServiceFactory {
> >      public void setServiceProperties(Map serviceProperties) {
> >          this.serviceProperties = serviceProperties;
> >      }
> > -
> > +
> >      public void setManagedComponentName(String managedComponentName) {
> >          this.managedComponentName = managedComponentName;
> >      }
> > @@ -168,82 +126,42 @@ public class CmManagedServiceFactory {
> >      public void setComponentDestroyMethod(String
> componentDestroyMethod) {
> >          this.componentDestroyMethod = componentDestroyMethod;
> >      }
> > -
> > -    protected void updated(String pid, Dictionary props) {
> > -      LOGGER.debug("Updated configuration {} with props {}", pid,
> props);
> > -
> > -      Hashtable regProps = null;
> > -      Object component = null;
> > -
> > -      // This method might be multithreaded, so synchronize checking and
> > -      // creating the service
> > -      final ServiceRegistration existingReg;
> > -      synchronized (pids) {
> > -         existingReg = pids.get(pid);
> > -         if (existingReg == null) {
> > -            updateComponentProperties(props);
> > -
> > -            component =
> > blueprintContainer.getComponentInstance(managedComponentName);
> > -
> > -            // TODO: call listeners, etc...
> > -
> > -            regProps = getRegistrationProperties(pid);
> > -            CmProperties cm = findServiceProcessor();
> > -            if (cm != null) {
> > -               if ("".equals(cm.getPersistentId())) {
> > -                  JavaUtils.copy(regProps, props);
> > -               }
> > -               cm.updateProperties(new PropertiesUpdater(pid),
> regProps);
> > -            }
> >
> > -            Set<String> classes = getClasses(component);
> > -            String[] classArray = classes.toArray(new
> > String[classes.size()]);
> > -            ServiceRegistration reg =
> > blueprintContainer.getBundleContext().registerService(classArray,
> > component, regProps);
> > -
> > -            LOGGER.debug("Service {} registered with interfaces {} and
> > properties {}", new Object[] { component, classes, regProps });
> > -
> > -            services.put(reg, component);
> > -            pids.put(pid, reg);
> > -         }
> > -        } // end of synchronization
> > -
> > -        // If we just registered a service, do the slower stuff outside
> > the synchronized block
> > -        if (existingReg == null)
> > -        {
> > -            if (listeners != null) {
> > -                for (ServiceListener listener : listeners) {
> > -                    listener.register(component, regProps);
> > +    private void getRegistrationProperties(Dictionary properties,
> boolean
> > update) {
> > +        CmProperties cm = findServiceProcessor();
> > +        if (cm == null) {
> > +            while (!properties.isEmpty()) {
> > +                properties.remove(properties.keys().nextElement());
> > +            }
> > +        } else  {
> > +            if (!cm.getUpdate()) {
> > +                if (update) {
> > +                    while (!properties.isEmpty()) {
> > +
> >  properties.remove(properties.keys().nextElement());
> > +                    }
> > +                    for (Map.Entry entry :
> cm.getProperties().entrySet())
> > {
> > +                        properties.put(entry.getKey(),
> entry.getValue());
> > +                    }
> > +                } else {
> > +                    cm.updated(properties);
> >                  }
> >              }
> > -        } else {
> > -            updateComponentProperties(props);
> > -
> > -            CmProperties cm = findServiceProcessor();
> > -            if (cm != null && "".equals(cm.getPersistentId())) {
> > -                regProps = getRegistrationProperties(pid);
> > -                JavaUtils.copy(regProps, props);
> > -                cm.updated(regProps);
> > -            }
> >          }
> > -    }
> > -
> > -    private Hashtable getRegistrationProperties(String pid) {
> > -        Hashtable regProps = new Hashtable();
> >          if (serviceProperties != null) {
> > -            regProps.putAll(serviceProperties);
> > +            for (Map.Entry entry : serviceProperties.entrySet()) {
> > +                properties.put(entry.getKey(), entry.getValue());
> > +            }
> >          }
> > -        regProps.put(Constants.SERVICE_PID, pid);
> > -        regProps.put(Constants.SERVICE_RANKING, ranking);
> > -        return regProps;
> > +        properties.put(Constants.SERVICE_RANKING, ranking);
> >      }
> > -
> > +
> >      private void updateComponentProperties(Dictionary props) {
> >          CmManagedProperties cm = findBeanProcessor();
> >          if (cm != null) {
> >              cm.updated(props);
> >          }
> >      }
> > -
> > +
> >      private CmManagedProperties findBeanProcessor() {
> >          for (BeanProcessor beanProcessor :
> > blueprintContainer.getProcessors(BeanProcessor.class)) {
> >              if (beanProcessor instanceof CmManagedProperties) {
> > @@ -255,7 +173,7 @@ public class CmManagedServiceFactory {
> >          }
> >          return null;
> >      }
> > -
> > +
> >      private CmProperties findServiceProcessor() {
> >          for (ServiceProcessor processor :
> > blueprintContainer.getProcessors(ServiceProcessor.class)) {
> >              if (processor instanceof CmProperties) {
> > @@ -267,20 +185,9 @@ public class CmManagedServiceFactory {
> >          }
> >          return null;
> >      }
> > -
> > -    private void destroyComponent(Object instance, int reason) {
> > -        Method method = findDestroyMethod(instance.getClass());
> > -        if (method != null) {
> > -            try {
> > -                method.invoke(instance, new Object [] { reason });
> > -            } catch (Exception e) {
> > -                e.printStackTrace();
> > -            }
> > -        }
> > -    }
> > -
> > +
> >      private Method findDestroyMethod(Class clazz) {
> > -        Method method = null;
> > +        Method method = null;
> >          if (componentDestroyMethod != null &&
> > componentDestroyMethod.length() > 0) {
> >              List<Method> methods =
> > ReflectionUtils.findCompatibleMethods(clazz, componentDestroyMethod, new
> > Class [] { int.class });
> >              if (methods != null && !methods.isEmpty()) {
> > @@ -289,17 +196,52 @@ public class CmManagedServiceFactory {
> >          }
> >          return method;
> >      }
> > -
> > -    protected void deleted(String pid) {
> > -        LOGGER.debug("Deleted configuration {}", pid);
> > -        ServiceRegistration reg = pids.remove(pid);
> > -        if (reg != null) {
> > -            Object component = services.remove(reg);
> > -            destroy(component, reg, CONFIGURATION_ADMIN_OBJECT_DELETED);
> > +
> > +    protected Object doCreate(Dictionary properties) throws Exception {
> > +        updateComponentProperties(copy(properties));
> > +        Object component =
> > blueprintContainer.getComponentInstance(managedComponentName);
> > +        getRegistrationProperties(properties, false);
> > +        return component;
> > +    }
> > +
> > +    protected Object doUpdate(Object service, Dictionary properties)
> > throws Exception {
> > +        updateComponentProperties(copy(properties));
> > +        getRegistrationProperties(properties, true);
> > +        return service;
> > +    }
> > +
> > +    protected void doDestroy(Object service, Dictionary properties, int
> > code) throws Exception {
> > +        Method method = findDestroyMethod(service.getClass());
> > +        if (method != null) {
> > +            try {
> > +                method.invoke(service, new Object [] { code });
> > +            } catch (Exception e) {
> > +                LOGGER.info("Error destroying component", e);
> > +            }
> > +        }
> > +    }
> > +
> > +    protected void postRegister(Object service, Dictionary properties,
> > ServiceRegistration registration) {
> > +        if (listeners != null && !listeners.isEmpty()) {
> > +            Hashtable props = new Hashtable();
> > +            JavaUtils.copy(properties, props);
> > +            for (ServiceListener listener : listeners) {
> > +                listener.register(service, props);
> > +            }
> > +        }
> > +    }
> > +
> > +    protected void preUnregister(Object service, Dictionary properties,
> > ServiceRegistration registration) {
> > +        if (listeners != null && !listeners.isEmpty()) {
> > +            Hashtable props = new Hashtable();
> > +            JavaUtils.copy(properties, props);
> > +            for (ServiceListener listener : listeners) {
> > +                listener.unregister(service, props);
> > +            }
> >          }
> >      }
> >
> > -    private Set<String> getClasses(Object service) {
> > +    protected String[] getExposedClasses(Object service) {
> >          Class serviceClass = service.getClass();
> >          Set<String> classes;
> >          switch (autoExport) {
> > @@ -317,47 +259,13 @@ public class CmManagedServiceFactory {
> >                  classes = new HashSet<String>(interfaces);
> >                  break;
> >          }
> > -        return classes;
> > +        return classes.toArray(new String[classes.size()]);
> >      }
> > -
> > -    private class ConfigurationWatcher implements ManagedServiceFactory
> {
> > -
> > -        public String getName() {
> > -            return null;
> > -        }
> > -
> > -        public void updated(String pid, Dictionary props) throws
> > ConfigurationException {
> > -            CmManagedServiceFactory.this.updated(pid, props);
> > -        }
> >
> > -        public void deleted(String pid) {
> > -            CmManagedServiceFactory.this.deleted(pid);
> > -        }
> > +    private Hashtable copy(Dictionary source) {
> > +        Hashtable ht = new Hashtable();
> > +        JavaUtils.copy(ht, source);
> > +        return ht;
> >      }
> >
> > -    private class PropertiesUpdater implements
> > ServiceProcessor.ServicePropertiesUpdater {
> > -
> > -        private String pid;
> > -
> > -        public PropertiesUpdater(String pid) {
> > -            this.pid = pid;
> > -        }
> > -
> > -        public String getId() {
> > -            return id;
> > -        }
> > -
> > -        public void updateProperties(Dictionary properties) {
> > -            ServiceRegistration reg = pids.get(pid);
> > -            if (reg != null) {
> > -                ServiceReference ref = reg.getReference();
> > -                if (ref != null) {
> > -                    Hashtable table = JavaUtils.getProperties(ref);
> > -                    JavaUtils.copy(table, properties);
> > -                    reg.setProperties(table);
> > -                }
> > -            }
> > -        }
> > -    }
> > -
> >  }
> >
> > Modified:
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
> > URL:
> >
> http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java?rev=1364914&r1=1364913&r2=1364914&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
> > (original)
> > +++
> >
> aries/trunk/blueprint/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
> > Tue Jul 24 06:35:34 2012
> > @@ -350,8 +350,7 @@ public class CmNamespaceHandler implemen
> >          factoryMetadata.setRuntimeClass(CmManagedServiceFactory.class);
> >          factoryMetadata.setInitMethod("init");
> >          factoryMetadata.setDestroyMethod("destroy");
> > -        factoryMetadata.addProperty("configAdmin",
> > createConfigurationAdminRef(context));
> > -        factoryMetadata.addProperty("blueprintContainer",
> > createRef(context, "blueprintContainer"));
> > +        factoryMetadata.addArgument(createRef(context,
> > "blueprintContainer"), null, 0);
> >          factoryMetadata.addProperty("factoryPid", createValue(context,
> > element.getAttribute(FACTORY_PID_ATTRIBUTE)));
> >          String autoExport = element.hasAttribute(AUTO_EXPORT_ATTRIBUTE)
> ?
> > element.getAttribute(AUTO_EXPORT_ATTRIBUTE) : AUTO_EXPORT_DEFAULT;
> >          if (AUTO_EXPORT_DISABLED.equals(autoExport)) {
> >
> > Modified:
> >
> aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java
> > URL:
> >
> http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java?rev=1364914&r1=1364913&r2=1364914&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java
> > (original)
> > +++
> >
> aries/trunk/blueprint/blueprint-cm/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java
> > Tue Jul 24 06:35:34 2012
> > @@ -56,6 +56,7 @@ public class ManagedServiceFactoryTest e
> >          assertNull(sr.getProperty("b"));
> >
> >          props = new Hashtable<String,String>();
> > +        props.put("a", "5");
> >          props.put("b", "foo");
> >          cf.update(props);
> >          Thread.sleep(500);
> > @@ -89,6 +90,7 @@ public class ManagedServiceFactoryTest e
> >          assertNull(sr.getProperty("b"));
> >
> >          props = new Hashtable<String,String>();
> > +        props.put("a", "5");
> >          props.put("b", "foo");
> >          cf.update(props);
> >
> > @@ -122,6 +124,7 @@ public class ManagedServiceFactoryTest e
> >          assertNull(sr.getProperty("b"));
> >
> >          props = new Hashtable<String,String>();
> > +        props.put("a", "5");
> >          props.put("b", "foo");
> >          cf.update(props);
> >
> >
> >
> >
>



-- 
------------------------
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
FuseSource, Integration everywhere
http://fusesource.com

Reply via email to