Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion scr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The Apache Felix Service Component Runtime described by the [OSGi Declarative Se

The Java annotations defined by the specification make implementing components easy and reduce the amount of code that needs be written. These annotations are processed at build time and translated into XML descriptor files which in turn are listed in the `Service-Component` header of the declaring bundle. But the good news is, you usually don't have to worry about this XML, however in case things don't work as expected , it's good to know how these things work.

The Apache Felix Declarative Services implementation is the reference implementation for the OSGi Declarative Services Specification Version 1.4 (R7) and therefore passes the OSGi CT.
The Apache Felix Declarative Services implementation is the reference implementation for the OSGi Declarative Services Specification Version 1.4 (R7) and therefore passes the OSGi CT. This implementation also includes support for OSGi R8 features such as the Satisfying Condition specification.

## Example Usage

Expand Down Expand Up @@ -112,6 +112,52 @@ public Comparator(@Reference LogService logService)
}
```

## Satisfying Condition (OSGi R8)

Apache Felix SCR implements the Satisfying Condition feature as specified in the OSGi R8 Declarative Services specification. This feature allows components to be activated only when specific runtime conditions are met.

### How It Works

When the OSGi framework provides a `true` condition service (registered by the system bundle with the property `osgi.condition.id=true`), Apache Felix SCR automatically adds an implicit satisfying condition reference to all components. This implicit reference:

- Has the name `osgi.ds.satisfying.condition`
- References the `org.osgi.service.condition.Condition` service
- Uses a dynamic policy
- Defaults to target `(osgi.condition.id=true)`

### Customizing the Satisfying Condition

Components can customize the satisfying condition target by setting the `osgi.ds.satisfying.condition.target` property:

```xml
<scr:component name="my.component" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.5.0">
<property name="osgi.ds.satisfying.condition.target" value="(my.condition=ready)"/>
<implementation class="com.example.MyComponent"/>
</scr:component>
```

Alternatively, components can explicitly declare the satisfying condition reference to have full control over its configuration:

```xml
<scr:component name="my.component" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.5.0">
<implementation class="com.example.MyComponent"/>
<reference name="osgi.ds.satisfying.condition"
interface="org.osgi.service.condition.Condition"
target="(my.custom.condition=true)"
policy="dynamic"/>
</scr:component>
```

### Use Cases

Satisfying conditions are useful for:
- Delaying component activation until the system is fully initialized
- Implementing conditional component activation based on runtime state
- Managing component lifecycle based on external conditions

For more details, see
- [112.3.13 Satisfying Condition](https://docs.osgi.org/specification/osgi.cmpn/8.0.0/service.component.html#service.component-satisfying.condition)

## Apache Maven Support

Both, the [maven-bundle-plugin](http://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html) as well as the [bnd-maven-plugin](https://github.com/bndtools/bnd/tree/master/maven) supports processing the annotations and creating the XML component descriptors.
Expand Down
10 changes: 10 additions & 0 deletions scr/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Changes in 2.2.15
-----------------
** Improvement
* Document Satisfying Condition feature as OSGi R8 specification-compliant
- The existing satisfying condition implementation is now documented as compliant
with the preliminary OSGi R8 Declarative Services specification changes
- See https://docs.osgi.org/specification/osgi.cmpn/8.0.0/service.component.html#service.component-satisfying.condition
- Added comprehensive documentation in README.md
- Updated code comments to reflect specification compliance

Changes in 2.2.14
-----------------
** PRs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ public enum ReferenceScope {bundle, prototype, prototype_required}

public static final String CONDITION_TRUE_FILTER = "(osgi.condition.id=true)";

// TODO this constant will be defined in the R8 Declarative Services spec
/**
* The reference name for the implicit satisfying condition as defined in the
* OSGi R8 Declarative Services specification (see https://github.com/osgi/osgi/pull/875).
* This reference is automatically added to components when a true condition service is available.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point of this comment wasn't to add javadoc later to this internal class. It was to remind us to use the actual spec'ed constant from the released APIs
https://github.com/osgi/osgi/blob/eb08fcac898f50aec1a1d2847cae6ffccd5a7385/org.osgi.service.component/src/org/osgi/service/component/ComponentConstants.java#L161

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public static final String REFERENCE_NAME_SATISFYING_CONDITION = "osgi.ds.satisfying.condition";

// Name for the reference (required)
Expand Down
12 changes: 9 additions & 3 deletions scr/src/main/java/org/apache/felix/scr/impl/xml/XmlHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,11 @@ else if ( localName.equals( XmlConstants.EL_FACTORY_PROPERTY ) && m_pendingFacto
m_pendingFactoryProperty = null;
}
}
// Add implicit satisfying condition reference as per OSGi R8 Declarative Services specification
// (see https://github.com/osgi/osgi/pull/875 and https://github.com/osgi/osgi/issues/720).
// When a true condition service is available from the framework, an implicit satisfying condition
// reference is automatically added to all components unless they already explicitly declare one.
// This allows components to be activated only when certain runtime conditions are met.
if (m_trueCondition != null && localName.equals(XmlConstants.EL_COMPONENT))
{
boolean missingSatisfyingConditionRef = true;
Expand All @@ -504,9 +509,10 @@ else if ( localName.equals( XmlConstants.EL_FACTORY_PROPERTY ) && m_pendingFacto
trueReference.setInterface(ReferenceMetadata.CONDITION_SERVICE_CLASS);
trueReference.setPolicy(ReferenceMetadata.POLICY_DYNAMIC);
m_currentComponent.addDependency(trueReference);
// Here we add the target property for the implicit satisfying condition
// first such that any properties that are specified explicitly can
// be used to override this implicit property
// Add the target property for the implicit satisfying condition.
// This is added first so that any explicitly specified properties can
// override this implicit property, allowing components to specify custom
// condition targets via the osgi.ds.satisfying.condition.target property.
PropertyMetadata prop = new PropertyMetadata(true);
prop.setName(
ReferenceMetadata.REFERENCE_NAME_SATISFYING_CONDITION + ".target");
Expand Down