Return-Path: Delivered-To: apmail-felix-commits-archive@www.apache.org Received: (qmail 14834 invoked from network); 24 Sep 2008 14:27:49 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 24 Sep 2008 14:27:49 -0000 Received: (qmail 6121 invoked by uid 500); 24 Sep 2008 14:27:46 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 6097 invoked by uid 500); 24 Sep 2008 14:27:46 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 6088 invoked by uid 99); 24 Sep 2008 14:27:46 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 24 Sep 2008 07:27:46 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 24 Sep 2008 14:26:53 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id EBE7A238899F; Wed, 24 Sep 2008 07:26:56 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r698589 [1/2] - in /felix/trunk/ipojo: core/src/main/java/org/apache/felix/ipojo/ core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ core/src/main/java/org/apache/felix/ipojo/util/ handler/eventadmin/src/main/resources/ handl... Date: Wed, 24 Sep 2008 14:26:55 -0000 To: commits@felix.apache.org From: clement@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080924142656.EBE7A238899F@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: clement Date: Wed Sep 24 07:26:55 2008 New Revision: 698589 URL: http://svn.apache.org/viewvc?rev=698589&view=rev Log: Improve javadoc of the instance creator Fix several concurrency issues with the configuration admin (such as Felix-732) Commit a test suite testing configuration admin support Improve the documentation of XSD Schemas (external handlers) Added: felix/trunk/ipojo/tests/core/configadmin/ felix/trunk/ipojo/tests/core/configadmin/pom.xml felix/trunk/ipojo/tests/core/configadmin/src/ felix/trunk/ipojo/tests/core/configadmin/src/main/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ConfigurableFooProvider.java felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ConfigurationTestSuite.java felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForImmediate.java felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForServices.java felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceTestForImmediate.java felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceTestForService.java felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/service/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/service/CheckService.java felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/service/FooService.java felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configuration/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/util/ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/util/Utils.java felix/trunk/ipojo/tests/core/configadmin/src/main/resources/ felix/trunk/ipojo/tests/core/configadmin/src/main/resources/metadata.xml Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java felix/trunk/ipojo/handler/eventadmin/src/main/resources/event-admin.xsd felix/trunk/ipojo/handler/extender/src/main/resources/extender-pattern.xsd felix/trunk/ipojo/handler/jmx/src/main/resources/jmx.xsd felix/trunk/ipojo/handler/temporal/src/main/resources/temporal.xsd felix/trunk/ipojo/handler/whiteboard/src/main/resources/whiteboard-pattern.xsd felix/trunk/ipojo/tests/pom.xml Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java?rev=698589&r1=698588&r2=698589&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java Wed Sep 24 07:26:55 2008 @@ -30,43 +30,46 @@ import org.osgi.framework.BundleContext; /** - * An instance creator aims to create instances and to track their factories. It's allow to create instance from outside factories. + * The instance creator creates instances and tracks their factories. + * It allows creating instances from external factories. * @author Felix Project Team */ public class InstanceCreator implements FactoryStateListener { /** - * Logger to log messages if error occurs. + * The logger to log messages if errors occur. */ private Logger m_logger; /** - * Configurations to create and maintains. + * The configurations to create and to maintain. */ private List m_idle = new ArrayList(); /** - * Map storing created instance. [AbstractFactory, List [ManagedInstance]] + * The map storing created instances. + * This map contains [AbstractFactory, List [ManagedInstance]] couples. */ private Map m_attached = new HashMap(); /** - * Abstract Factory list. + * The abstract factory list. */ private List m_factories = new ArrayList(); /** - * Constructor. - * @param context : iPOJO bundle context. + * Creates the instance creator. + * This object is generally a singleton. + * @param context the bundle context of the iPOJO bundle. */ public InstanceCreator(BundleContext context) { m_logger = new Logger(context, "iPOJO Instance Creator"); } /** - * Add an instance to manage. - * @param instance : instance configuration - * @param bundle : bundle id declaring the instance + * Adds an instance to manage. + * @param instance the instance configuration + * @param bundle the bundle id declaring the instance */ synchronized void addInstance(Dictionary instance, long bundle) { ManagedInstance managed = new ManagedInstance(instance, bundle); @@ -92,8 +95,8 @@ } /** - * Dispose and stop to manage all instances declared by the given bundle. - * @param bundle : bundle. + * Disposes all instances declared by the given (leaving) bundle. + * @param bundle the bundle. */ void removeInstancesFromBundle(long bundle) { // Disposes instance from attached instances @@ -136,8 +139,8 @@ } /** - * A new factory appears. - * @param factory : the new factory. + * This method is called when a factory appears. + * @param factory the new factory. */ public synchronized void addFactory(IPojoFactory factory) { List createdInstances = new ArrayList(1); @@ -167,8 +170,8 @@ } /** - * A factory is leaving. - * @param factory : the leaving factory + * This method is called when a factory is leaving. + * @param factory the leaving factory */ void removeFactory(IPojoFactory factory) { factory.removeFactoryStateListener(this); @@ -178,8 +181,8 @@ } /** - * The given factory becomes valid. - * @param factory : the factory becoming valid. + * This method is called when the given factory becomes valid. + * @param factory the factory becoming valid. */ private void onValidation(IPojoFactory factory) { List toRemove = new ArrayList(); @@ -204,8 +207,8 @@ } /** - * The given factory becomes invalid. - * @param factory : factory which becomes invalid. + * This method is called when the given factory becomes invalid. + * @param factory the factory becoming invalid. */ private void onInvalidation(IPojoFactory factory) { List instances = (List) m_attached.remove(factory); @@ -219,9 +222,9 @@ } /** - * Factory state changed method. - * @param factory : factory. - * @param newState : new state. + * This method is called when the state of a factory changes. + * @param factory the factory. + * @param newState the new state. * @see org.apache.felix.ipojo.FactoryStateListener#stateChanged(org.apache.felix.ipojo.Factory, int) */ public void stateChanged(Factory factory, int newState) { @@ -233,33 +236,35 @@ } /** - * This structure aims to manage a configuration. It stores all necessary information to create an instance and to track the factory. + * This structure aims to manage a configuration. + * It stores all necessary information to create an instance + * and to track the factory. */ private class ManagedInstance { /** - * Configuration of the instance to create. + * The configuration of the instance to create. */ private Dictionary m_configuration; /** - * Bundle which create the instance. + * The bundle which creates the instance. */ private long m_bundleId; /** - * Factory used to create the instance. + * The factory used to create the instance. */ private IPojoFactory m_factory; /** - * Created instance. + * The created instance. */ private ComponentInstance m_instance; /** - * Constructor. - * @param conf : the configuration to create. - * @param bundle : the bundle in which the instance is declared. + * Creates a ManagedInstance. + * @param conf the configuration to create. + * @param bundle the bundle in which the instance is declared. */ ManagedInstance(Dictionary conf, long bundle) { m_configuration = conf; @@ -267,7 +272,7 @@ } /** - * Return the used factory name. + * Returns the used factory. * @return the factory */ IPojoFactory getFactory() { @@ -275,18 +280,21 @@ } /** - * Return the created instance. - * @return the instance (or null if no instance are created). + * Returns the created instance. + * @return the instance (or null if no instance are created). */ ComponentInstance getInstance() { return m_instance; } /** - * Test if the given factory match with the factory required by this instance. A factory matches if its name or its class name is equals to - * the 'component' property of the instance. Then the acceptability of the configuration is checked. - * @param factory : the factory to confront against the current instance. - * @return true if the factory match. + * Checks if the given factory match with the factory + * required by this instance. A factory matches if its + * name or its class name is equals to the 'component' + * property of the instance. Then the acceptability of + * the configuration is checked. + * @param factory the factory to confront against the current instance. + * @return true if the factory matches. */ public boolean match(IPojoFactory factory) { // Test factory name (and classname) @@ -313,8 +321,8 @@ } /** - * Create the instance by using the given factory. - * @param factory : the factory to use to create the instance. The factory must match. + * Creates the instance by using the given factory. + * @param factory the factory to use to create the instance. The factory must match. */ public void create(IPojoFactory factory) { try { @@ -333,7 +341,7 @@ } /** - * Dispose the current instance. + * Disposes the current instance if not null. */ public void dispose() { if (m_instance != null) { Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java?rev=698589&r1=698588&r2=698589&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java Wed Sep 24 07:26:55 2008 @@ -518,12 +518,8 @@ } return m_pojoObjects.toArray(new Object[m_pojoObjects.size()]); } - - /** - * Create an instance of the component. This method need to be called one time only for singleton provided service. - * @return a new instance - */ - public Object createPojoObject() { + + private Object createObject() { if (m_clazz == null) { load(); } @@ -662,6 +658,16 @@ return null; } } + return instance; + } + + /** + * Create an instance of the component. + * This method need to be called one time only for singleton provided service. + * @return a new instance + */ + public Object createPojoObject() { + Object instance = createObject(); // Add the new instance in the instance list. synchronized (this) { @@ -684,17 +690,27 @@ */ public Object getPojoObject() { Object pojo = null; + boolean newPOJO = false; synchronized (this) { if (m_pojoObjects != null) { pojo = m_pojoObjects.get(0); // Stack confinement + } else { + pojo = createObject(); // Stack confinement + if (m_pojoObjects == null) { + m_pojoObjects = new ArrayList(1); + } + m_pojoObjects.add(pojo); + newPOJO = true; } } - if (pojo == null) { - return createPojoObject(); // This method must be called without the lock. - } else { - return pojo; - } + // Call createInstance on Handlers : + for (int i = 0; newPOJO && i < m_handlers.length; i++) { + ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(pojo); + } + //NOTE this method allows returning a POJO object before calling the onCreation on handler. + + return pojo; } /** Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java?rev=698589&r1=698588&r2=698589&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java Wed Sep 24 07:26:55 2008 @@ -321,7 +321,8 @@ * @param configuration : the new configuration * @see org.apache.felix.ipojo.Handler#reconfigure(java.util.Dictionary) */ - public synchronized void reconfigure(Dictionary configuration) { + public synchronized void reconfigure(Dictionary configuration) { + warn(getInstanceManager().getInstanceName() + " is reconfiguring the properties : " + configuration); Properties props = reconfigureProperties(configuration); propagate(props, m_propagatedFromInstance); m_propagatedFromInstance = props; @@ -348,12 +349,16 @@ m_configurableProperties[i].setValue(value); getInstanceManager().onSet(null, m_configurableProperties[i].getField(), m_configurableProperties[i].getValue()); // Notify other handler of the field value change. if (m_configurableProperties[i].hasMethod()) { - m_configurableProperties[i].invoke(null); // Call on all created pojo objects. + if (getInstanceManager().getPojoObjects() != null) { + m_configurableProperties[i].invoke(null); // Call on all created pojo objects. + } } } } else if (m_configurableProperties[i].hasMethod()) { // Method but no field m_configurableProperties[i].setValue(value); - m_configurableProperties[i].invoke(null); // Call on all created pojo objects. + if (getInstanceManager().getPojoObjects() != null) { + m_configurableProperties[i].invoke(null); // Call on all created pojo objects. + } } found = true; break; Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java?rev=698589&r1=698588&r2=698589&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java Wed Sep 24 07:26:55 2008 @@ -205,7 +205,8 @@ // - if instances already exists : call on each instances // - if no instance exists : create an instance if (m_manager.getPojoObjects() == null) { - return m_methodObj.invoke(m_manager.getPojoObject(), arg); + Object r = m_methodObj.invoke(m_manager.getPojoObject(), arg); + return r; } else { Object newObject = null; for (int i = 0; i < m_manager.getPojoObjects().length; i++) { Modified: felix/trunk/ipojo/handler/eventadmin/src/main/resources/event-admin.xsd URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/src/main/resources/event-admin.xsd?rev=698589&r1=698588&r2=698589&view=diff ============================================================================== --- felix/trunk/ipojo/handler/eventadmin/src/main/resources/event-admin.xsd (original) +++ felix/trunk/ipojo/handler/eventadmin/src/main/resources/event-admin.xsd Wed Sep 24 07:26:55 2008 @@ -22,20 +22,66 @@ elementFormDefault="qualified"> - - - - - + + Description of an event publisher. + + + + The name of the event publisher, acting as a unique identifier. +The name of the POJO's field that will be used to send events. The field is initialized at component instantiation time. The type of the field must be "org.apache.felix.ipojo.handlers.event.publisher.Publisher". + + + + The name of the POJO field associated to this event publisher. +Despite it creates a dependency between the component code and the handler, this system allows hiding the whole complexity of event sending. + + + + The comma-separated-list of the topics on which events will be sent. All subscribers that are listening to one of these topics will receive the events. + + + Determines if event sending is synchronous or not. By default, events are sent asynchronously, but you can specify there the desired behaviour of the Publisher. +The default value of this attribute is "false". + + + + The data key is used when you want to send data events. This attribute's value is the key, in the event's dictionary, in which sent data are stored. When you use the sendData method of the Publisher, the given object is placed in the event dictionary, associated with the specified data-key. +The default value of this attribute is user.data. - - - - - - + + Description of an event subscriber. + + + + The name of the event subscriber, acting as a unique identifier. + + + The name of the POJO's method that will be called each time an event is received. +This method takes only one parameter, of typeorg.osgi.service.event.Eventby default, but this type can be overridden by defining the data-key and/or the data-type attributes. + + + + The comma-separated-list of the topics that the handler will listen to. Each event sent on a topic present in this list will be sent to the specified callback method. + + + The event filter is used to filter incoming events before sending them to the callback. +The syntax of this field is described in the OSGi EventAdmin Specification. If you don't specify a filter, all events sent on the listened topics will be considered. + + + + The data key is used when you want to receive data events. This attribute's value is the key corresponding to the received data in the event's dictionary. +If you use this attribute, the parameter passed to the callback method is the the value associated to this key, not the whole event. +This attribute is generally used with the data-typeattribute to specify the received object type. +If an event is received and it does not contain such a key, it is ignored (with a warning message). + + + + This attribute is associated to the data-key attribute. It specifies the type of objects (java.lang.Object by default) that the callback expects. +It is used to determine the unique callback method (in case of multiple methods with the same name) and to check type compliance at event reception. +Data events that are not corresponding to the specified type will be ignored (with a warning message). + Modified: felix/trunk/ipojo/handler/extender/src/main/resources/extender-pattern.xsd URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/extender/src/main/resources/extender-pattern.xsd?rev=698589&r1=698588&r2=698589&view=diff ============================================================================== --- felix/trunk/ipojo/handler/extender/src/main/resources/extender-pattern.xsd (original) +++ felix/trunk/ipojo/handler/extender/src/main/resources/extender-pattern.xsd Wed Sep 24 07:26:55 2008 @@ -22,8 +22,21 @@ elementFormDefault="qualified"> - - - + + Description of the extender pattern configuration. +The extender tracks extensions. The particularity of this architecture-style is that extensions are packaged in different bundles. An extension is detected by analyzing the bundle. The mark is currently a header in the bundle manifest. At each time a matching bundle appears or disappears, a callback is invoked. + + + + Declaring the method to invoke when a matching bundle arrives + + + + Declaring the method to invoke when a matching bundle leaves + + + + Declaring the looked manifest header. + \ No newline at end of file Modified: felix/trunk/ipojo/handler/jmx/src/main/resources/jmx.xsd URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/src/main/resources/jmx.xsd?rev=698589&r1=698588&r2=698589&view=diff ============================================================================== --- felix/trunk/ipojo/handler/jmx/src/main/resources/jmx.xsd (original) +++ felix/trunk/ipojo/handler/jmx/src/main/resources/jmx.xsd Wed Sep 24 07:26:55 2008 @@ -24,37 +24,154 @@ + + + Description of a JMX managed component. + + - - + + + + The list of methods to expose. + + + + + + + The list of attributes to expose. + + + + + + Determines if the component must be register on the + MOSGi MBean server or not. + + + + + The complete object name of the managed component. + The syntax of this attribute must be compliant with + the ObjectName syntax, detailed in the JMX + specification. If neither domain nor name attributes + are specified, the default value is determined by + the package, the type and the instance name of the + component. This attribute overrides the domain and + name attributes. + + + + + + + The domain of the managed object (i.e., the left + part of the object name). This attribute must be + compliant with the domain syntax, as described in + the JMX specification. + + + + + + + The name property of the managed object. The value + of this attribute must comply with the ObjectName + value syntax, as described in the JMX specification. + + - - + + + + Specifies method to carry out operations before + beeing registered from the MBean server. The + signature of the specified method must be : + "ObjectName preRegister(MBeanServer server, + ObjectName name) throws Exception". + + + + + + + Specifies method to carry out operations after + beeing registered from the MBean server. The + signature of the specified method must be : "void + postRegister(Boolean registrationDone)". + + + + + + + Specifies method to carry out operations before + beeing unregistered from the MBean server. The + signature of the specified method must be : "void + preDeregister() throws Exception". + + + + + + + Specifies method to carry out operations after + beeing unregistered from the MBean server. The + signature of the specified method must be : + "void postDeregister()". + - - + + Description of an attribute to expose. + + + + The name of the component's field to expose. + + + The name of the property as it will appear in JMX. If unspecified, the default value is the name of the exposed field. - - + + Specify the access permission of the exposed field. + + + + Access permission of an exposed field. Accepted values are "r" (read-only access, the default value) and "w" (read and write access). + + - + + + Enable or disable attribute change notification sending for this property. If set to "true", a notification is sent each time the value of the field changes. - - + + Description of a method to expose. + + + + The name of the method to expose. If multiple methods have the same name, all of them are exposed. + + + + The description of the exposed method, as it will appear in JMX. \ No newline at end of file Modified: felix/trunk/ipojo/handler/temporal/src/main/resources/temporal.xsd URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/temporal/src/main/resources/temporal.xsd?rev=698589&r1=698588&r2=698589&view=diff ============================================================================== --- felix/trunk/ipojo/handler/temporal/src/main/resources/temporal.xsd (original) +++ felix/trunk/ipojo/handler/temporal/src/main/resources/temporal.xsd Wed Sep 24 07:26:55 2008 @@ -24,15 +24,23 @@ - - + + Description of a temporal dependency. + + + + The implementation field supporting the dependency. + + + + Filter use to discover matching filter. - Specifies the timeout after which the onTimeout policy is executed. The value is the time in ms to wait. -1 is used to indicate an infinite wait. + Specifies the timeout after which the onTimeout policy is executed. The value is the time in ms to wait. -1 is used to indicate an infinite wait. - Specifies the onTimeout policy. This determines the object to inject when the service stills unavailable when the timeout expires. Several values are supported: - 'nullable' means that a Nullable object will be injected - 'empty-array' injects an empty array (only for aggregate dependency) - 'null' injects Null - any other value are interpreted as the default implementation class to use. If the onTimetout attribute is not specified, a RuntimeException is thrown when the timeout is reached. + Specifies the onTimeout policy. This determines the object to inject when the service stills unavailable when the timeout expires. Several values are supported: 'nullable' means that a Nullable object will be injected, 'empty-array' injects an empty array (only for aggregate dependency), 'null' injects Null, any other value are interpreted as the default implementation class to use. If the onTimetout attribute is not specified, a RuntimeException is thrown when the timeout is reached. Modified: felix/trunk/ipojo/handler/whiteboard/src/main/resources/whiteboard-pattern.xsd URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/whiteboard/src/main/resources/whiteboard-pattern.xsd?rev=698589&r1=698588&r2=698589&view=diff ============================================================================== --- felix/trunk/ipojo/handler/whiteboard/src/main/resources/whiteboard-pattern.xsd (original) +++ felix/trunk/ipojo/handler/whiteboard/src/main/resources/whiteboard-pattern.xsd Wed Sep 24 07:26:55 2008 @@ -22,9 +22,24 @@ elementFormDefault="qualified"> - - - - + + Description of the white-board architecture. + + + + Declaring the method to invoke when a matching service arrives. + + + + Declaring the method to invoke when a matching service leaves. + + + + Method called when an injected service reference is modified but stills valid against the filter. + + + + Filter use to discover matching filter. + \ No newline at end of file Added: felix/trunk/ipojo/tests/core/configadmin/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/configadmin/pom.xml?rev=698589&view=auto ============================================================================== --- felix/trunk/ipojo/tests/core/configadmin/pom.xml (added) +++ felix/trunk/ipojo/tests/core/configadmin/pom.xml Wed Sep 24 07:26:55 2008 @@ -0,0 +1,101 @@ + + + 4.0.0 + bundle + iPOJO Configuration Admin Management Test Suite + tests.core.configadmin + ipojo.tests + 0.9.0-SNAPSHOT + + + org.apache.felix + org.apache.felix.ipojo + 0.9.0-SNAPSHOT + + + org.apache.felix + org.apache.felix.ipojo.metadata + 0.9.0-SNAPSHOT + + + org.apache.felix + org.osgi.core + 1.0.0 + + + junit + junit + 3.8.1 + + + ipojo.examples + org.apache.felix.ipojo.junit4osgi + 0.9.0-SNAPSHOT + + + + + + org.apache.felix + maven-bundle-plugin + 1.4.2 + true + + + + org.apache.felix.ipojo.test.scenarios.configadmin.service + + + ${pom.artifactId} + + + org.apache.felix.ipojo.test* + + + org.apache.felix.ipojo.test.scenarios.configadmin.ConfigurationTestSuite + + + + + org.apache.felix + maven-ipojo-plugin + 0.9.0-SNAPSHOT + + + + ipojo-bundle + + + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.4 + 1.4 + + + + + Added: felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ConfigurableFooProvider.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ConfigurableFooProvider.java?rev=698589&view=auto ============================================================================== --- felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ConfigurableFooProvider.java (added) +++ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ConfigurableFooProvider.java Wed Sep 24 07:26:55 2008 @@ -0,0 +1,53 @@ +package org.apache.felix.ipojo.test.scenarios.component; + +import java.util.Properties; + +import org.apache.felix.ipojo.test.scenarios.configadmin.service.FooService; + +public class ConfigurableFooProvider implements FooService { + + private String message; // Configurable property + private int invokeCount = 0; + + public void setMessage(String message) { + System.out.println("Set message to " + message); + this.message = message; + invokeCount++; + } + + public boolean foo() { + return true; + } + + public Properties fooProps() { + Properties props = new Properties(); + if (message == null) { + props.put("message", "NULL"); + } else { + props.put("message", message); + } + props.put("count", new Integer(invokeCount)); + return props; + } + + public boolean getBoolean() { + return false; + } + + public double getDouble() { + return invokeCount; + } + + public int getInt() { + return invokeCount; + } + + public long getLong() { + return invokeCount; + } + + public Boolean getObject() { + return null; + } + +} Added: felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ConfigurationTestSuite.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ConfigurationTestSuite.java?rev=698589&view=auto ============================================================================== --- felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ConfigurationTestSuite.java (added) +++ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ConfigurationTestSuite.java Wed Sep 24 07:26:55 2008 @@ -0,0 +1,37 @@ +/* + * 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.felix.ipojo.test.scenarios.configadmin; + +import junit.framework.Test; + +import org.apache.felix.ipojo.junit4osgi.OSGiTestSuite; +import org.osgi.framework.BundleContext; + +public class ConfigurationTestSuite { + + public static Test suite(BundleContext bc) { + OSGiTestSuite ots = new OSGiTestSuite("Configuration Admin Test Suite", bc); + ots.addTestSuite(ManagedServiceFactoryTestForServices.class); + ots.addTestSuite(ManagedServiceFactoryTestForImmediate.class); + ots.addTestSuite(ManagedServiceTestForImmediate.class); + ots.addTestSuite(ManagedServiceTestForService.class); + return ots; + } + +} Added: felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForImmediate.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForImmediate.java?rev=698589&view=auto ============================================================================== --- felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForImmediate.java (added) +++ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForImmediate.java Wed Sep 24 07:26:55 2008 @@ -0,0 +1,337 @@ +package org.apache.felix.ipojo.test.scenarios.configadmin; + +import java.io.IOException; +import java.util.Dictionary; +import java.util.Properties; + +import org.apache.felix.ipojo.ComponentFactory; +import org.apache.felix.ipojo.architecture.Architecture; +import org.apache.felix.ipojo.junit4osgi.OSGiTestCase; +import org.apache.felix.ipojo.test.scenarios.configadmin.service.FooService; +import org.apache.felix.ipojo.test.scenarios.util.Utils; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; + +public class ManagedServiceFactoryTestForImmediate extends OSGiTestCase { + + private ComponentFactory factory; + private ConfigurationAdmin admin; + + public void setUp() { + factory = (ComponentFactory) Utils.getFactoryByName(context, "CA-ImmConfigurableProvider"); + admin = (ConfigurationAdmin) Utils.getServiceObject(context, ConfigurationAdmin.class.getName(), null); + assertNotNull("Check configuration admin availability", admin); + try { + Configuration[] configurations = admin.listConfigurations("(service.factoryPid=CA-ImmConfigurableProvider)"); + for (int i = 0; configurations != null && i < configurations.length; i++) { + configurations[i].delete(); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidSyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void tearDown() { + try { + Configuration[] configurations = admin.listConfigurations("(service.factoryPid=CA-ImmConfigurableProvider)"); + for (int i = 0; configurations != null && i < configurations.length; i++) { + configurations[i].delete(); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidSyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + admin = null; + + + } + + public void testCreationAndReconfiguration() { + Configuration configuration = null; + try { + configuration = admin.createFactoryConfiguration("CA-ImmConfigurableProvider", null); + } catch (IOException e) { + fail(e.getMessage()); + } + Dictionary props = configuration.getProperties(); + if(props == null) { + props = new Properties(); + } + props.put("message", "message"); + + try { + configuration.update(props); + } catch (IOException e) { + fail(e.getMessage()); + } + + String pid = configuration.getPid(); + System.out.println("PID : " + pid); + + // The instance should be created, wait for the architecture service + Utils.waitForService(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + Architecture architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + FooService fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + Properties p = fs.fooProps(); + String mes = p.getProperty("message"); + int count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message", mes); + assertEquals("Assert count", 1, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + props.put("message", "message2"); + try { + configuration.update(props); + // Update the configuration ... + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + p = fs.fooProps(); + mes = p.getProperty("message"); + count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message2", mes); + assertEquals("Assert count", 2, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + try { + configuration.delete(); + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + ServiceReference ref = Utils.getServiceReference(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + assertNull("Check unavailability", ref); + } + + public void testCreationAndReconfiguration2() { + //The reconfiguration happens before the service invocation + Configuration configuration = null; + try { + configuration = admin.createFactoryConfiguration("CA-ImmConfigurableProvider", null); + } catch (IOException e) { + fail(e.getMessage()); + } + Dictionary props = configuration.getProperties(); + if(props == null) { + props = new Properties(); + } + props.put("message", "message"); + + try { + configuration.update(props); + } catch (IOException e) { + fail(e.getMessage()); + } + + String pid = configuration.getPid(); + System.out.println("PID : " + pid); + + // The instance should be created, wait for the architecture service + Utils.waitForService(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + Architecture architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + props.put("message", "message2"); + try { + configuration.update(props); + // Update the configuration ... + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check object -2", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + //Invoke + FooService fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + Properties p = fs.fooProps(); + String mes = p.getProperty("message"); + int count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message2", mes); + assertEquals("Assert count", 2, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + try { + configuration.delete(); + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + ServiceReference ref = Utils.getServiceReference(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + assertNull("Check unavailability", ref); + } + + public void testDelayedCreationAndReconfiguration() { + factory.stop(); + Configuration configuration = null; + try { + configuration = admin.createFactoryConfiguration("CA-ImmConfigurableProvider", null); + } catch (IOException e) { + fail(e.getMessage()); + } + Dictionary props = configuration.getProperties(); + if(props == null) { + props = new Properties(); + } + props.put("message", "message"); + + try { + configuration.update(props); + } catch (IOException e) { + fail(e.getMessage()); + } + + String pid = configuration.getPid(); + System.out.println("PID : " + pid); + + assertNull("check no instance", Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")")); + + factory.start(); + + + // The instance should be created, wait for the architecture service + Utils.waitForService(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + Architecture architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + FooService fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + Properties p = fs.fooProps(); + String mes = p.getProperty("message"); + int count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message", mes); + assertEquals("Assert count", 1, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + props.put("message", "message2"); + try { + configuration.update(props); + // Update the configuration ... + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + p = fs.fooProps(); + mes = p.getProperty("message"); + count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message2", mes); + //assertEquals("Assert count", 2, count); + // This test was removed as the result can be 3. + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + try { + configuration.delete(); + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + ServiceReference ref = Utils.getServiceReference(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + assertNull("Check unavailability", ref); + } + + public void testDelayedCreationAndReconfiguration2() { + factory.stop(); + //The reconfiguration happens before the service invocation + Configuration configuration = null; + try { + configuration = admin.createFactoryConfiguration("CA-ImmConfigurableProvider", null); + } catch (IOException e) { + fail(e.getMessage()); + } + Dictionary props = configuration.getProperties(); + if(props == null) { + props = new Properties(); + } + props.put("message", "message"); + + try { + configuration.update(props); + } catch (IOException e) { + fail(e.getMessage()); + } + + String pid = configuration.getPid(); + System.out.println("PID : " + pid); + + assertNull("check no instance", Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")")); + + factory.start(); + + + // The instance should be created, wait for the architecture service + Utils.waitForService(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + Architecture architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + props.put("message", "message2"); + try { + configuration.update(props); + // Update the configuration ... + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check object -1", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + //Invoke + FooService fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + Properties p = fs.fooProps(); + String mes = p.getProperty("message"); + int count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message2", mes); + //assertEquals("Assert count", 2, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + try { + configuration.delete(); + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + ServiceReference ref = Utils.getServiceReference(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + assertNull("Check unavailability", ref); + } + + + +} Added: felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForServices.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForServices.java?rev=698589&view=auto ============================================================================== --- felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForServices.java (added) +++ felix/trunk/ipojo/tests/core/configadmin/src/main/java/org/apache/felix/ipojo/test/scenarios/configadmin/ManagedServiceFactoryTestForServices.java Wed Sep 24 07:26:55 2008 @@ -0,0 +1,340 @@ +package org.apache.felix.ipojo.test.scenarios.configadmin; + +import java.io.IOException; +import java.util.Dictionary; +import java.util.Properties; + +import org.apache.felix.ipojo.ComponentFactory; +import org.apache.felix.ipojo.architecture.Architecture; +import org.apache.felix.ipojo.junit4osgi.OSGiTestCase; +import org.apache.felix.ipojo.test.scenarios.configadmin.service.FooService; +import org.apache.felix.ipojo.test.scenarios.util.Utils; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; + +public class ManagedServiceFactoryTestForServices extends OSGiTestCase { + + private ComponentFactory factory; + private ConfigurationAdmin admin; + + public void setUp() { + factory = (ComponentFactory) Utils.getFactoryByName(context, "CA-ConfigurableProvider"); + admin = (ConfigurationAdmin) Utils.getServiceObject(context, ConfigurationAdmin.class.getName(), null); + assertNotNull("Check configuration admin availability", admin); + try { + Configuration[] configurations = admin.listConfigurations("(service.factoryPid=CA-ConfigurableProvider)"); + for (int i = 0; configurations != null && i < configurations.length; i++) { + configurations[i].delete(); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidSyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public void tearDown() { + try { + Configuration[] configurations = admin.listConfigurations("(service.factoryPid=CA-ConfigurableProvider)"); + for (int i = 0; configurations != null && i < configurations.length; i++) { + configurations[i].delete(); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvalidSyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + admin = null; + + + } + + public void testCreationAndReconfiguration() { + Configuration configuration = null; + try { + configuration = admin.createFactoryConfiguration("CA-ConfigurableProvider", null); + } catch (IOException e) { + fail(e.getMessage()); + } + Dictionary props = configuration.getProperties(); + if(props == null) { + props = new Properties(); + } + props.put("message", "message"); + + try { + configuration.update(props); + } catch (IOException e) { + fail(e.getMessage()); + } + + String pid = configuration.getPid(); + System.out.println("PID : " + pid); + + // The instance should be created, wait for the architecture service + Utils.waitForService(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + Architecture architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check no object", 0, architecture.getInstanceDescription().getCreatedObjects().length); + + FooService fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + Properties p = fs.fooProps(); + String mes = p.getProperty("message"); + int count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message", mes); + assertEquals("Assert count", 1, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + props.put("message", "message2"); + try { + configuration.update(props); + // Update the configuration ... + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + p = fs.fooProps(); + mes = p.getProperty("message"); + count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message2", mes); + assertEquals("Assert count", 2, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + try { + configuration.delete(); + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + ServiceReference ref = Utils.getServiceReference(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + assertNull("Check unavailability", ref); + } + + public void testCreationAndReconfiguration2() { + //The reconfiguration happens before the service invocation + Configuration configuration = null; + try { + configuration = admin.createFactoryConfiguration("CA-ConfigurableProvider", null); + } catch (IOException e) { + fail(e.getMessage()); + } + Dictionary props = configuration.getProperties(); + if(props == null) { + props = new Properties(); + } + props.put("message", "message"); + + try { + configuration.update(props); + } catch (IOException e) { + fail(e.getMessage()); + } + + String pid = configuration.getPid(); + System.out.println("PID : " + pid); + + // The instance should be created, wait for the architecture service + Utils.waitForService(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + Architecture architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check no object", 0, architecture.getInstanceDescription().getCreatedObjects().length); + + props.put("message", "message2"); + try { + configuration.update(props); + // Update the configuration ... + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check no object -2", 0, architecture.getInstanceDescription().getCreatedObjects().length); + + //Invoke + FooService fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + Properties p = fs.fooProps(); + String mes = p.getProperty("message"); + int count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message2", mes); + assertEquals("Assert count", 1, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + try { + configuration.delete(); + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + ServiceReference ref = Utils.getServiceReference(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + assertNull("Check unavailability", ref); + } + + public void testDelayedCreationAndReconfiguration() { + factory.stop(); + Configuration configuration = null; + try { + configuration = admin.createFactoryConfiguration("CA-ConfigurableProvider", null); + } catch (IOException e) { + fail(e.getMessage()); + } + Dictionary props = configuration.getProperties(); + if(props == null) { + props = new Properties(); + } + props.put("message", "message"); + + try { + configuration.update(props); + } catch (IOException e) { + fail(e.getMessage()); + } + + String pid = configuration.getPid(); + System.out.println("PID : " + pid); + + assertNull("check no instance", Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")")); + + factory.start(); + + + // The instance should be created, wait for the architecture service + Utils.waitForService(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + Architecture architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check no object", 0, architecture.getInstanceDescription().getCreatedObjects().length); + + FooService fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + Properties p = fs.fooProps(); + String mes = p.getProperty("message"); + int count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message", mes); + assertEquals("Assert count", 1, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + System.out.println("==="); + + props.put("message", "message2"); + try { + configuration.update(props); + // Update the configuration ... + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + System.out.println("==="); + + fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + p = fs.fooProps(); + mes = p.getProperty("message"); + count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message2", mes); + // assertEquals("Assert count", 2, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + try { + configuration.delete(); + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + ServiceReference ref = Utils.getServiceReference(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + assertNull("Check unavailability", ref); + } + + public void testDelayedCreationAndReconfiguration2() { + factory.stop(); + //The reconfiguration happens before the service invocation + Configuration configuration = null; + try { + configuration = admin.createFactoryConfiguration("CA-ConfigurableProvider", null); + } catch (IOException e) { + fail(e.getMessage()); + } + Dictionary props = configuration.getProperties(); + if(props == null) { + props = new Properties(); + } + props.put("message", "message"); + + try { + configuration.update(props); + } catch (IOException e) { + fail(e.getMessage()); + } + + String pid = configuration.getPid(); + System.out.println("PID : " + pid); + + assertNull("check no instance", Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")")); + + factory.start(); + + + // The instance should be created, wait for the architecture service + Utils.waitForService(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + Architecture architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check no object", 0, architecture.getInstanceDescription().getCreatedObjects().length); + + props.put("message", "message2"); + try { + configuration.update(props); + // Update the configuration ... + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Check no object -2", 0, architecture.getInstanceDescription().getCreatedObjects().length); + + //Invoke + FooService fs = (FooService) Utils.getServiceObject(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + Properties p = fs.fooProps(); + String mes = p.getProperty("message"); + int count = ((Integer) p.get("count")).intValue(); + architecture = (Architecture) Utils.getServiceObject(context, Architecture.class.getName(), "(architecture.instance="+pid+")"); + + assertEquals("Assert Message", "message2", mes); + assertEquals("Assert count", 1, count); + assertEquals("Check 1 object", 1, architecture.getInstanceDescription().getCreatedObjects().length); + + try { + configuration.delete(); + Thread.sleep(10); + } catch (Exception e) { + fail(e.getMessage()); + } + + ServiceReference ref = Utils.getServiceReference(context, FooService.class.getName(), "(instance.name=" + pid + ")"); + assertNull("Check unavailability", ref); + } + + + +}