You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by tj...@apache.org on 2020/10/09 14:28:54 UTC

[felix-dev] branch scrR8 updated (49599cc -> 35c51c7)

This is an automated email from the ASF dual-hosted git repository.

tjwatson pushed a change to branch scrR8
in repository https://gitbox.apache.org/repos/asf/felix-dev.git.


    from 49599cc  Update minor version for OSGi R8 SCR implementation
     add 810b56a  FELIX-6326: don't encode resource urls but handle query and refs directly.
     add 87f3aff  FELIX-6327 - NoSuchElementException when services are removed
     add c3f6eba  Merge pull request #47 from tjwatson/FELIX-6327
     add 0ccae0a  FELIX-4678 : No list of denied event handlers available
     add 6ee400e  Update webconsole event plugin to latest parent poim
     add bb581d9  FELIX-6329 : Update event admin to Java 8
     add c0cb779  FELIX-6330 : Use term deny list for event handlers hitting the timeout
     add bf93a1d  FELIX-6328 : Web Console (All In One) imports javax.portlet via fileupload
     add 495cb80  FELIX-6329 : Update event admin to Java 8
     add dba0764  FELIX-6329 : Update event admin to Java 8
     add 4f9358c  FELIX-6318: Fix tiny thread safety bug in BundleWiringImpl::getClassLoader
     add 494ec53  Merge pull request #41 from rhernandez35/master
     add febfde7  FELIX-6315: do not deactivate factory component configurations
     add 28b8f0e  Merge pull request #37 from rovarga/felix6315
     add 1046fb7  [maven-release-plugin] prepare release org.apache.felix.scr-2.1.24
     add cfa7bc5  [maven-release-plugin] prepare for next development iteration
     add 7378a7f  FELIX-6331: fix a race condtion in unget service from service factory.
     add db90841  Enable animal sniffer
     add 08d2eac  FELIX-6324 : Protect code against IllegalStateException and IllegalArgumentException
     add b842bcc  FELIX-6334 : Switch to Java 8
     add 93a1975  FELIX-6333 : Update to Jetty 9.4.31.v20200723
     add 03eccc6  Prepare http release
     add f29aa29  [maven-release-plugin] prepare release org.apache.felix.http.base-4.1.0
     add 9a4a971  [maven-release-plugin] prepare for next development iteration
     add 08d6d4c  [maven-release-plugin] prepare release org.apache.felix.http.bridge-4.1.0
     add 0fa8a1d  [maven-release-plugin] prepare for next development iteration
     add 2444d82  [maven-release-plugin] prepare release org.apache.felix.http.jetty-4.1.0
     add b916888  [maven-release-plugin] prepare for next development iteration
     add 31aea2b  FELIX-6342 HTTP Session not invalidated over HTTPS (#55)
     add 0e0729d  FELIX-6342 : HTTP Session not invalidated over HTTPS
     add 0da0100  FELIX-6341 ConfigAdmin - deleting a configuration logs a string that (#54)
     add 5226995  FELIX-6341 : Update changelog
     add 5d624af  Make http projects buildable with Java >= 9
     add 41e3c64  FELIX-6343 : Update Jetty to 9.4.32.v20200930
     add 58bed83  Make project compilable with Java >= 9
     add 2a06d9c  Prepare http release
     add 4bcd631  [maven-release-plugin] prepare release org.apache.felix.http.parent-13
     add c54f42c  [maven-release-plugin] prepare for next development iteration
     add efc950b  [maven-release-plugin] prepare release org.apache.felix.http.base-4.1.2
     add 06e1eab  [maven-release-plugin] prepare for next development iteration
     add 7827c2f  [maven-release-plugin] prepare release org.apache.felix.http.bridge-4.1.2
     add ad0153b  [maven-release-plugin] prepare for next development iteration
     add a3363a9  [maven-release-plugin] prepare release org.apache.felix.http.jetty-4.1.2
     add 6573a17  [maven-release-plugin] prepare for next development iteration
     add 9443607  Use released version of gogo parent pom v6
     add d2b1064  Update change logs
     add bd451fe  [maven-release-plugin] prepare release org.apache.felix.gogo.runtime-1.1.4
     add 0444d87  [maven-release-plugin] prepare for next development iteration
     add 4573b2a  Use release version of gogo runtime v1.1.4
     add 05764b4  [maven-release-plugin] prepare release org.apache.felix.gogo.shell-1.1.4
     add c1c7ba4  [maven-release-plugin] prepare for next development iteration
     add 1cf4877  Use release version of gogo runtime v1.1.4
     add 4e3039f  [maven-release-plugin] prepare release org.apache.felix.gogo.command-1.1.2
     add 5a733c2  [maven-release-plugin] prepare for next development iteration
     add 0ad1a4f  Update to released versions runtime, shell, command, jline
     add 5782241  [maven-release-plugin] prepare release org.apache.felix.gogo.bom-1.0.4
     add a4d2d72  [maven-release-plugin] prepare for next development iteration
     add 89f006f  FELIX-6018 Use more generic label "Service Unavailable" in servlet
     add 03288b9  FELIX-6344 - Also catch Throwable to make sure the future is always removed
     new b186ccc  Merge branch 'master' into scrR8
     new 35c51c7  OSGi R8 - Add support for satisfying condition

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 eventadmin/impl/changelog.txt                      |   9 +
 eventadmin/impl/pom.xml                            |  22 +--
 .../apache/felix/eventadmin/impl/Activator.java    |   4 +-
 .../felix/eventadmin/impl/Configuration.java       |  24 ++-
 .../eventadmin/impl/MetaTypeProviderImpl.java      |   4 +-
 .../impl/adapter/BundleEventAdapter.java           |   5 +-
 .../impl/adapter/FrameworkEventAdapter.java        |   6 +-
 .../eventadmin/impl/adapter/LogEventAdapter.java   |  69 ++-----
 .../impl/adapter/ServiceEventAdapter.java          |  48 +----
 .../eventadmin/impl/handler/EventAdminImpl.java    |  23 +++
 .../eventadmin/impl/handler/EventHandlerProxy.java |  33 ++--
 .../impl/handler/EventHandlerTracker.java          |  33 ++++
 .../{BlacklistLatch.java => DenylistLatch.java}    |  22 +--
 .../felix/eventadmin/impl/tasks/HandlerTask.java   |  16 +-
 .../eventadmin/impl/tasks/SyncDeliverTasks.java    |   8 +-
 .../felix/eventadmin/impl/util/LogWrapper.java     |  28 +--
 .../felix/eventadmin/ittests/AbstractTest.java     |  27 ++-
 .../apache/felix/eventadmin/ittests/Listener.java  |   4 +-
 .../eventadmin/perftests/PerformanceTestIT.java    |  46 +++--
 .../apache/felix/framework/BundleRevisionImpl.java |  29 +--
 .../apache/felix/framework/BundleWiringImpl.java   |   2 +-
 .../apache/felix/framework/ServiceRegistry.java    |   9 +-
 .../framework/URLHandlersBundleURLConnection.java  |  15 +-
 .../felix/framework/ResourceLoadingTest.java       |   8 +
 gogo/bom/pom.xml                                   |  13 +-
 gogo/command/doc/changelog.txt                     |   5 +
 gogo/command/pom.xml                               |   9 +-
 gogo/itest-jline/pom.xml                           |   2 +-
 gogo/itest-shell/pom.xml                           |   2 +-
 gogo/runtime/doc/changelog.txt                     |   6 +
 gogo/runtime/pom.xml                               |   7 +-
 gogo/shell/doc/changelog.txt                       |   8 +
 gogo/shell/pom.xml                                 |   9 +-
 .../hc/core/impl/executor/HealthCheckFuture.java   |  14 +-
 .../core/impl/filter/ServiceUnavailableFilter.java |   2 +-
 http/base/pom.xml                                  |   8 +-
 .../felix/http/base/internal/HttpConfig.java       |  94 +++++++++
 .../base/internal/handler/HttpSessionWrapper.java  |  20 +-
 .../base/internal/handler/PreprocessorHandler.java |   7 +-
 .../internal/handler/WhiteboardFilterHandler.java  |  22 +--
 .../handler/WhiteboardListenerHandler.java         |  22 +--
 .../internal/handler/WhiteboardServletHandler.java |  18 +-
 .../internal/logger/LogServiceEnabledLogger.java   |   5 +-
 .../internal/runtime/dto/RuntimeDTOBuilder.java    |   6 -
 .../internal/service/PerBundleHttpServiceImpl.java |   3 +-
 .../http/base/internal/util/ServiceUtils.java      |  89 +++++++++
 .../whiteboard/SharedServletContextImpl.java       |   1 -
 .../whiteboard/WhiteboardContextHandler.java       |  32 ++--
 .../internal/context/ServletContextImplTest.java   |   6 +-
 .../internal/handler/FilterConfigImplTest.java     |  14 +-
 .../internal/handler/HttpSessionWrapperTest.java   |  67 +++++++
 .../internal/handler/ServletConfigImplTest.java    |  12 +-
 .../internal/registry/ErrorPageRegistryTest.java   |  11 +-
 .../registry/EventListenerRegistryTest.java        |   7 +-
 .../base/internal/registry/FilterRegistryTest.java |   6 +-
 .../internal/registry/ServletRegistryTest.java     |  13 +-
 .../internal/runtime/AbstractInfoOrderingTest.java |   6 +-
 .../base/internal/runtime/ListenerInfoTest.java    |   1 +
 http/bridge/pom.xml                                |  10 +-
 http/itest/pom.xml                                 |  36 ++--
 http/jetty/pom.xml                                 |  14 +-
 .../jetty/internal/ConfigMetaTypeProvider.java     |   8 +
 .../jetty/internal/ConnectorFactoryTracker.java    |   7 +-
 .../felix/http/jetty/internal/JettyConfig.java     |   4 +-
 .../LoadBalancerCustomizerFactoryTracker.java      |  11 +-
 .../http/jetty/internal/RequestLogTracker.java     |  24 ++-
 http/parent/pom.xml                                |  13 +-
 http/pom.xml                                       |   2 +-
 http/sslfilter/pom.xml                             |  33 ++--
 .../java/org/apache/felix/scr/impl/Activator.java  |  40 +++-
 .../felix/scr/impl/BundleComponentActivator.java   |  15 +-
 .../felix/scr/impl/manager/ComponentActivator.java |   2 +
 .../felix/scr/impl/manager/DependencyManager.java  | 141 +++++++++++---
 .../felix/scr/impl/manager/ServiceTracker.java     |  41 +++-
 .../scr/impl/manager/SingleComponentManager.java   |   3 +-
 .../felix/scr/impl/metadata/ReferenceMetadata.java |   8 +
 .../org/apache/felix/scr/impl/xml/XmlHandler.java  |  31 ++-
 .../impl/manager/SingleComponentManagerTest.java   |   7 +
 .../felix/scr/impl/metadata/ComponentBase.java     |   6 +-
 .../truecondition/ComponentTestClass.java}         |  16 +-
 .../scr/impl/truecondition/TrueConditionTest.java  | 213 +++++++++++++++++++++
 .../apache/felix/scr/impl/xml/XmlHandlerTest.java  |  70 ++++++-
 .../scr/integration/ServiceBindGreedyTest.java     |  54 ++++--
 .../integration/components/SimpleComponent.java    |   8 +-
 .../integration/components/SimpleServiceImpl.java  |  24 ++-
 .../java/org/osgi/service/condition/Condition.java |  77 ++++++++
 ...s_11.xml => satisfying-condition-specified.xml} |   9 +-
 ...ivate_11.xml => satisfying_condition_test1.xml} |  15 +-
 ...ymous_11.xml => satisfying_condition_test2.xml} |  14 +-
 webconsole-plugins/event/pom.xml                   |  51 +++--
 .../plugins/event/internal/Activator.java          |   8 +-
 .../event/internal/ConfigurationListener.java      |  12 +-
 .../plugins/event/internal/EventCollector.java     |  18 +-
 .../plugins/event/internal/EventHandler.java       |   9 +-
 .../plugins/event/internal/EventInfo.java          |   4 +-
 .../event/internal/OptionalFeaturesHandler.java    |  31 ++-
 .../plugins/event/internal/OsgiUtil.java           |  30 +--
 .../plugins/event/internal/PluginServlet.java      |  23 ++-
 .../event/internal/PropertiesEditorSupport.java    |   6 +-
 .../internal/converter/ServiceEventConverter.java  |   7 +-
 webconsole/changelog.txt                           |   7 +
 webconsole/pom.xml                                 |   7 +-
 .../felix/webconsole/SimpleWebConsolePlugin.java   |  41 ++++
 .../i18n/ConsolePropertyResourceBundle.java        |   8 +-
 .../internal/servlet/OsgiManagerTest.java          |  14 ++
 105 files changed, 1643 insertions(+), 630 deletions(-)
 rename eventadmin/impl/src/main/java/org/apache/felix/eventadmin/impl/tasks/{BlacklistLatch.java => DenylistLatch.java} (79%)
 create mode 100644 http/base/src/main/java/org/apache/felix/http/base/internal/util/ServiceUtils.java
 copy scr/src/test/java/org/apache/felix/scr/{integration/components/activatesignature/Signature_Private_ComponentContext.java => impl/truecondition/ComponentTestClass.java} (70%)
 create mode 100644 scr/src/test/java/org/apache/felix/scr/impl/truecondition/TrueConditionTest.java
 create mode 100644 scr/src/test/java/org/osgi/service/condition/Condition.java
 copy scr/src/test/resources/{components_anonymous_11.xml => satisfying-condition-specified.xml} (70%)
 mode change 100644 => 100755
 copy scr/src/test/resources/{components_activate_11.xml => satisfying_condition_test1.xml} (71%)
 mode change 100644 => 100755
 copy scr/src/test/resources/{components_anonymous_11.xml => satisfying_condition_test2.xml} (67%)
 mode change 100644 => 100755


[felix-dev] 02/02: OSGi R8 - Add support for satisfying condition

Posted by tj...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tjwatson pushed a commit to branch scrR8
in repository https://gitbox.apache.org/repos/asf/felix-dev.git

commit 35c51c74723ae1fc638b66754f9c780dcd0e08f4
Author: Thomas Watson <tj...@us.ibm.com>
AuthorDate: Tue Sep 22 18:42:25 2020 -0500

    OSGi R8 - Add support for satisfying condition
    
    For R8 the DS specification adds support for the condition service by
    adding a default reference named "osgi.ds.satisfying.condition" which
    requires the condition with osgi.condition.id=true (i.e. the "true"
    condition published by R8 Core framework).
    
    The assumption is if this "true" Condition service exists and is
    published by the system bundle then it will always be available for the
    lifetime of the active framework.  If the "true" Condition service is
    found then SCR must automatically add a reference to the "true"
    condition using the reference name "osgi.ds.satisfying.condition".  The
    component property "osgi.ds.satisfying.condition.target" can be used to
    override the default target for matching the true condition
    "(osgi.condition.id=true)".
---
 .../java/org/apache/felix/scr/impl/Activator.java  |  40 +++-
 .../felix/scr/impl/BundleComponentActivator.java   |  15 +-
 .../felix/scr/impl/manager/ComponentActivator.java |   2 +
 .../felix/scr/impl/manager/DependencyManager.java  |  30 ++-
 .../felix/scr/impl/manager/ServiceTracker.java     |  41 +++-
 .../felix/scr/impl/metadata/ReferenceMetadata.java |   8 +
 .../org/apache/felix/scr/impl/xml/XmlHandler.java  |  31 ++-
 .../impl/manager/SingleComponentManagerTest.java   |   7 +
 .../felix/scr/impl/metadata/ComponentBase.java     |   6 +-
 .../scr/impl/truecondition/ComponentTestClass.java |  35 ++++
 .../scr/impl/truecondition/TrueConditionTest.java  | 213 +++++++++++++++++++++
 .../apache/felix/scr/impl/xml/XmlHandlerTest.java  |  70 ++++++-
 .../java/org/osgi/service/condition/Condition.java |  77 ++++++++
 .../resources/satisfying-condition-specified.xml   |  23 +++
 .../test/resources/satisfying_condition_test1.xml  |  27 +++
 .../test/resources/satisfying_condition_test2.xml  |  28 +++
 16 files changed, 629 insertions(+), 24 deletions(-)

diff --git a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
index a419f43..d135690 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
@@ -49,11 +49,14 @@ import org.apache.felix.scr.impl.manager.ComponentHolder;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.MetadataStoreHelper.MetaDataReader;
 import org.apache.felix.scr.impl.metadata.MetadataStoreHelper.MetaDataWriter;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.apache.felix.scr.impl.runtime.ServiceComponentRuntimeImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWire;
@@ -77,6 +80,8 @@ public class Activator extends AbstractExtender
     //Either this bundle's context or the framework bundle context, depending on the globalExtender setting.
     private BundleContext m_globalContext;
 
+    private ServiceReference<?> m_trueCondition;
+
     // this bundle
     private Bundle m_bundle;
 
@@ -115,6 +120,7 @@ public class Activator extends AbstractExtender
     {
         m_context = context;
         m_bundle = context.getBundle();
+        m_trueCondition = findTrueCondition(context);
         // set bundle context for PackageAdmin tracker
         ClassUtils.setBundleContext( context );
         // get the configuration
@@ -122,6 +128,33 @@ public class Activator extends AbstractExtender
     }
 
 
+    private ServiceReference<?> findTrueCondition(BundleContext context)
+    {
+        try
+        {
+            ServiceReference<?>[] foundTrue = context.getServiceReferences(
+                ReferenceMetadata.CONDITION_SERVICE_CLASS, ReferenceMetadata.CONDITION_TRUE_FILTER);
+            if (foundTrue == null || foundTrue.length == 0)
+            {
+                return null;
+            }
+            for (ServiceReference<?> ref : foundTrue)
+            {
+                Bundle b = ref.getBundle();
+                if (b != null && b.getBundleId() == 0)
+                {
+                    return ref;
+                }
+            }
+            return null;
+        }
+        catch (InvalidSyntaxException e)
+        {
+            // should never happen; blow up if it does
+            throw new RuntimeException(e);
+        }
+    }
+
     public void restart(boolean globalExtender)
     {
         m_componentMetadataStore = load(m_context, logger,
@@ -211,6 +244,11 @@ public class Activator extends AbstractExtender
         logger.close();
     }
 
+    public ServiceReference<?> getTrueCondition()
+    {
+        return m_trueCondition;
+    }
+
     @Override
     public void bundleChanged(BundleEvent event)
     {
@@ -550,7 +588,7 @@ public class Activator extends AbstractExtender
         try
         {
             BundleComponentActivator ga = new BundleComponentActivator( this.logger, m_componentRegistry, m_componentActor,
-                context, m_configuration, cached);
+                context, m_configuration, cached, getTrueCondition());
             ga.initialEnable();
             if (cached == null)
             {
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
index 1bf5108..a49b1d7 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
@@ -95,6 +95,8 @@ public class BundleComponentActivator implements ComponentActivator
 
     private final BundleLogger logger;
 
+    private final ServiceReference<?> m_trueCondition;
+
     private static class ListenerInfo implements ServiceListener
     {
         List<ExtendedServiceListener<ExtendedServiceEvent>> listeners = new ArrayList<>();
@@ -187,6 +189,7 @@ public class BundleComponentActivator implements ComponentActivator
      *      register components with to ensure uniqueness of component names
      *      and to ensure configuration updates.
      * @param   context  The bundle context owning the components
+     * @param serviceReference 
      *
      * @throws ComponentException if any error occurrs initializing this class
      */
@@ -195,7 +198,8 @@ public class BundleComponentActivator implements ComponentActivator
             final ComponentActorThread componentActor,
             final BundleContext context,
             final ScrConfiguration configuration,
-            final List<ComponentMetadata> cachedComponentMetadata)
+            final List<ComponentMetadata> cachedComponentMetadata, 
+            final ServiceReference<?> trueConditiion)
     throws ComponentException
     {
         // create a logger on behalf of the bundle
@@ -207,6 +211,7 @@ public class BundleComponentActivator implements ComponentActivator
         m_bundle = context.getBundle();
 
         m_configuration = configuration;
+        m_trueCondition = trueConditiion;
 
         logger.log(Level.DEBUG, "BundleComponentActivator : Bundle active", null);
 
@@ -388,7 +393,7 @@ public class BundleComponentActivator implements ComponentActivator
             stream = descriptorURL.openStream();
 
             XmlHandler handler = new XmlHandler( m_bundle, this.logger, getConfiguration().isFactoryEnabled(),
-                getConfiguration().keepInstances() );
+                getConfiguration().keepInstances(), m_trueCondition);
             final SAXParserFactory factory = SAXParserFactory.newInstance();
             factory.setNamespaceAware(true);
             final SAXParser parser = factory.newSAXParser();
@@ -760,4 +765,10 @@ public class BundleComponentActivator implements ComponentActivator
     public void updateChangeCount() {
         this.m_componentRegistry.updateChangeCount();
     }
+
+    @Override
+    public ServiceReference<?> getTrueCondition()
+    {
+        return this.m_trueCondition;
+    }
 }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentActivator.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentActivator.java
index 2aa0055..4ee3755 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentActivator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentActivator.java
@@ -59,4 +59,6 @@ public interface ComponentActivator extends ExtendedServiceListenerContext<Exten
 
     /** Inform about any change in the state of the components. */
     void updateChangeCount();
+
+    ServiceReference<?> getTrueCondition();
 }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index 8d0b650..4a89f47 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -67,7 +67,7 @@ public class DependencyManager<S, T> implements ReferenceManager<S, T>
 
     private final int m_index;
 
-    private volatile Customizer<S, T> m_customizer;
+    private final Customizer<S, T> m_customizer;
 
     //only set once, but it's not clear there is enough other synchronization to get the correct object before it's used.
     private volatile ReferenceMethods m_bindMethods;
@@ -2316,6 +2316,7 @@ public class DependencyManager<S, T> implements ReferenceManager<S, T>
         if (minimumCardinality != null && (minimumCardinality < defaultMinimumCardinality(m_dependencyMetadata)
             || (!m_dependencyMetadata.isMultiple() && minimumCardinality > 1)))
         {
+            // TODO no warning logged here?  Seem we should at least have a debug message.
             minimumCardinality = null;
         }
         if (minimumCardinality == null)
@@ -2435,9 +2436,10 @@ public class DependencyManager<S, T> implements ReferenceManager<S, T>
             "New service tracker for {0}, initial active: {1}, previous references: {2}, classFilter: {3}, initialReferenceFilter {4}",
             null, getName(), initialActive, refMap, classFilterString,
                     initialReferenceFilterString );
+        ServiceReference<T> trueReference = getTrueConditionRef();
         ServiceTracker<T, RefPair<S, T>, ExtendedServiceEvent> tracker = new ServiceTracker<>(
             bundleContext, m_customizer, initialActive, m_componentManager.getActivator(),
-            initialReferenceFilterString);
+            initialReferenceFilterString, trueReference);
         m_customizer.setTracker(tracker);
         //set minimum cardinality
         m_minCardinality = minimumCardinality;
@@ -2453,6 +2455,30 @@ public class DependencyManager<S, T> implements ReferenceManager<S, T>
                 null, getName());
     }
 
+    @SuppressWarnings("unchecked")
+    private ServiceReference<T> getTrueConditionRef()
+    {
+        if (m_dependencyMetadata.getScope() == ReferenceScope.prototype_required)
+        {
+            return null;
+        }
+        if (ReferenceMetadata.REFERENCE_NAME_SATISFYING_CONDITION.equals(
+            m_dependencyMetadata.getName()) == false)
+        {
+            return null;
+        }
+        if (ReferenceMetadata.CONDITION_TRUE_FILTER.equals(m_target) == false)
+        {
+            return null;
+        }
+        if (ReferenceMetadata.CONDITION_SERVICE_CLASS.equals(
+            m_dependencyMetadata.getInterface()) == false)
+        {
+            return null;
+        }
+        return (ServiceReference<T>) m_componentManager.getActivator().getTrueCondition();
+    }
+
     private Customizer<S, T> newCustomizer()
     {
         Customizer<S, T> customizer;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTracker.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTracker.java
index 3ee738e..57e0c25 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTracker.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceTracker.java
@@ -98,13 +98,19 @@ public class ServiceTracker<S, T, U extends ServiceEvent> {
      */
     private boolean active;
 
-	/**
-	 * Accessor method for the current Tracked object. This method is only
-	 * intended to be used by the unsynchronized methods which do not modify the
-	 * tracked field.
-	 * 
-	 * @return The current Tracked object.
-	 */
+    /**
+     * Reference to be tracked. If this field is set, then we are tracking a
+     * single ServiceReference.
+     */
+    private final ServiceReference<S> trackReference;
+
+    /**
+     * Accessor method for the current Tracked object. This method is only
+     * intended to be used by the unsynchronized methods which do not modify the
+     * tracked field.
+     * 
+     * @return The current Tracked object.
+     */
 	public Tracked tracked() {
 		return tracked;
 	}
@@ -134,7 +140,8 @@ public class ServiceTracker<S, T, U extends ServiceEvent> {
 	    final ServiceTrackerCustomizer<S, T, U> customizer,
 	    boolean initialActive,
 	    ExtendedServiceListenerContext<U> bundleComponentActivator,
-	    final String initialReferenceFilterString) {
+        final String initialReferenceFilterString, final ServiceReference<S> initialReference)
+    {
         if ((context == null)) {
             /*
              * we throw a NPE here to be consistent with the other constructors
@@ -142,6 +149,7 @@ public class ServiceTracker<S, T, U extends ServiceEvent> {
             throw new NullPointerException( "BundleContext");
         }
 		this.context = context;
+        this.trackReference = initialReference;
 		this.initialReferenceFilterString = initialReferenceFilterString;
 		this.customizer = customizer;
 		this.active = initialActive;
@@ -196,7 +204,22 @@ public class ServiceTracker<S, T, U extends ServiceEvent> {
 			synchronized (t) {
 				try {
 					extendedServiceListenerContext.addServiceListener(initialReferenceFilterString, t);
-					ServiceReference<S>[] references = getInitialReferences(null, initialReferenceFilterString);
+                    ServiceReference<S>[] references = null;
+                    if (trackReference != null)
+                    {
+                        if (trackReference.getBundle() != null)
+                        {
+                            @SuppressWarnings("unchecked")
+                            ServiceReference<S>[] single = new ServiceReference[] {
+                                    trackReference };
+                            references = single;
+                        }
+                    }
+                    else
+                    {
+                        references = getInitialReferences(null,
+                            initialReferenceFilterString);
+                    }
 					/* set tracked with the initial references */
 					t.setInitial(references);
 				} catch (InvalidSyntaxException e) {
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
index d72755c..1406291 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
@@ -97,6 +97,13 @@ public class ReferenceMetadata
     // set of valid field value type settings
     private static final Set<String> FIELD_VALUE_TYPE_VALID;
 
+    public static final String CONDITION_SERVICE_CLASS = "org.osgi.service.condition.Condition";
+
+    public static final String CONDITION_TRUE_FILTER = "(osgi.condition.id=true)";
+
+    // TODO this constant will be defined in the R8 Declarative Services spec
+    public static final String REFERENCE_NAME_SATISFYING_CONDITION = "osgi.ds.satisfying.condition";
+
     // Name for the reference (required)
     private String m_name;
 
@@ -154,6 +161,7 @@ public class ReferenceMetadata
     // Flag that is set once the component is verified (its properties cannot be changed)
     private boolean m_validated = false;
 
+
     static
     {
         CARDINALITY_VALID = new TreeSet<>();
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java b/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java
index 4197d74..19c9374 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java
@@ -26,6 +26,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
+import javax.xml.XMLConstants;
+
 import org.apache.felix.scr.impl.logger.BundleLogger;
 import org.apache.felix.scr.impl.logger.InternalLogger.Level;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
@@ -34,6 +36,7 @@ import org.apache.felix.scr.impl.metadata.PropertyMetadata;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.apache.felix.scr.impl.metadata.ServiceMetadata;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
@@ -53,6 +56,8 @@ public class XmlHandler extends DefaultHandler
 
     private final boolean m_globalDelayedKeepInstances;
 
+    private final ServiceReference<?> m_trueCondition;
+
     // A reference to the current component
     private ComponentMetadata m_currentComponent;
 
@@ -81,12 +86,13 @@ public class XmlHandler extends DefaultHandler
 
     // creates an instance with the bundle owning the component descriptor
     // file parsed by this instance
-    public XmlHandler( Bundle bundle, BundleLogger logger, boolean globalObsoleteFactoryComponentFactory, boolean globalDelayedKeepInstances )
+    public XmlHandler(Bundle bundle, BundleLogger logger, boolean globalObsoleteFactoryComponentFactory, boolean globalDelayedKeepInstances, ServiceReference<?> trueCondition)
     {
         m_bundle = bundle;
         m_logger = logger;
         m_globalObsoleteFactoryComponentFactory = globalObsoleteFactoryComponentFactory;
         m_globalDelayedKeepInstances = globalDelayedKeepInstances;
+        m_trueCondition = trueCondition;
     }
 
 
@@ -479,6 +485,29 @@ public class XmlHandler extends DefaultHandler
                 m_pendingFactoryProperty = null;
             }
         }
+        if (m_trueCondition != null && localName.equals(XmlConstants.EL_COMPONENT))
+        {
+            boolean missingSatisfyingConditionRef = true;
+            for (ReferenceMetadata ref : m_currentComponent.getDependencies())
+            {
+                if (ReferenceMetadata.REFERENCE_NAME_SATISFYING_CONDITION.equals(
+                    ref.getName()))
+                {
+                    missingSatisfyingConditionRef = false;
+                    break;
+                }
+            }
+            if (missingSatisfyingConditionRef)
+            {
+                ReferenceMetadata trueReference = new ReferenceMetadata();
+                trueReference.setName(
+                    ReferenceMetadata.REFERENCE_NAME_SATISFYING_CONDITION);
+                trueReference.setTarget(ReferenceMetadata.CONDITION_TRUE_FILTER);
+                trueReference.setInterface(ReferenceMetadata.CONDITION_SERVICE_CLASS);
+                trueReference.setPolicy(ReferenceMetadata.POLICY_DYNAMIC);
+                m_currentComponent.addDependency(trueReference);
+            }
+        }
     }
 
 
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java b/scr/src/test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java
index aea0aae..413778b 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/manager/SingleComponentManagerTest.java
@@ -170,6 +170,13 @@ public class SingleComponentManagerTest
         public BundleLogger getLogger() {
             return bundleLogger;
         }
+
+        @Override
+        public ServiceReference<?> getTrueCondition()
+        {
+            // TODO Auto-generated method stub
+            return null;
+        }
     };
 
     @Test
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentBase.java b/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentBase.java
index 8b93ac9..581728f 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentBase.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentBase.java
@@ -18,13 +18,9 @@
  */
 package org.apache.felix.scr.impl.metadata;
 
-import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringReader;
 import java.util.Iterator;
 import java.util.List;
 
@@ -58,7 +54,7 @@ public class ComponentBase extends TestCase
         factory.setNamespaceAware(true);
         final SAXParser parser = factory.newSAXParser();
 
-        XmlHandler handler = new XmlHandler(new MockBundle(), logger, false, false);
+        XmlHandler handler = new XmlHandler(new MockBundle(), logger, false, false, null);
         parser.parse(in, handler);
 
         return handler.getComponentMetadataList();
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/truecondition/ComponentTestClass.java b/scr/src/test/java/org/apache/felix/scr/impl/truecondition/ComponentTestClass.java
new file mode 100644
index 0000000..1f78e54
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/impl/truecondition/ComponentTestClass.java
@@ -0,0 +1,35 @@
+/*
+ * 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.scr.impl.truecondition;
+
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+import org.osgi.service.component.ComponentContext;
+
+public class ComponentTestClass
+{
+
+    void activate(ComponentContext cc)
+    {
+        Object trueCondition = cc.locateService(
+            ReferenceMetadata.REFERENCE_NAME_SATISFYING_CONDITION);
+        System.out.println("Found condition: " + trueCondition);
+    }
+
+}
+
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/truecondition/TrueConditionTest.java b/scr/src/test/java/org/apache/felix/scr/impl/truecondition/TrueConditionTest.java
new file mode 100644
index 0000000..5d58777
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/impl/truecondition/TrueConditionTest.java
@@ -0,0 +1,213 @@
+/*
+ * 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.scr.impl.truecondition;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.bundle;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withClassicBuilder;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import org.apache.felix.scr.impl.Activator;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.ops4j.pax.tinybundles.core.TinyBundle;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.launch.Framework;
+import org.osgi.service.component.runtime.ServiceComponentRuntime;
+import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO;
+import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO;
+import org.osgi.service.component.runtime.dto.ReferenceDTO;
+import org.osgi.service.component.runtime.dto.SatisfiedReferenceDTO;
+import org.osgi.service.component.runtime.dto.UnsatisfiedReferenceDTO;
+import org.osgi.service.condition.Condition;
+
+import aQute.bnd.osgi.Builder;
+import aQute.bnd.osgi.Jar;
+import aQute.bnd.osgi.JarResource;
+import aQute.lib.io.IO;
+
+public class TrueConditionTest
+{
+
+    private static Framework framework;
+    private static Bundle scr;
+    private BundleActivator scrActivator;
+    private ServiceComponentRuntime scRuntime;
+    private Collection<Bundle> installed = new ArrayList<>();
+
+    @BeforeClass
+    public static void setup() throws Exception
+    {
+        File tmp = IO.getFile("target/tmp/loggertest");
+        Map<String, String> configuration = new HashMap<>();
+        configuration.put(Constants.FRAMEWORK_STORAGE,
+            tmp.getAbsolutePath());
+        configuration.put(Constants.FRAMEWORK_STORAGE_CLEAN,
+            Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
+        configuration.put(Constants.FRAMEWORK_BUNDLE_PARENT,
+            Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK);
+        configuration.put(Constants.FRAMEWORK_BOOTDELEGATION, "*");
+        framework = ServiceLoader.load(
+            org.osgi.framework.launch.FrameworkFactory.class).iterator().next().newFramework(
+                configuration);
+        framework.init();
+        framework.start();
+
+        // fake out a true condition for an R8 framework impl
+        Hashtable<String, String> trueConditionProps = new Hashtable<>();
+        trueConditionProps.put(Condition.CONDITION_ID, Condition.CONDITION_ID_TRUE);
+        framework.getBundleContext().registerService(Condition.class, Condition.INSTANCE,
+            trueConditionProps);
+
+        scr = framework.getBundleContext().installBundle("scr",
+            makeBundle("scr").openInputStream());
+        scr.start();
+    }
+
+    @AfterClass
+    public static void after() throws Exception
+    {
+        framework.stop();
+        framework.waitForStop(100000);
+    }
+
+    @Before
+    public void startScr() throws Exception
+    {
+        scrActivator = new Activator();
+        scrActivator.start(scr.getBundleContext());
+        scRuntime = getServiceComponentRuntime();
+    }
+
+    @After
+    public void cleanup() throws Exception
+    {
+        for (Bundle b : installed)
+        {
+            b.uninstall();
+        }
+        scrActivator.stop(scr.getBundleContext());
+    }
+
+    private static JarResource makeBundle(String bsn) throws Exception
+    {
+        @SuppressWarnings("resource")
+        Builder b = new Builder();
+        b.setBundleSymbolicName(bsn);
+        Jar jar = b.build();
+        b.removeClose(jar);
+        return new JarResource(jar);
+    }
+
+    private Bundle installComponentBundle(String bsn,
+        String componentXML) throws BundleException, Exception
+    {
+        Bundle b = framework.getBundleContext().installBundle(bsn,
+            makeComponent(bsn, componentXML));
+        installed.add(b);
+        return b;
+    }
+
+    private InputStream makeComponent(String bsn, String componentXML) throws Exception
+    {
+
+
+        TinyBundle bundle = bundle() //
+            .add("OSGI-INF/components.xml", getClass().getResource("/" + componentXML)) //
+            .set(Constants.BUNDLE_MANIFESTVERSION, "2") //
+            .set(Constants.BUNDLE_SYMBOLICNAME, bsn) //
+            .set(Constants.BUNDLE_VERSION, "1.0.0") //
+            .set("Service-Component", "OSGI-INF/components.xml");
+        return bundle.build(withClassicBuilder());
+    }
+
+    @Test
+    public void testDefaultSatisfyingCondition() throws BundleException, Exception
+    {
+        Bundle componentBundle = installComponentBundle("component.test.bundle", //
+            "satisfying_condition_test1.xml");
+        componentBundle.start();
+        ComponentDescriptionDTO descriptionDTO = scRuntime.getComponentDescriptionDTO(
+            componentBundle, "satisfying-condition-test1");
+        assertNotNull("No component DTO found.", descriptionDTO);
+        assertEquals("Wrong number of references.", 1, descriptionDTO.references.length);
+
+        ReferenceDTO trueReference = descriptionDTO.references[0];
+        assertEquals("Wrong name.", "osgi.ds.satisfying.condition", trueReference.name);
+        assertEquals("Wrong interface.", "org.osgi.service.condition.Condition",
+            trueReference.interfaceName);
+        assertEquals("Wrong policy.", "dynamic", trueReference.policy);
+        assertEquals("Wrong target.", "(osgi.condition.id=true)", trueReference.target);
+
+        ComponentConfigurationDTO configDTO = scRuntime.getComponentConfigurationDTOs(
+            descriptionDTO).iterator().next();
+        SatisfiedReferenceDTO satisfiedDTO = configDTO.satisfiedReferences[0];
+        assertEquals("Wrong target.", "(osgi.condition.id=true)", satisfiedDTO.target);
+    }
+
+    @Test
+    public void testTargetPropSatisfyingCondition() throws BundleException, Exception
+    {
+        Bundle componentBundle = installComponentBundle("component.test.bundle", //
+            "satisfying_condition_test2.xml");
+        componentBundle.start();
+        ComponentDescriptionDTO descriptionDTO = scRuntime.getComponentDescriptionDTO(
+            componentBundle, "satisfying-condition-test2");
+        assertNotNull("No component DTO found.", descriptionDTO);
+        assertEquals("Wrong number of references.", 1, descriptionDTO.references.length);
+
+        ReferenceDTO trueReference = descriptionDTO.references[0];
+        assertEquals("Wrong name.", "osgi.ds.satisfying.condition", trueReference.name);
+        assertEquals("Wrong interface.", "org.osgi.service.condition.Condition",
+            trueReference.interfaceName);
+        assertEquals("Wrong policy.", "dynamic", trueReference.policy);
+        assertEquals("Wrong target.", "(osgi.condition.id=true)", trueReference.target);
+
+        ComponentConfigurationDTO configDTO = scRuntime.getComponentConfigurationDTOs(
+            descriptionDTO).iterator().next();
+        UnsatisfiedReferenceDTO unsatisfiedDTO = configDTO.unsatisfiedReferences[0];
+        assertEquals("Wrong target.", "(foo=bar)", unsatisfiedDTO.target);
+    }
+
+    private ServiceComponentRuntime getServiceComponentRuntime()
+    {
+        ServiceReference<ServiceComponentRuntime> ref = framework.getBundleContext().getServiceReference(
+            ServiceComponentRuntime.class);
+        assertNotNull("No registered ServiceComponentRuntime.", ref);
+        ServiceComponentRuntime scRuntime = framework.getBundleContext().getService(ref);
+        assertNotNull("No registered SerivceComponentRuntime.", scRuntime);
+        return scRuntime;
+    }
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/xml/XmlHandlerTest.java b/scr/src/test/java/org/apache/felix/scr/impl/xml/XmlHandlerTest.java
index 5484acd..e59e5dc 100755
--- a/scr/src/test/java/org/apache/felix/scr/impl/xml/XmlHandlerTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/xml/XmlHandlerTest.java
@@ -31,16 +31,18 @@ import javax.xml.parsers.SAXParserFactory;
 
 import org.apache.felix.scr.impl.logger.MockBundleLogger;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
 
 public class XmlHandlerTest {
 
     @Test
     public void testPropertiesWithoutValue() throws Exception {
-        final URL url = this.getClass().getClassLoader().getResource("parsertest-nopropvalue.xml");
-        final List<ComponentMetadata> components = parse(url);
+        final URL url = getClass().getResource("/parsertest-nopropvalue.xml");
+        final List<ComponentMetadata> components = parse(url, null);
         assertEquals(1, components.size());
 
         final ComponentMetadata cm = components.get(0);
@@ -52,7 +54,66 @@ public class XmlHandlerTest {
         assertNotNull(cm.getProperties().get("jmx.objectname"));
     }
 
-    private List<ComponentMetadata> parse(final URL descriptorURL) throws Exception {
+    @Test
+    public void testNoTrueCondition() throws Exception
+    {
+        final URL url = getClass().getResource("/parsertest-nopropvalue.xml");
+        final List<ComponentMetadata> components = parse(url, null);
+        assertEquals(1, components.size());
+
+        final ComponentMetadata cm = components.get(0);
+        cm.validate();
+        List<ReferenceMetadata> dependencies = cm.getDependencies();
+        assertEquals("Wrong number of dependencies.", 4, dependencies.size());
+    }
+
+    @Test
+    public void testAvailableTrueCondition() throws Exception
+    {
+        final URL url = getClass().getResource("/parsertest-nopropvalue.xml");
+        final List<ComponentMetadata> components = parse(url,
+            Mockito.mock(ServiceReference.class));
+        assertEquals(1, components.size());
+
+        final ComponentMetadata cm = components.get(0);
+        cm.validate();
+        List<ReferenceMetadata> dependencies = cm.getDependencies();
+        assertEquals("Wrong number of dependencies.", 5, dependencies.size());
+        ReferenceMetadata trueDependency = dependencies.get(dependencies.size() - 1);
+        assertEquals("Wrong name.", "osgi.ds.satisfying.condition",
+            trueDependency.getName());
+        assertEquals("Wrong interface.", "org.osgi.service.condition.Condition",
+            trueDependency.getInterface());
+        assertEquals("Wrong policy.", "dynamic", trueDependency.getPolicy());
+        assertEquals("Wrong target.", "(osgi.condition.id=true)",
+            trueDependency.getTarget());
+    }
+
+    @Test
+    public void testSatisfyingConditionSpecified() throws Exception
+    {
+        final URL url = getClass().getResource("/satisfying-condition-specified.xml");
+        final List<ComponentMetadata> components = parse(url,
+            Mockito.mock(ServiceReference.class));
+        assertEquals(1, components.size());
+
+        final ComponentMetadata cm = components.get(0);
+        cm.validate();
+        List<ReferenceMetadata> dependencies = cm.getDependencies();
+        assertEquals("Wrong number of dependencies.", 1, dependencies.size());
+        ReferenceMetadata trueDependency = dependencies.get(dependencies.size() - 1);
+        assertEquals("Wrong name.", "osgi.ds.satisfying.condition",
+            trueDependency.getName());
+        assertEquals("Wrong interface.", "org.osgi.service.condition.Condition",
+            trueDependency.getInterface());
+        assertEquals("Wrong policy.", "dynamic", trueDependency.getPolicy());
+        assertEquals("Wrong target.", "(foo=bar)",
+            trueDependency.getTarget());
+    }
+
+    private List<ComponentMetadata> parse(final URL descriptorURL,
+        ServiceReference<?> trueCondition) throws Exception
+    {
         final Bundle bundle = Mockito.mock(Bundle.class);
         Mockito.when(bundle.getLocation()).thenReturn("bundle");
 
@@ -60,7 +121,8 @@ public class XmlHandlerTest {
         try {
             stream = descriptorURL.openStream();
 
-            XmlHandler handler = new XmlHandler(bundle, new MockBundleLogger(), false, false);
+            XmlHandler handler = new XmlHandler(bundle, new MockBundleLogger(), false,
+                false, trueCondition);
             final SAXParserFactory factory = SAXParserFactory.newInstance();
             factory.setNamespaceAware(true);
             final SAXParser parser = factory.newSAXParser();
diff --git a/scr/src/test/java/org/osgi/service/condition/Condition.java b/scr/src/test/java/org/osgi/service/condition/Condition.java
new file mode 100644
index 0000000..fcd6da8
--- /dev/null
+++ b/scr/src/test/java/org/osgi/service/condition/Condition.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) OSGi Alliance (2020). All Rights Reserved.
+ * 
+ * Licensed 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.osgi.service.condition;
+
+import org.osgi.annotation.versioning.ConsumerType;
+
+/**
+ * Condition Service interface.
+ * <p>
+ * In dynamic systems, such as OSGi, one of the more challenging problems can be
+ * to define when a system or part of it is ready to do work. The answer can
+ * change depending on the individual perspective. The developer of a web server
+ * might say, the system is ready when the server starts listening on port 80.
+ * An application developer however would define the system as ready when the
+ * database connection is up and all servlets are registered. Taking the
+ * application developers view, the web server should start listening on port 80
+ * when the application is ready and not beforehand.
+ * <p>
+ * The {@code Condition} service interface is a marker interface designed to
+ * address this issue. Its role is to provide a dependency that can be tracked.
+ * It acts as a defined signal to other services.
+ * <p>
+ * A {@code Condition} service must be registered with the
+ * {@link Condition#CONDITION_ID} service property.
+ * 
+ * @ThreadSafe
+ * @author $Id: 9736e5e1c38c45254f733d73ed7ae2c0e253f544 $
+ */
+@ConsumerType
+public interface Condition {
+
+	/**
+	 * Service property identifying a condition's unique identifier.
+	 * <p>
+	 * Since a {@code Condition} service can potentially describe more then one
+	 * condition, the type of this service property is {@code String+}.
+	 */
+	String		CONDITION_ID		= "osgi.condition.id";
+
+	/**
+	 * The unique identifier for the default True condition.
+	 * <p>
+	 * The default True condition is registered by the framework during
+	 * framework initialization and therefore can always be relied upon.
+	 * 
+	 * @see Condition#CONDITION_ID
+	 */
+	String		CONDITION_ID_TRUE	= "true";
+
+	/**
+	 * A condition instance that can be used to register {@code Condition}
+	 * services.
+	 * <p>
+	 * This can be helpful to avoid a bundle having to implement this interface
+	 * to register a {@code Condition} service
+	 */
+	Condition	INSTANCE			= new ConditionImpl();
+}
+
+final class ConditionImpl implements Condition {
+	ConditionImpl() {
+	}
+}
diff --git a/scr/src/test/resources/satisfying-condition-specified.xml b/scr/src/test/resources/satisfying-condition-specified.xml
new file mode 100755
index 0000000..70519ab
--- /dev/null
+++ b/scr/src/test/resources/satisfying-condition-specified.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0" name="satisfying-condition-specified">
+    <reference name="osgi.ds.satisfying.condition" interface="org.osgi.service.condition.Condition" cardinality="1..n" policy="dynamic" target="(foo=bar)"/>
+    <implementation class="org.apache.felix.scr.test.SatisfyingConditionSpecified"/>
+</scr:component>
\ No newline at end of file
diff --git a/scr/src/test/resources/satisfying_condition_test1.xml b/scr/src/test/resources/satisfying_condition_test1.xml
new file mode 100755
index 0000000..2d1b763
--- /dev/null
+++ b/scr/src/test/resources/satisfying_condition_test1.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.4.0"
+ name="satisfying-condition-test1"
+ immediate="true">
+    <implementation class="org.apache.felix.scr.impl.truecondition.ComponentTestClass"/>
+    <service>
+        <provide interface="org.apache.felix.scr.impl.truecondition.ComponentTestClass" />
+    </service>
+</scr:component>
\ No newline at end of file
diff --git a/scr/src/test/resources/satisfying_condition_test2.xml b/scr/src/test/resources/satisfying_condition_test2.xml
new file mode 100755
index 0000000..20c1d3c
--- /dev/null
+++ b/scr/src/test/resources/satisfying_condition_test2.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.4.0"
+ name="satisfying-condition-test2"
+ immediate="true">
+    <implementation class="org.apache.felix.scr.impl.truecondition.ComponentTestClass"/>
+    <property name="osgi.ds.satisfying.condition.target" value="(foo=bar)"/>
+    <service>
+        <provide interface="org.apache.felix.scr.impl.truecondition.ComponentTestClass" />
+    </service>
+</scr:component>
\ No newline at end of file


[felix-dev] 01/02: Merge branch 'master' into scrR8

Posted by tj...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tjwatson pushed a commit to branch scrR8
in repository https://gitbox.apache.org/repos/asf/felix-dev.git

commit b186ccc4ebb525387962c8179b889e898bd46418
Merge: 49599cc 03288b9
Author: Thomas Watson <tj...@us.ibm.com>
AuthorDate: Thu Oct 8 12:17:05 2020 -0500

    Merge branch 'master' into scrR8

 eventadmin/impl/changelog.txt                      |   9 ++
 eventadmin/impl/pom.xml                            |  22 ++--
 .../apache/felix/eventadmin/impl/Activator.java    |   4 +-
 .../felix/eventadmin/impl/Configuration.java       |  24 +++--
 .../eventadmin/impl/MetaTypeProviderImpl.java      |   4 +-
 .../impl/adapter/BundleEventAdapter.java           |   5 +-
 .../impl/adapter/FrameworkEventAdapter.java        |   6 +-
 .../eventadmin/impl/adapter/LogEventAdapter.java   |  69 +++----------
 .../impl/adapter/ServiceEventAdapter.java          |  48 ++-------
 .../eventadmin/impl/handler/EventAdminImpl.java    |  23 +++++
 .../eventadmin/impl/handler/EventHandlerProxy.java |  33 ++++--
 .../impl/handler/EventHandlerTracker.java          |  33 ++++++
 .../{BlacklistLatch.java => DenylistLatch.java}    |  22 ++--
 .../felix/eventadmin/impl/tasks/HandlerTask.java   |  16 +--
 .../eventadmin/impl/tasks/SyncDeliverTasks.java    |   8 +-
 .../felix/eventadmin/impl/util/LogWrapper.java     |  28 +++---
 .../felix/eventadmin/ittests/AbstractTest.java     |  27 +++--
 .../apache/felix/eventadmin/ittests/Listener.java  |   4 +-
 .../eventadmin/perftests/PerformanceTestIT.java    |  46 +++++----
 .../apache/felix/framework/BundleRevisionImpl.java |  29 ++----
 .../apache/felix/framework/BundleWiringImpl.java   |   2 +-
 .../apache/felix/framework/ServiceRegistry.java    |   9 +-
 .../framework/URLHandlersBundleURLConnection.java  |  15 +--
 .../felix/framework/ResourceLoadingTest.java       |   8 ++
 gogo/bom/pom.xml                                   |  13 +--
 gogo/command/doc/changelog.txt                     |   5 +
 gogo/command/pom.xml                               |   9 +-
 gogo/itest-jline/pom.xml                           |   2 +-
 gogo/itest-shell/pom.xml                           |   2 +-
 gogo/runtime/doc/changelog.txt                     |   6 ++
 gogo/runtime/pom.xml                               |   7 +-
 gogo/shell/doc/changelog.txt                       |   8 ++
 gogo/shell/pom.xml                                 |   9 +-
 .../hc/core/impl/executor/HealthCheckFuture.java   |  14 ++-
 .../core/impl/filter/ServiceUnavailableFilter.java |   2 +-
 http/base/pom.xml                                  |   8 +-
 .../felix/http/base/internal/HttpConfig.java       |  94 +++++++++++++++++
 .../base/internal/handler/HttpSessionWrapper.java  |  20 +++-
 .../base/internal/handler/PreprocessorHandler.java |   7 +-
 .../internal/handler/WhiteboardFilterHandler.java  |  22 ++--
 .../handler/WhiteboardListenerHandler.java         |  22 ++--
 .../internal/handler/WhiteboardServletHandler.java |  18 +---
 .../internal/logger/LogServiceEnabledLogger.java   |   5 +-
 .../internal/runtime/dto/RuntimeDTOBuilder.java    |   6 --
 .../internal/service/PerBundleHttpServiceImpl.java |   3 +-
 .../http/base/internal/util/ServiceUtils.java      |  89 +++++++++++++++++
 .../whiteboard/SharedServletContextImpl.java       |   1 -
 .../whiteboard/WhiteboardContextHandler.java       |  32 +++---
 .../internal/context/ServletContextImplTest.java   |   6 +-
 .../internal/handler/FilterConfigImplTest.java     |  14 +--
 .../internal/handler/HttpSessionWrapperTest.java   |  67 +++++++++++++
 .../internal/handler/ServletConfigImplTest.java    |  12 ++-
 .../internal/registry/ErrorPageRegistryTest.java   |  11 +-
 .../registry/EventListenerRegistryTest.java        |   7 +-
 .../base/internal/registry/FilterRegistryTest.java |   6 +-
 .../internal/registry/ServletRegistryTest.java     |  13 +--
 .../internal/runtime/AbstractInfoOrderingTest.java |   6 +-
 .../base/internal/runtime/ListenerInfoTest.java    |   1 +
 http/bridge/pom.xml                                |  10 +-
 http/itest/pom.xml                                 |  36 +++----
 http/jetty/pom.xml                                 |  14 ++-
 .../jetty/internal/ConfigMetaTypeProvider.java     |   8 ++
 .../jetty/internal/ConnectorFactoryTracker.java    |   7 +-
 .../felix/http/jetty/internal/JettyConfig.java     |   4 +-
 .../LoadBalancerCustomizerFactoryTracker.java      |  11 +-
 .../http/jetty/internal/RequestLogTracker.java     |  24 +++--
 http/parent/pom.xml                                |  13 +--
 http/pom.xml                                       |   2 +-
 http/sslfilter/pom.xml                             |  33 +++---
 .../felix/scr/impl/manager/DependencyManager.java  | 111 ++++++++++++++++-----
 .../scr/impl/manager/SingleComponentManager.java   |   3 +-
 .../scr/integration/ServiceBindGreedyTest.java     |  54 +++++++---
 .../integration/components/SimpleComponent.java    |   8 +-
 .../integration/components/SimpleServiceImpl.java  |  24 +++--
 webconsole-plugins/event/pom.xml                   |  51 +++++++---
 .../plugins/event/internal/Activator.java          |   8 +-
 .../event/internal/ConfigurationListener.java      |  12 ++-
 .../plugins/event/internal/EventCollector.java     |  18 ++--
 .../plugins/event/internal/EventHandler.java       |   9 +-
 .../plugins/event/internal/EventInfo.java          |   4 +-
 .../event/internal/OptionalFeaturesHandler.java    |  31 ++++--
 .../plugins/event/internal/OsgiUtil.java           |  30 +++---
 .../plugins/event/internal/PluginServlet.java      |  23 +++--
 .../event/internal/PropertiesEditorSupport.java    |   6 +-
 .../internal/converter/ServiceEventConverter.java  |   7 +-
 webconsole/changelog.txt                           |   7 ++
 webconsole/pom.xml                                 |   7 +-
 .../felix/webconsole/SimpleWebConsolePlugin.java   |  41 ++++++++
 .../i18n/ConsolePropertyResourceBundle.java        |   8 +-
 .../internal/servlet/OsgiManagerTest.java          |  14 +++
 90 files changed, 1097 insertions(+), 582 deletions(-)